@burdenoff/microfe-technospam 2026.716.2 → 2026.719.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/node_modules/recharts/es6/cartesian/Brush.js.map +1 -1
  2. package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js.map +1 -1
  3. package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js.map +1 -1
  4. package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js.map +1 -1
  5. package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js.map +1 -1
  6. package/dist/node_modules/recharts/es6/cartesian/XAxis.js.map +1 -1
  7. package/dist/node_modules/recharts/es6/cartesian/YAxis.js.map +1 -1
  8. package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js.map +1 -1
  9. package/dist/node_modules/sonner/dist/index.js.map +1 -1
  10. package/dist/technospam/TechnoSpamRoot.d.ts.map +1 -1
  11. package/dist/technospam/TechnoSpamRoot.js +190 -250
  12. package/dist/technospam/TechnoSpamRoot.js.map +1 -1
  13. package/dist/technospam/TechnoSpamRoutes.d.ts.map +1 -1
  14. package/dist/technospam/TechnoSpamRoutes.js.map +1 -1
  15. package/dist/technospam/api/technospamApi.d.ts +20 -9
  16. package/dist/technospam/api/technospamApi.d.ts.map +1 -1
  17. package/dist/technospam/api/technospamApi.js +62 -16
  18. package/dist/technospam/api/technospamApi.js.map +1 -1
  19. package/dist/technospam/pages/AdminAdminDashboardPagePage.js +2 -2
  20. package/dist/technospam/pages/AdminAdminDashboardPagePage.js.map +1 -1
  21. package/dist/technospam/pages/AnalyticsAnalyticsPagePage.js +1 -1
  22. package/dist/technospam/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  23. package/dist/technospam/pages/ApplicationsProblemsPagePage.d.ts.map +1 -1
  24. package/dist/technospam/pages/ApplicationsProblemsPagePage.js +176 -76
  25. package/dist/technospam/pages/ApplicationsProblemsPagePage.js.map +1 -1
  26. package/dist/technospam/pages/DashboardDashboardPagePage.js +1 -1
  27. package/dist/technospam/pages/DashboardDashboardPagePage.js.map +1 -1
  28. package/dist/technospam/pages/HackathonsHackathonDetailsPagePage.js +1 -1
  29. package/dist/technospam/pages/HackathonsHackathonDetailsPagePage.js.map +1 -1
  30. package/dist/technospam/pages/MentorshipSessionsPagePage.js +1 -1
  31. package/dist/technospam/pages/MentorshipSessionsPagePage.js.map +1 -1
  32. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"technospamApi.js","names":[],"sources":["../../../src/technospam/api/technospamApi.ts"],"sourcesContent":["/**\n * TechnoSpam data layer — Apollo operations + typed hooks over the\n * wspace-technospam-svc subgraph (Tec* fields), reached through the host\n * shell's default workspace ApolloProvider (defaultGateway: \"workspace\").\n *\n * Every page consumes real backend data through these hooks. There is NO mock\n * data. List queries are cursor-paginated: page 1 omits `cursor` entirely\n * (passing cursor: null makes the Prisma cursor resolver 500), \"load more\"\n * passes the previous page's `pageInfo.cursor`.\n */\nimport { useState } from 'react';\nimport { gql, type ErrorLike } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nimport { notify } from '../lib/toast';\n\n/* ------------------------------------------------------------------ enums */\n\nexport type TecCourseLevel = 'BEGINNER' | 'INTERMEDIATE' | 'ADVANCED' | 'EXPERT';\nexport type TecCourseStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\nexport type TecLessonKind = 'VIDEO' | 'ARTICLE' | 'INTERACTIVE' | 'QUIZ' | 'PROJECT';\nexport type TecEnrollmentStatus = 'ENROLLED' | 'IN_PROGRESS' | 'COMPLETED' | 'DROPPED';\nexport type TecCertificateStatus = 'ISSUED' | 'REVOKED';\nexport type TecProblemDifficulty = 'EASY' | 'MEDIUM' | 'HARD';\nexport type TecProblemStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\nexport type TecSubmissionVerdict =\n | 'PENDING'\n | 'ACCEPTED'\n | 'WRONG_ANSWER'\n | 'TIME_LIMIT_EXCEEDED'\n | 'RUNTIME_ERROR'\n | 'COMPILE_ERROR';\nexport type TecMentorStatus = 'PENDING' | 'ACTIVE' | 'PAUSED' | 'INACTIVE';\nexport type TecSessionStatus = 'REQUESTED' | 'CONFIRMED' | 'COMPLETED' | 'CANCELLED' | 'NO_SHOW';\nexport type TecHackathonStatus =\n 'DRAFT' | 'REGISTRATION_OPEN' | 'IN_PROGRESS' | 'JUDGING' | 'COMPLETED' | 'CANCELLED';\nexport type TecTeamSubmissionStatus = 'DRAFT' | 'SUBMITTED' | 'DISQUALIFIED' | 'WINNER';\n\n/* ------------------------------------------------------------------ types */\n\nexport interface TecCourse {\n id: string;\n slug: string;\n title: string;\n summary?: string | null;\n topic?: string | null;\n level: TecCourseLevel;\n status: TecCourseStatus;\n tags: string[];\n estimatedMinutes: number;\n instructorId?: string | null;\n publishedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n lessons?: TecLesson[];\n enrollments?: TecEnrollment[];\n}\n\nexport interface TecLesson {\n id: string;\n courseId: string;\n title: string;\n kind: TecLessonKind;\n content?: string | null;\n position: number;\n estimatedMinutes: number;\n isPreview: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface TecEnrollment {\n id: string;\n courseId: string;\n learnerId: string;\n status: TecEnrollmentStatus;\n progressPct: number;\n lessonsCompleted: number;\n startedAt: string;\n lastActiveAt?: string | null;\n completedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n course?: TecCourse | null;\n}\n\nexport interface TecCertificate {\n id: string;\n courseId: string;\n learnerId: string;\n serial: string;\n score: number;\n status: TecCertificateStatus;\n issuedAt: string;\n revokedAt?: string | null;\n revokeReason?: string | null;\n createdAt: string;\n course?: TecCourse | null;\n}\n\nexport interface TecProblem {\n id: string;\n slug: string;\n title: string;\n statement?: string | null;\n topic?: string | null;\n difficulty: TecProblemDifficulty;\n status: TecProblemStatus;\n tags: string[];\n languages: string[];\n points: number;\n starterCode?: string | null;\n publishedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n submissions?: TecSubmission[];\n}\n\nexport interface TecSubmission {\n id: string;\n problemId: string;\n learnerId: string;\n language: string;\n code: string;\n verdict: TecSubmissionVerdict;\n runtimeMs: number;\n pointsAwarded: number;\n judgedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n problem?: TecProblem | null;\n}\n\nexport interface TecMentor {\n id: string;\n userId: string;\n headline: string;\n bio?: string | null;\n expertise: string[];\n hourlyRate: number;\n currency: string;\n status: TecMentorStatus;\n isAcceptingMentees: boolean;\n ratingAvg: number;\n sessionsCount: number;\n createdAt: string;\n updatedAt: string;\n sessions?: TecMentorSession[];\n}\n\nexport interface TecMentorSession {\n id: string;\n mentorId: string;\n menteeId: string;\n topic: string;\n agenda?: string | null;\n scheduledAt: string;\n durationMinutes: number;\n status: TecSessionStatus;\n meetingUrl?: string | null;\n rating?: number | null;\n feedback?: string | null;\n completedAt?: string | null;\n cancelledAt?: string | null;\n createdAt: string;\n updatedAt: string;\n mentor?: TecMentor | null;\n}\n\nexport interface TecHackathon {\n id: string;\n slug: string;\n title: string;\n theme?: string | null;\n description?: string | null;\n status: TecHackathonStatus;\n startAt: string;\n endAt: string;\n submissionDeadline?: string | null;\n prizePool: number;\n currency: string;\n maxTeamSize: number;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n teams?: TecHackathonTeam[];\n}\n\nexport interface TecHackathonTeam {\n id: string;\n hackathonId: string;\n name: string;\n captainId: string;\n memberIds: string[];\n projectName?: string | null;\n projectUrl?: string | null;\n repoUrl?: string | null;\n pitch?: string | null;\n status: TecTeamSubmissionStatus;\n score: number;\n submittedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n hackathon?: TecHackathon | null;\n}\n\nexport interface TecPageInfo {\n cursor?: string | null;\n hasMore: boolean;\n}\n\nexport interface PaginationInput {\n limit?: number;\n cursor?: string | null;\n}\n\n/** Build a pagination arg that NEVER sends cursor:null (page-1 500 guard). */\nexport function pageArg(limit = 50, cursor?: string | null): { limit: number; cursor?: string } {\n return cursor ? { limit, cursor } : { limit };\n}\n\n/* -------------------------------------------------------------- fragments */\n\nconst COURSE_FIELDS = gql`\n fragment CourseFields on TecCourse {\n id\n slug\n title\n summary\n topic\n level\n status\n tags\n estimatedMinutes\n instructorId\n publishedAt\n createdAt\n updatedAt\n }\n`;\n\nconst LESSON_FIELDS = gql`\n fragment LessonFields on TecLesson {\n id\n courseId\n title\n kind\n content\n position\n estimatedMinutes\n isPreview\n createdAt\n updatedAt\n }\n`;\n\nconst ENROLLMENT_FIELDS = gql`\n fragment EnrollmentFields on TecEnrollment {\n id\n courseId\n learnerId\n status\n progressPct\n lessonsCompleted\n startedAt\n lastActiveAt\n completedAt\n createdAt\n updatedAt\n }\n`;\n\nconst PROBLEM_FIELDS = gql`\n fragment ProblemFields on TecProblem {\n id\n slug\n title\n statement\n topic\n difficulty\n status\n tags\n languages\n points\n starterCode\n publishedAt\n createdAt\n updatedAt\n }\n`;\n\nconst SUBMISSION_FIELDS = gql`\n fragment SubmissionFields on TecSubmission {\n id\n problemId\n learnerId\n language\n code\n verdict\n runtimeMs\n pointsAwarded\n judgedAt\n createdAt\n updatedAt\n }\n`;\n\nconst MENTOR_FIELDS = gql`\n fragment MentorFields on TecMentor {\n id\n userId\n headline\n bio\n expertise\n hourlyRate\n currency\n status\n isAcceptingMentees\n ratingAvg\n sessionsCount\n createdAt\n updatedAt\n }\n`;\n\nconst SESSION_FIELDS = gql`\n fragment SessionFields on TecMentorSession {\n id\n mentorId\n menteeId\n topic\n agenda\n scheduledAt\n durationMinutes\n status\n meetingUrl\n rating\n feedback\n completedAt\n cancelledAt\n createdAt\n updatedAt\n }\n`;\n\nconst HACKATHON_FIELDS = gql`\n fragment HackathonFields on TecHackathon {\n id\n slug\n title\n theme\n description\n status\n startAt\n endAt\n submissionDeadline\n prizePool\n currency\n maxTeamSize\n tags\n createdAt\n updatedAt\n }\n`;\n\nconst TEAM_FIELDS = gql`\n fragment TeamFields on TecHackathonTeam {\n id\n hackathonId\n name\n captainId\n memberIds\n projectName\n projectUrl\n repoUrl\n pitch\n status\n score\n submittedAt\n createdAt\n updatedAt\n }\n`;\n\nconst CERTIFICATE_FIELDS = gql`\n fragment CertificateFields on TecCertificate {\n id\n courseId\n learnerId\n serial\n score\n status\n issuedAt\n revokedAt\n revokeReason\n createdAt\n }\n`;\n\n/* --------------------------------------------------------------- queries */\n\nconst LIST_COURSES = gql`\n ${COURSE_FIELDS}\n query TecListCourses(\n $level: TecCourseLevel\n $status: TecCourseStatus\n $pagination: PaginationInput\n ) {\n tecListCourses(level: $level, status: $status, pagination: $pagination) {\n items {\n ...CourseFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_COURSE = gql`\n ${COURSE_FIELDS}\n ${LESSON_FIELDS}\n ${ENROLLMENT_FIELDS}\n query TecCourse($id: ID!) {\n tecCourse(id: $id) {\n ...CourseFields\n lessons {\n ...LessonFields\n }\n enrollments {\n ...EnrollmentFields\n }\n }\n }\n`;\n\nconst LIST_ENROLLMENTS = gql`\n ${ENROLLMENT_FIELDS}\n ${COURSE_FIELDS}\n query TecListEnrollments($learnerId: ID, $courseId: ID, $pagination: PaginationInput) {\n tecListEnrollments(learnerId: $learnerId, courseId: $courseId, pagination: $pagination) {\n items {\n ...EnrollmentFields\n course {\n ...CourseFields\n }\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst LIST_CERTIFICATES = gql`\n ${CERTIFICATE_FIELDS}\n ${COURSE_FIELDS}\n query TecListCertificates($learnerId: ID, $courseId: ID) {\n tecListCertificates(learnerId: $learnerId, courseId: $courseId) {\n ...CertificateFields\n course {\n ...CourseFields\n }\n }\n }\n`;\n\nconst LIST_PROBLEMS = gql`\n ${PROBLEM_FIELDS}\n query TecListProblems(\n $difficulty: TecProblemDifficulty\n $status: TecProblemStatus\n $topic: String\n $pagination: PaginationInput\n ) {\n tecListProblems(\n difficulty: $difficulty\n status: $status\n topic: $topic\n pagination: $pagination\n ) {\n items {\n ...ProblemFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_PROBLEM = gql`\n ${PROBLEM_FIELDS}\n ${SUBMISSION_FIELDS}\n query TecProblem($id: ID!) {\n tecProblem(id: $id) {\n ...ProblemFields\n submissions {\n ...SubmissionFields\n }\n }\n }\n`;\n\nconst LIST_SUBMISSIONS = gql`\n ${SUBMISSION_FIELDS}\n ${PROBLEM_FIELDS}\n query TecListSubmissions($learnerId: ID, $problemId: ID, $pagination: PaginationInput) {\n tecListSubmissions(learnerId: $learnerId, problemId: $problemId, pagination: $pagination) {\n items {\n ...SubmissionFields\n problem {\n ...ProblemFields\n }\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst LIST_MENTORS = gql`\n ${MENTOR_FIELDS}\n query TecListMentors($status: TecMentorStatus, $pagination: PaginationInput) {\n tecListMentors(status: $status, pagination: $pagination) {\n items {\n ...MentorFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_MENTOR = gql`\n ${MENTOR_FIELDS}\n ${SESSION_FIELDS}\n query TecMentor($id: ID!) {\n tecMentor(id: $id) {\n ...MentorFields\n sessions {\n ...SessionFields\n }\n }\n }\n`;\n\nconst LIST_SESSIONS = gql`\n ${SESSION_FIELDS}\n ${MENTOR_FIELDS}\n query TecListSessions($mentorId: ID, $menteeId: ID, $status: TecSessionStatus) {\n tecListSessions(mentorId: $mentorId, menteeId: $menteeId, status: $status) {\n ...SessionFields\n mentor {\n ...MentorFields\n }\n }\n }\n`;\n\nconst LIST_HACKATHONS = gql`\n ${HACKATHON_FIELDS}\n query TecListHackathons($status: TecHackathonStatus, $pagination: PaginationInput) {\n tecListHackathons(status: $status, pagination: $pagination) {\n items {\n ...HackathonFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n ${TEAM_FIELDS}\n query TecHackathon($id: ID!) {\n tecHackathon(id: $id) {\n ...HackathonFields\n teams {\n ...TeamFields\n }\n }\n }\n`;\n\nconst LIST_TEAMS = gql`\n ${TEAM_FIELDS}\n query TecListTeams($hackathonId: ID!) {\n tecListTeams(hackathonId: $hackathonId) {\n ...TeamFields\n }\n }\n`;\n\nconst LIST_LESSONS = gql`\n ${LESSON_FIELDS}\n query TecListLessons($courseId: ID!) {\n tecListLessons(courseId: $courseId) {\n ...LessonFields\n }\n }\n`;\n\n/* ------------------------------------------------------- response typings */\n\ntype Conn<K extends string, T> = Record<K, { items: T[]; pageInfo: TecPageInfo }>;\n\n/* ---------------------------------------------------------- query hooks */\n\nexport const useCoursesQuery = (vars: {\n level?: TecCourseLevel;\n status?: TecCourseStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListCourses', TecCourse>>(LIST_COURSES, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useCourseQuery = (id: string) =>\n useQuery<{ tecCourse: TecCourse | null }>(GET_COURSE, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useEnrollmentsQuery = (vars: { learnerId?: string; courseId?: string }) =>\n useQuery<Conn<'tecListEnrollments', TecEnrollment>>(LIST_ENROLLMENTS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useCertificatesQuery = (vars: { learnerId?: string; courseId?: string }) =>\n useQuery<{ tecListCertificates: TecCertificate[] }>(LIST_CERTIFICATES, {\n variables: vars,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useProblemsQuery = (vars: {\n difficulty?: TecProblemDifficulty;\n status?: TecProblemStatus;\n topic?: string;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListProblems', TecProblem>>(LIST_PROBLEMS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useProblemQuery = (id: string) =>\n useQuery<{ tecProblem: TecProblem | null }>(GET_PROBLEM, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useSubmissionsQuery = (vars: { learnerId?: string; problemId?: string }) =>\n useQuery<Conn<'tecListSubmissions', TecSubmission>>(LIST_SUBMISSIONS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useMentorsQuery = (vars: {\n status?: TecMentorStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListMentors', TecMentor>>(LIST_MENTORS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useMentorQuery = (id: string) =>\n useQuery<{ tecMentor: TecMentor | null }>(GET_MENTOR, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useSessionsQuery = (vars: {\n mentorId?: string;\n menteeId?: string;\n status?: TecSessionStatus;\n}) =>\n useQuery<{ tecListSessions: TecMentorSession[] }>(LIST_SESSIONS, {\n variables: vars,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useHackathonsQuery = (vars: {\n status?: TecHackathonStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListHackathons', TecHackathon>>(LIST_HACKATHONS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useHackathonQuery = (id: string) =>\n useQuery<{ tecHackathon: TecHackathon | null }>(GET_HACKATHON, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useTeamsQuery = (hackathonId: string) =>\n useQuery<{ tecListTeams: TecHackathonTeam[] }>(LIST_TEAMS, {\n variables: { hackathonId },\n skip: !hackathonId,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useLessonsQuery = (courseId: string) =>\n useQuery<{ tecListLessons: TecLesson[] }>(LIST_LESSONS, {\n variables: { courseId },\n skip: !courseId,\n fetchPolicy: 'cache-and-network',\n });\n\n/* ------------------------------------------------------------ mutations */\n\nconst onMutationError = (error: ErrorLike): void => {\n notify.error('Something went wrong', error.message || 'Please try again.');\n};\n\nconst REFETCH = {\n courses: 'TecListCourses',\n enrollments: 'TecListEnrollments',\n problems: 'TecListProblems',\n submissions: 'TecListSubmissions',\n mentors: 'TecListMentors',\n sessions: 'TecListSessions',\n hackathons: 'TecListHackathons',\n} as const;\n\nconst ENROLL = gql`\n ${ENROLLMENT_FIELDS}\n mutation TecEnroll($input: TecEnrollInput!) {\n tecEnroll(input: $input) {\n ...EnrollmentFields\n }\n }\n`;\n\nconst UPDATE_PROGRESS = gql`\n ${ENROLLMENT_FIELDS}\n mutation TecUpdateProgress($input: TecUpdateProgressInput!) {\n tecUpdateProgress(input: $input) {\n ...EnrollmentFields\n }\n }\n`;\n\nconst SUBMIT_SOLUTION = gql`\n ${SUBMISSION_FIELDS}\n mutation TecSubmitSolution($input: TecSubmitSolutionInput!) {\n tecSubmitSolution(input: $input) {\n ...SubmissionFields\n }\n }\n`;\n\nconst BOOK_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecBookSession($input: TecBookSessionInput!) {\n tecBookSession(input: $input) {\n ...SessionFields\n }\n }\n`;\n\nconst CANCEL_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecCancelSession($id: ID!) {\n tecCancelSession(id: $id) {\n ...SessionFields\n }\n }\n`;\n\nconst BECOME_MENTOR = gql`\n ${MENTOR_FIELDS}\n mutation TecBecomeMentor($input: TecCreateMentorInput!) {\n tecBecomeMentor(input: $input) {\n ...MentorFields\n }\n }\n`;\n\nconst REGISTER_TEAM = gql`\n ${TEAM_FIELDS}\n mutation TecRegisterTeam($input: TecRegisterTeamInput!) {\n tecRegisterTeam(input: $input) {\n ...TeamFields\n }\n }\n`;\n\nconst SUBMIT_PROJECT = gql`\n ${TEAM_FIELDS}\n mutation TecSubmitProject($input: TecSubmitProjectInput!) {\n tecSubmitProject(input: $input) {\n ...TeamFields\n }\n }\n`;\n\n/* ------- admin / authoring mutations ------- */\n\nconst CREATE_COURSE = gql`\n ${COURSE_FIELDS}\n mutation TecCreateCourse($input: TecCreateCourseInput!) {\n tecCreateCourse(input: $input) {\n ...CourseFields\n }\n }\n`;\n\nconst PUBLISH_COURSE = gql`\n ${COURSE_FIELDS}\n mutation TecPublishCourse($id: ID!) {\n tecPublishCourse(id: $id) {\n ...CourseFields\n }\n }\n`;\n\nconst ARCHIVE_COURSE = gql`\n mutation TecArchiveCourse($id: ID!) {\n tecArchiveCourse(id: $id)\n }\n`;\n\nconst CREATE_LESSON = gql`\n ${LESSON_FIELDS}\n mutation TecCreateLesson($input: TecCreateLessonInput!) {\n tecCreateLesson(input: $input) {\n ...LessonFields\n }\n }\n`;\n\nconst CREATE_PROBLEM = gql`\n ${PROBLEM_FIELDS}\n mutation TecCreateProblem($input: TecCreateProblemInput!) {\n tecCreateProblem(input: $input) {\n ...ProblemFields\n }\n }\n`;\n\nconst PUBLISH_PROBLEM = gql`\n ${PROBLEM_FIELDS}\n mutation TecPublishProblem($id: ID!) {\n tecPublishProblem(id: $id) {\n ...ProblemFields\n }\n }\n`;\n\nconst CREATE_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n mutation TecCreateHackathon($input: TecCreateHackathonInput!) {\n tecCreateHackathon(input: $input) {\n ...HackathonFields\n }\n }\n`;\n\nconst OPEN_REGISTRATION = gql`\n ${HACKATHON_FIELDS}\n mutation TecOpenRegistration($id: ID!) {\n tecOpenRegistration(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\nconst APPROVE_MENTOR = gql`\n ${MENTOR_FIELDS}\n mutation TecApproveMentor($id: ID!) {\n tecApproveMentor(id: $id) {\n ...MentorFields\n }\n }\n`;\n\nconst SCORE_TEAM = gql`\n ${TEAM_FIELDS}\n mutation TecScoreTeam($id: ID!, $score: Int!, $winner: Boolean) {\n tecScoreTeam(id: $id, score: $score, winner: $winner) {\n ...TeamFields\n }\n }\n`;\n\nconst CONFIRM_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecConfirmSession($id: ID!, $meetingUrl: String) {\n tecConfirmSession(id: $id, meetingUrl: $meetingUrl) {\n ...SessionFields\n }\n }\n`;\n\nconst COMPLETE_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecCompleteSession($id: ID!, $rating: Int, $feedback: String) {\n tecCompleteSession(id: $id, rating: $rating, feedback: $feedback) {\n ...SessionFields\n }\n }\n`;\n\nconst GRADE_SUBMISSION = gql`\n ${SUBMISSION_FIELDS}\n mutation TecGradeSubmission($id: ID!, $verdict: TecSubmissionVerdict!, $runtimeMs: Int) {\n tecGradeSubmission(id: $id, verdict: $verdict, runtimeMs: $runtimeMs) {\n ...SubmissionFields\n }\n }\n`;\n\nconst ISSUE_CERTIFICATE = gql`\n ${CERTIFICATE_FIELDS}\n mutation TecIssueCertificate($courseId: ID!, $learnerId: ID!, $score: Int!) {\n tecIssueCertificate(courseId: $courseId, learnerId: $learnerId, score: $score) {\n ...CertificateFields\n }\n }\n`;\n\nconst REVOKE_CERTIFICATE = gql`\n ${CERTIFICATE_FIELDS}\n mutation TecRevokeCertificate($id: ID!, $reason: String) {\n tecRevokeCertificate(id: $id, reason: $reason) {\n ...CertificateFields\n }\n }\n`;\n\nconst START_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n mutation TecStartHackathon($id: ID!) {\n tecStartHackathon(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\nconst START_JUDGING = gql`\n ${HACKATHON_FIELDS}\n mutation TecStartJudging($id: ID!) {\n tecStartJudging(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\nconst COMPLETE_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n mutation TecCompleteHackathon($id: ID!) {\n tecCompleteHackathon(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\n/* ---------------------------------------------------------- mutation hooks */\n\nexport const useEnroll = () =>\n useMutation<{ tecEnroll: TecEnrollment }>(ENROLL, {\n onError: onMutationError,\n refetchQueries: [REFETCH.enrollments, REFETCH.courses],\n });\n\nexport const useUpdateProgress = () =>\n useMutation<{ tecUpdateProgress: TecEnrollment }>(UPDATE_PROGRESS, {\n onError: onMutationError,\n refetchQueries: [REFETCH.enrollments],\n });\n\nexport const useSubmitSolution = () =>\n useMutation<{ tecSubmitSolution: TecSubmission }>(SUBMIT_SOLUTION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.submissions],\n });\n\nexport const useBookSession = () =>\n useMutation<{ tecBookSession: TecMentorSession }>(BOOK_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions, REFETCH.mentors],\n });\n\nexport const useCancelSession = () =>\n useMutation<{ tecCancelSession: TecMentorSession }>(CANCEL_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions],\n });\n\nexport const useBecomeMentor = () =>\n useMutation<{ tecBecomeMentor: TecMentor }>(BECOME_MENTOR, {\n onError: onMutationError,\n refetchQueries: [REFETCH.mentors],\n });\n\nexport const useRegisterTeam = () =>\n useMutation<{ tecRegisterTeam: TecHackathonTeam }>(REGISTER_TEAM, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useSubmitProject = () =>\n useMutation<{ tecSubmitProject: TecHackathonTeam }>(SUBMIT_PROJECT, {\n onError: onMutationError,\n });\n\nexport const useCreateCourse = () =>\n useMutation<{ tecCreateCourse: TecCourse }>(CREATE_COURSE, {\n onError: onMutationError,\n refetchQueries: [REFETCH.courses],\n });\n\nexport const usePublishCourse = () =>\n useMutation<{ tecPublishCourse: TecCourse }>(PUBLISH_COURSE, {\n onError: onMutationError,\n refetchQueries: [REFETCH.courses],\n });\n\nexport const useArchiveCourse = () =>\n useMutation<{ tecArchiveCourse: boolean }>(ARCHIVE_COURSE, {\n onError: onMutationError,\n refetchQueries: [REFETCH.courses],\n });\n\nexport const useCreateLesson = () =>\n useMutation<{ tecCreateLesson: TecLesson }>(CREATE_LESSON, { onError: onMutationError });\n\nexport const useCreateProblem = () =>\n useMutation<{ tecCreateProblem: TecProblem }>(CREATE_PROBLEM, {\n onError: onMutationError,\n refetchQueries: [REFETCH.problems],\n });\n\nexport const usePublishProblem = () =>\n useMutation<{ tecPublishProblem: TecProblem }>(PUBLISH_PROBLEM, {\n onError: onMutationError,\n refetchQueries: [REFETCH.problems],\n });\n\nexport const useCreateHackathon = () =>\n useMutation<{ tecCreateHackathon: TecHackathon }>(CREATE_HACKATHON, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useOpenRegistration = () =>\n useMutation<{ tecOpenRegistration: TecHackathon }>(OPEN_REGISTRATION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useApproveMentor = () =>\n useMutation<{ tecApproveMentor: TecMentor }>(APPROVE_MENTOR, {\n onError: onMutationError,\n refetchQueries: [REFETCH.mentors],\n });\n\nexport const useScoreTeam = () =>\n useMutation<{ tecScoreTeam: TecHackathonTeam }>(SCORE_TEAM, { onError: onMutationError });\n\nexport const useConfirmSession = () =>\n useMutation<{ tecConfirmSession: TecMentorSession }>(CONFIRM_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions],\n });\n\nexport const useCompleteSession = () =>\n useMutation<{ tecCompleteSession: TecMentorSession }>(COMPLETE_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions],\n });\n\nexport const useGradeSubmission = () =>\n useMutation<{ tecGradeSubmission: TecSubmission }>(GRADE_SUBMISSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.submissions],\n });\n\nexport const useIssueCertificate = () =>\n useMutation<{ tecIssueCertificate: TecCertificate }>(ISSUE_CERTIFICATE, {\n onError: onMutationError,\n });\n\nexport const useRevokeCertificate = () =>\n useMutation<{ tecRevokeCertificate: TecCertificate }>(REVOKE_CERTIFICATE, {\n onError: onMutationError,\n });\n\nexport const useStartHackathon = () =>\n useMutation<{ tecStartHackathon: TecHackathon }>(START_HACKATHON, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useStartJudging = () =>\n useMutation<{ tecStartJudging: TecHackathon }>(START_JUDGING, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useCompleteHackathon = () =>\n useMutation<{ tecCompleteHackathon: TecHackathon }>(COMPLETE_HACKATHON, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\n/* ------------------------------------------------------- pagination helper */\n\nexport interface PageLimit {\n limit: number;\n more: () => void;\n}\n\n/**\n * Simple, robust \"load more\". The backend paginates with `take = limit + 1`\n * (offset is ignored; only `cursor` shifts the window), so a larger `limit`\n * simply fetches more rows from the top and `pageInfo.hasMore` reports whether\n * still more exist. Growing the limit avoids cursor-merge/fetchMore complexity\n * and never sends `cursor: null` (the page-1 500 guard). Pass `limit` into the\n * query's `pageArg` and render <LoadMore hasMore={...} onClick={more} />.\n */\nexport function usePageLimit(step = 24, initial = 24): PageLimit {\n const [limit, setLimit] = useState(initial);\n return { limit, more: () => setLimit((l) => l + step) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"technospamApi.js","names":[],"sources":["../../../src/technospam/api/technospamApi.ts"],"sourcesContent":["/**\n * TechnoSpam data layer — Apollo operations + typed hooks over the\n * wspace-technospam-svc subgraph (Tec* fields), reached through the host\n * shell's default workspace ApolloProvider (defaultGateway: \"workspace\").\n *\n * Every page consumes real backend data through these hooks. There is NO mock\n * data. List queries are cursor-paginated: page 1 omits `cursor` entirely\n * (passing cursor: null makes the Prisma cursor resolver 500), \"load more\"\n * passes the previous page's `pageInfo.cursor`.\n */\nimport { useState } from 'react';\nimport { gql, type ErrorLike } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\n\nimport { notify } from '../lib/toast';\n\n/* ------------------------------------------------------------------ enums */\n\nexport type TecCourseLevel = 'BEGINNER' | 'INTERMEDIATE' | 'ADVANCED' | 'EXPERT';\nexport type TecCourseStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\nexport type TecLessonKind = 'VIDEO' | 'ARTICLE' | 'INTERACTIVE' | 'QUIZ' | 'PROJECT';\nexport type TecEnrollmentStatus = 'ENROLLED' | 'IN_PROGRESS' | 'COMPLETED' | 'DROPPED';\nexport type TecCertificateStatus = 'ISSUED' | 'REVOKED';\nexport type TecProblemDifficulty = 'EASY' | 'MEDIUM' | 'HARD';\nexport type TecProblemStatus = 'DRAFT' | 'PUBLISHED' | 'ARCHIVED';\nexport type TecInterviewFrequency = 'LOW' | 'MEDIUM' | 'HIGH';\nexport type TecSubmissionVerdict =\n | 'PENDING'\n | 'ACCEPTED'\n | 'WRONG_ANSWER'\n | 'TIME_LIMIT_EXCEEDED'\n | 'RUNTIME_ERROR'\n | 'COMPILE_ERROR';\nexport type TecMentorStatus = 'PENDING' | 'ACTIVE' | 'PAUSED' | 'INACTIVE';\nexport type TecSessionStatus = 'REQUESTED' | 'CONFIRMED' | 'COMPLETED' | 'CANCELLED' | 'NO_SHOW';\nexport type TecHackathonStatus =\n 'DRAFT' | 'REGISTRATION_OPEN' | 'IN_PROGRESS' | 'JUDGING' | 'COMPLETED' | 'CANCELLED';\nexport type TecTeamSubmissionStatus = 'DRAFT' | 'SUBMITTED' | 'DISQUALIFIED' | 'WINNER';\n\n/* ------------------------------------------------------------------ types */\n\nexport interface TecCourse {\n id: string;\n slug: string;\n title: string;\n summary?: string | null;\n topic?: string | null;\n level: TecCourseLevel;\n status: TecCourseStatus;\n tags: string[];\n estimatedMinutes: number;\n instructorId?: string | null;\n publishedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n lessons?: TecLesson[];\n enrollments?: TecEnrollment[];\n}\n\nexport interface TecLesson {\n id: string;\n courseId: string;\n title: string;\n kind: TecLessonKind;\n content?: string | null;\n position: number;\n estimatedMinutes: number;\n isPreview: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface TecEnrollment {\n id: string;\n courseId: string;\n learnerId: string;\n status: TecEnrollmentStatus;\n progressPct: number;\n lessonsCompleted: number;\n startedAt: string;\n lastActiveAt?: string | null;\n completedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n course?: TecCourse | null;\n}\n\nexport interface TecCertificate {\n id: string;\n courseId: string;\n learnerId: string;\n serial: string;\n score: number;\n status: TecCertificateStatus;\n issuedAt: string;\n revokedAt?: string | null;\n revokeReason?: string | null;\n createdAt: string;\n course?: TecCourse | null;\n}\n\nexport interface TecProblem {\n id: string;\n slug: string;\n title: string;\n statement?: string | null;\n topic?: string | null;\n difficulty: TecProblemDifficulty;\n status: TecProblemStatus;\n tags: string[];\n languages: string[];\n companies: string[];\n roles: string[];\n interviewFrequency?: TecInterviewFrequency | null;\n points: number;\n starterCode?: string | null;\n publishedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n submissions?: TecSubmission[];\n}\n\nexport interface TecSubmission {\n id: string;\n problemId: string;\n learnerId: string;\n language: string;\n code: string;\n verdict: TecSubmissionVerdict;\n runtimeMs: number;\n pointsAwarded: number;\n judgedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n problem?: TecProblem | null;\n}\n\nexport interface TecMentor {\n id: string;\n userId: string;\n headline: string;\n bio?: string | null;\n expertise: string[];\n hourlyRate: number;\n currency: string;\n status: TecMentorStatus;\n isAcceptingMentees: boolean;\n ratingAvg: number;\n sessionsCount: number;\n createdAt: string;\n updatedAt: string;\n sessions?: TecMentorSession[];\n}\n\nexport interface TecMentorSession {\n id: string;\n mentorId: string;\n menteeId: string;\n topic: string;\n agenda?: string | null;\n scheduledAt: string;\n durationMinutes: number;\n status: TecSessionStatus;\n meetingUrl?: string | null;\n rating?: number | null;\n feedback?: string | null;\n completedAt?: string | null;\n cancelledAt?: string | null;\n createdAt: string;\n updatedAt: string;\n mentor?: TecMentor | null;\n}\n\nexport interface TecHackathon {\n id: string;\n slug: string;\n title: string;\n theme?: string | null;\n description?: string | null;\n status: TecHackathonStatus;\n startAt: string;\n endAt: string;\n submissionDeadline?: string | null;\n prizePool: number;\n currency: string;\n maxTeamSize: number;\n tags: string[];\n createdAt: string;\n updatedAt: string;\n teams?: TecHackathonTeam[];\n}\n\nexport interface TecHackathonTeam {\n id: string;\n hackathonId: string;\n name: string;\n captainId: string;\n memberIds: string[];\n projectName?: string | null;\n projectUrl?: string | null;\n repoUrl?: string | null;\n pitch?: string | null;\n status: TecTeamSubmissionStatus;\n score: number;\n submittedAt?: string | null;\n createdAt: string;\n updatedAt: string;\n hackathon?: TecHackathon | null;\n}\n\nexport interface TecPageInfo {\n cursor?: string | null;\n hasMore: boolean;\n}\n\nexport interface PaginationInput {\n limit?: number;\n cursor?: string | null;\n}\n\n/** Build a pagination arg that NEVER sends cursor:null (page-1 500 guard). */\nexport function pageArg(limit = 50, cursor?: string | null): { limit: number; cursor?: string } {\n return cursor ? { limit, cursor } : { limit };\n}\n\n/* -------------------------------------------------------------- fragments */\n\nconst COURSE_FIELDS = gql`\n fragment CourseFields on TecCourse {\n id\n slug\n title\n summary\n topic\n level\n status\n tags\n estimatedMinutes\n instructorId\n publishedAt\n createdAt\n updatedAt\n }\n`;\n\nconst LESSON_FIELDS = gql`\n fragment LessonFields on TecLesson {\n id\n courseId\n title\n kind\n content\n position\n estimatedMinutes\n isPreview\n createdAt\n updatedAt\n }\n`;\n\nconst ENROLLMENT_FIELDS = gql`\n fragment EnrollmentFields on TecEnrollment {\n id\n courseId\n learnerId\n status\n progressPct\n lessonsCompleted\n startedAt\n lastActiveAt\n completedAt\n createdAt\n updatedAt\n }\n`;\n\nconst PROBLEM_FIELDS = gql`\n fragment ProblemFields on TecProblem {\n id\n slug\n title\n statement\n topic\n difficulty\n status\n tags\n languages\n companies\n roles\n interviewFrequency\n points\n starterCode\n publishedAt\n createdAt\n updatedAt\n }\n`;\n\nconst SUBMISSION_FIELDS = gql`\n fragment SubmissionFields on TecSubmission {\n id\n problemId\n learnerId\n language\n code\n verdict\n runtimeMs\n pointsAwarded\n judgedAt\n createdAt\n updatedAt\n }\n`;\n\nconst MENTOR_FIELDS = gql`\n fragment MentorFields on TecMentor {\n id\n userId\n headline\n bio\n expertise\n hourlyRate\n currency\n status\n isAcceptingMentees\n ratingAvg\n sessionsCount\n createdAt\n updatedAt\n }\n`;\n\nconst SESSION_FIELDS = gql`\n fragment SessionFields on TecMentorSession {\n id\n mentorId\n menteeId\n topic\n agenda\n scheduledAt\n durationMinutes\n status\n meetingUrl\n rating\n feedback\n completedAt\n cancelledAt\n createdAt\n updatedAt\n }\n`;\n\nconst HACKATHON_FIELDS = gql`\n fragment HackathonFields on TecHackathon {\n id\n slug\n title\n theme\n description\n status\n startAt\n endAt\n submissionDeadline\n prizePool\n currency\n maxTeamSize\n tags\n createdAt\n updatedAt\n }\n`;\n\nconst TEAM_FIELDS = gql`\n fragment TeamFields on TecHackathonTeam {\n id\n hackathonId\n name\n captainId\n memberIds\n projectName\n projectUrl\n repoUrl\n pitch\n status\n score\n submittedAt\n createdAt\n updatedAt\n }\n`;\n\nconst CERTIFICATE_FIELDS = gql`\n fragment CertificateFields on TecCertificate {\n id\n courseId\n learnerId\n serial\n score\n status\n issuedAt\n revokedAt\n revokeReason\n createdAt\n }\n`;\n\n/* --------------------------------------------------------------- queries */\n\nconst LIST_COURSES = gql`\n ${COURSE_FIELDS}\n query TecListCourses(\n $level: TecCourseLevel\n $status: TecCourseStatus\n $pagination: PaginationInput\n ) {\n tecListCourses(level: $level, status: $status, pagination: $pagination) {\n items {\n ...CourseFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_COURSE = gql`\n ${COURSE_FIELDS}\n ${LESSON_FIELDS}\n ${ENROLLMENT_FIELDS}\n query TecCourse($id: ID!) {\n tecCourse(id: $id) {\n ...CourseFields\n lessons {\n ...LessonFields\n }\n enrollments {\n ...EnrollmentFields\n }\n }\n }\n`;\n\nconst LIST_ENROLLMENTS = gql`\n ${ENROLLMENT_FIELDS}\n ${COURSE_FIELDS}\n query TecListEnrollments($learnerId: ID, $courseId: ID, $pagination: PaginationInput) {\n tecListEnrollments(learnerId: $learnerId, courseId: $courseId, pagination: $pagination) {\n items {\n ...EnrollmentFields\n course {\n ...CourseFields\n }\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst LIST_CERTIFICATES = gql`\n ${CERTIFICATE_FIELDS}\n ${COURSE_FIELDS}\n query TecListCertificates($learnerId: ID, $courseId: ID) {\n tecListCertificates(learnerId: $learnerId, courseId: $courseId) {\n ...CertificateFields\n course {\n ...CourseFields\n }\n }\n }\n`;\n\nconst LIST_PROBLEMS = gql`\n ${PROBLEM_FIELDS}\n query TecListProblems(\n $difficulty: TecProblemDifficulty\n $status: TecProblemStatus\n $topic: String\n $company: String\n $role: String\n $interviewFrequency: TecInterviewFrequency\n $pagination: PaginationInput\n ) {\n tecListProblems(\n difficulty: $difficulty\n status: $status\n topic: $topic\n company: $company\n role: $role\n interviewFrequency: $interviewFrequency\n pagination: $pagination\n ) {\n items {\n ...ProblemFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_PROBLEM = gql`\n ${PROBLEM_FIELDS}\n ${SUBMISSION_FIELDS}\n query TecProblem($id: ID!) {\n tecProblem(id: $id) {\n ...ProblemFields\n submissions {\n ...SubmissionFields\n }\n }\n }\n`;\n\nconst LIST_SUBMISSIONS = gql`\n ${SUBMISSION_FIELDS}\n ${PROBLEM_FIELDS}\n query TecListSubmissions($learnerId: ID, $problemId: ID, $pagination: PaginationInput) {\n tecListSubmissions(learnerId: $learnerId, problemId: $problemId, pagination: $pagination) {\n items {\n ...SubmissionFields\n problem {\n ...ProblemFields\n }\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst LIST_MENTORS = gql`\n ${MENTOR_FIELDS}\n query TecListMentors($status: TecMentorStatus, $pagination: PaginationInput) {\n tecListMentors(status: $status, pagination: $pagination) {\n items {\n ...MentorFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_MENTOR = gql`\n ${MENTOR_FIELDS}\n ${SESSION_FIELDS}\n query TecMentor($id: ID!) {\n tecMentor(id: $id) {\n ...MentorFields\n sessions {\n ...SessionFields\n }\n }\n }\n`;\n\nconst LIST_SESSIONS = gql`\n ${SESSION_FIELDS}\n ${MENTOR_FIELDS}\n query TecListSessions(\n $mentorId: ID\n $menteeId: ID\n $status: TecSessionStatus\n $pagination: PaginationInput\n ) {\n tecListSessions(\n mentorId: $mentorId\n menteeId: $menteeId\n status: $status\n pagination: $pagination\n ) {\n items {\n ...SessionFields\n mentor {\n ...MentorFields\n }\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst LIST_HACKATHONS = gql`\n ${HACKATHON_FIELDS}\n query TecListHackathons($status: TecHackathonStatus, $pagination: PaginationInput) {\n tecListHackathons(status: $status, pagination: $pagination) {\n items {\n ...HackathonFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst GET_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n ${TEAM_FIELDS}\n query TecHackathon($id: ID!) {\n tecHackathon(id: $id) {\n ...HackathonFields\n teams {\n ...TeamFields\n }\n }\n }\n`;\n\nconst LIST_TEAMS = gql`\n ${TEAM_FIELDS}\n query TecListTeams($hackathonId: ID!, $pagination: PaginationInput) {\n tecListTeams(hackathonId: $hackathonId, pagination: $pagination) {\n items {\n ...TeamFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\nconst LIST_LESSONS = gql`\n ${LESSON_FIELDS}\n query TecListLessons($courseId: ID!, $pagination: PaginationInput) {\n tecListLessons(courseId: $courseId, pagination: $pagination) {\n items {\n ...LessonFields\n }\n pageInfo {\n cursor\n hasMore\n }\n }\n }\n`;\n\n/* ------------------------------------------------------- response typings */\n\ntype Conn<K extends string, T> = Record<K, { items: T[]; pageInfo: TecPageInfo }>;\n\n/* ---------------------------------------------------------- query hooks */\n\nexport const useCoursesQuery = (vars: {\n level?: TecCourseLevel;\n status?: TecCourseStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListCourses', TecCourse>>(LIST_COURSES, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useCourseQuery = (id: string) =>\n useQuery<{ tecCourse: TecCourse | null }>(GET_COURSE, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useEnrollmentsQuery = (vars: { learnerId?: string; courseId?: string }) =>\n useQuery<Conn<'tecListEnrollments', TecEnrollment>>(LIST_ENROLLMENTS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useCertificatesQuery = (vars: { learnerId?: string; courseId?: string }) =>\n useQuery<{ tecListCertificates: TecCertificate[] }>(LIST_CERTIFICATES, {\n variables: vars,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useProblemsQuery = (vars: {\n difficulty?: TecProblemDifficulty;\n status?: TecProblemStatus;\n topic?: string;\n company?: string;\n role?: string;\n interviewFrequency?: TecInterviewFrequency;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListProblems', TecProblem>>(LIST_PROBLEMS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useProblemQuery = (id: string) =>\n useQuery<{ tecProblem: TecProblem | null }>(GET_PROBLEM, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useSubmissionsQuery = (vars: { learnerId?: string; problemId?: string }) =>\n useQuery<Conn<'tecListSubmissions', TecSubmission>>(LIST_SUBMISSIONS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useMentorsQuery = (vars: {\n status?: TecMentorStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListMentors', TecMentor>>(LIST_MENTORS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useMentorQuery = (id: string) =>\n useQuery<{ tecMentor: TecMentor | null }>(GET_MENTOR, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useSessionsQuery = (vars: {\n mentorId?: string;\n menteeId?: string;\n status?: TecSessionStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListSessions', TecMentorSession>>(LIST_SESSIONS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useHackathonsQuery = (vars: {\n status?: TecHackathonStatus;\n pagination?: { limit: number; cursor?: string };\n}) =>\n useQuery<Conn<'tecListHackathons', TecHackathon>>(LIST_HACKATHONS, {\n variables: { pagination: pageArg(50), ...vars },\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useHackathonQuery = (id: string) =>\n useQuery<{ tecHackathon: TecHackathon | null }>(GET_HACKATHON, {\n variables: { id },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useTeamsQuery = (\n hackathonId: string,\n pagination?: { limit: number; cursor?: string }\n) =>\n useQuery<Conn<'tecListTeams', TecHackathonTeam>>(LIST_TEAMS, {\n variables: { hackathonId, pagination: pagination ?? pageArg(50) },\n skip: !hackathonId,\n fetchPolicy: 'cache-and-network',\n });\n\nexport const useLessonsQuery = (\n courseId: string,\n pagination?: { limit: number; cursor?: string }\n) =>\n useQuery<Conn<'tecListLessons', TecLesson>>(LIST_LESSONS, {\n variables: { courseId, pagination: pagination ?? pageArg(50) },\n skip: !courseId,\n fetchPolicy: 'cache-and-network',\n });\n\n/* ------------------------------------------------------------ mutations */\n\nconst onMutationError = (error: ErrorLike): void => {\n notify.error('Something went wrong', error.message || 'Please try again.');\n};\n\nconst REFETCH = {\n courses: 'TecListCourses',\n enrollments: 'TecListEnrollments',\n problems: 'TecListProblems',\n submissions: 'TecListSubmissions',\n mentors: 'TecListMentors',\n sessions: 'TecListSessions',\n hackathons: 'TecListHackathons',\n} as const;\n\nconst ENROLL = gql`\n ${ENROLLMENT_FIELDS}\n mutation TecEnroll($input: TecEnrollInput!) {\n tecEnroll(input: $input) {\n ...EnrollmentFields\n }\n }\n`;\n\nconst UPDATE_PROGRESS = gql`\n ${ENROLLMENT_FIELDS}\n mutation TecUpdateProgress($input: TecUpdateProgressInput!) {\n tecUpdateProgress(input: $input) {\n ...EnrollmentFields\n }\n }\n`;\n\nconst SUBMIT_SOLUTION = gql`\n ${SUBMISSION_FIELDS}\n mutation TecSubmitSolution($input: TecSubmitSolutionInput!) {\n tecSubmitSolution(input: $input) {\n ...SubmissionFields\n }\n }\n`;\n\nconst BOOK_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecBookSession($input: TecBookSessionInput!) {\n tecBookSession(input: $input) {\n ...SessionFields\n }\n }\n`;\n\nconst CANCEL_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecCancelSession($id: ID!) {\n tecCancelSession(id: $id) {\n ...SessionFields\n }\n }\n`;\n\nconst BECOME_MENTOR = gql`\n ${MENTOR_FIELDS}\n mutation TecBecomeMentor($input: TecCreateMentorInput!) {\n tecBecomeMentor(input: $input) {\n ...MentorFields\n }\n }\n`;\n\nconst REGISTER_TEAM = gql`\n ${TEAM_FIELDS}\n mutation TecRegisterTeam($input: TecRegisterTeamInput!) {\n tecRegisterTeam(input: $input) {\n ...TeamFields\n }\n }\n`;\n\nconst SUBMIT_PROJECT = gql`\n ${TEAM_FIELDS}\n mutation TecSubmitProject($input: TecSubmitProjectInput!) {\n tecSubmitProject(input: $input) {\n ...TeamFields\n }\n }\n`;\n\n/* ------- admin / authoring mutations ------- */\n\nconst CREATE_COURSE = gql`\n ${COURSE_FIELDS}\n mutation TecCreateCourse($input: TecCreateCourseInput!) {\n tecCreateCourse(input: $input) {\n ...CourseFields\n }\n }\n`;\n\nconst PUBLISH_COURSE = gql`\n ${COURSE_FIELDS}\n mutation TecPublishCourse($id: ID!) {\n tecPublishCourse(id: $id) {\n ...CourseFields\n }\n }\n`;\n\nconst ARCHIVE_COURSE = gql`\n mutation TecArchiveCourse($id: ID!) {\n tecArchiveCourse(id: $id)\n }\n`;\n\nconst CREATE_LESSON = gql`\n ${LESSON_FIELDS}\n mutation TecCreateLesson($input: TecCreateLessonInput!) {\n tecCreateLesson(input: $input) {\n ...LessonFields\n }\n }\n`;\n\nconst CREATE_PROBLEM = gql`\n ${PROBLEM_FIELDS}\n mutation TecCreateProblem($input: TecCreateProblemInput!) {\n tecCreateProblem(input: $input) {\n ...ProblemFields\n }\n }\n`;\n\nconst PUBLISH_PROBLEM = gql`\n ${PROBLEM_FIELDS}\n mutation TecPublishProblem($id: ID!) {\n tecPublishProblem(id: $id) {\n ...ProblemFields\n }\n }\n`;\n\nconst CREATE_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n mutation TecCreateHackathon($input: TecCreateHackathonInput!) {\n tecCreateHackathon(input: $input) {\n ...HackathonFields\n }\n }\n`;\n\nconst OPEN_REGISTRATION = gql`\n ${HACKATHON_FIELDS}\n mutation TecOpenRegistration($id: ID!) {\n tecOpenRegistration(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\nconst APPROVE_MENTOR = gql`\n ${MENTOR_FIELDS}\n mutation TecApproveMentor($id: ID!) {\n tecApproveMentor(id: $id) {\n ...MentorFields\n }\n }\n`;\n\nconst SCORE_TEAM = gql`\n ${TEAM_FIELDS}\n mutation TecScoreTeam($id: ID!, $score: Int!, $winner: Boolean) {\n tecScoreTeam(id: $id, score: $score, winner: $winner) {\n ...TeamFields\n }\n }\n`;\n\nconst CONFIRM_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecConfirmSession($id: ID!, $meetingUrl: String) {\n tecConfirmSession(id: $id, meetingUrl: $meetingUrl) {\n ...SessionFields\n }\n }\n`;\n\nconst COMPLETE_SESSION = gql`\n ${SESSION_FIELDS}\n mutation TecCompleteSession($id: ID!, $rating: Int, $feedback: String) {\n tecCompleteSession(id: $id, rating: $rating, feedback: $feedback) {\n ...SessionFields\n }\n }\n`;\n\nconst GRADE_SUBMISSION = gql`\n ${SUBMISSION_FIELDS}\n mutation TecGradeSubmission($id: ID!, $verdict: TecSubmissionVerdict!, $runtimeMs: Int) {\n tecGradeSubmission(id: $id, verdict: $verdict, runtimeMs: $runtimeMs) {\n ...SubmissionFields\n }\n }\n`;\n\nconst ISSUE_CERTIFICATE = gql`\n ${CERTIFICATE_FIELDS}\n mutation TecIssueCertificate($courseId: ID!, $learnerId: ID!, $score: Int!) {\n tecIssueCertificate(courseId: $courseId, learnerId: $learnerId, score: $score) {\n ...CertificateFields\n }\n }\n`;\n\nconst REVOKE_CERTIFICATE = gql`\n ${CERTIFICATE_FIELDS}\n mutation TecRevokeCertificate($id: ID!, $reason: String) {\n tecRevokeCertificate(id: $id, reason: $reason) {\n ...CertificateFields\n }\n }\n`;\n\nconst START_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n mutation TecStartHackathon($id: ID!) {\n tecStartHackathon(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\nconst START_JUDGING = gql`\n ${HACKATHON_FIELDS}\n mutation TecStartJudging($id: ID!) {\n tecStartJudging(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\nconst COMPLETE_HACKATHON = gql`\n ${HACKATHON_FIELDS}\n mutation TecCompleteHackathon($id: ID!) {\n tecCompleteHackathon(id: $id) {\n ...HackathonFields\n }\n }\n`;\n\n/* ---------------------------------------------------------- mutation hooks */\n\nexport const useEnroll = () =>\n useMutation<{ tecEnroll: TecEnrollment }>(ENROLL, {\n onError: onMutationError,\n refetchQueries: [REFETCH.enrollments, REFETCH.courses],\n });\n\nexport const useUpdateProgress = () =>\n useMutation<{ tecUpdateProgress: TecEnrollment }>(UPDATE_PROGRESS, {\n onError: onMutationError,\n refetchQueries: [REFETCH.enrollments],\n });\n\nexport const useSubmitSolution = () =>\n useMutation<{ tecSubmitSolution: TecSubmission }>(SUBMIT_SOLUTION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.submissions],\n });\n\nexport const useBookSession = () =>\n useMutation<{ tecBookSession: TecMentorSession }>(BOOK_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions, REFETCH.mentors],\n });\n\nexport const useCancelSession = () =>\n useMutation<{ tecCancelSession: TecMentorSession }>(CANCEL_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions],\n });\n\nexport const useBecomeMentor = () =>\n useMutation<{ tecBecomeMentor: TecMentor }>(BECOME_MENTOR, {\n onError: onMutationError,\n refetchQueries: [REFETCH.mentors],\n });\n\nexport const useRegisterTeam = () =>\n useMutation<{ tecRegisterTeam: TecHackathonTeam }>(REGISTER_TEAM, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useSubmitProject = () =>\n useMutation<{ tecSubmitProject: TecHackathonTeam }>(SUBMIT_PROJECT, {\n onError: onMutationError,\n });\n\nexport const useCreateCourse = () =>\n useMutation<{ tecCreateCourse: TecCourse }>(CREATE_COURSE, {\n onError: onMutationError,\n refetchQueries: [REFETCH.courses],\n });\n\nexport const usePublishCourse = () =>\n useMutation<{ tecPublishCourse: TecCourse }>(PUBLISH_COURSE, {\n onError: onMutationError,\n refetchQueries: [REFETCH.courses],\n });\n\nexport const useArchiveCourse = () =>\n useMutation<{ tecArchiveCourse: boolean }>(ARCHIVE_COURSE, {\n onError: onMutationError,\n refetchQueries: [REFETCH.courses],\n });\n\nexport const useCreateLesson = () =>\n useMutation<{ tecCreateLesson: TecLesson }>(CREATE_LESSON, { onError: onMutationError });\n\nexport const useCreateProblem = () =>\n useMutation<{ tecCreateProblem: TecProblem }>(CREATE_PROBLEM, {\n onError: onMutationError,\n refetchQueries: [REFETCH.problems],\n });\n\nexport const usePublishProblem = () =>\n useMutation<{ tecPublishProblem: TecProblem }>(PUBLISH_PROBLEM, {\n onError: onMutationError,\n refetchQueries: [REFETCH.problems],\n });\n\nexport const useCreateHackathon = () =>\n useMutation<{ tecCreateHackathon: TecHackathon }>(CREATE_HACKATHON, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useOpenRegistration = () =>\n useMutation<{ tecOpenRegistration: TecHackathon }>(OPEN_REGISTRATION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useApproveMentor = () =>\n useMutation<{ tecApproveMentor: TecMentor }>(APPROVE_MENTOR, {\n onError: onMutationError,\n refetchQueries: [REFETCH.mentors],\n });\n\nexport const useScoreTeam = () =>\n useMutation<{ tecScoreTeam: TecHackathonTeam }>(SCORE_TEAM, { onError: onMutationError });\n\nexport const useConfirmSession = () =>\n useMutation<{ tecConfirmSession: TecMentorSession }>(CONFIRM_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions],\n });\n\nexport const useCompleteSession = () =>\n useMutation<{ tecCompleteSession: TecMentorSession }>(COMPLETE_SESSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.sessions],\n });\n\nexport const useGradeSubmission = () =>\n useMutation<{ tecGradeSubmission: TecSubmission }>(GRADE_SUBMISSION, {\n onError: onMutationError,\n refetchQueries: [REFETCH.submissions],\n });\n\nexport const useIssueCertificate = () =>\n useMutation<{ tecIssueCertificate: TecCertificate }>(ISSUE_CERTIFICATE, {\n onError: onMutationError,\n });\n\nexport const useRevokeCertificate = () =>\n useMutation<{ tecRevokeCertificate: TecCertificate }>(REVOKE_CERTIFICATE, {\n onError: onMutationError,\n });\n\nexport const useStartHackathon = () =>\n useMutation<{ tecStartHackathon: TecHackathon }>(START_HACKATHON, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useStartJudging = () =>\n useMutation<{ tecStartJudging: TecHackathon }>(START_JUDGING, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\nexport const useCompleteHackathon = () =>\n useMutation<{ tecCompleteHackathon: TecHackathon }>(COMPLETE_HACKATHON, {\n onError: onMutationError,\n refetchQueries: [REFETCH.hackathons],\n });\n\n/* ------------------------------------------------------- pagination helper */\n\nexport interface PageLimit {\n limit: number;\n more: () => void;\n}\n\n/**\n * Simple, robust \"load more\". The backend paginates with `take = limit + 1`\n * (offset is ignored; only `cursor` shifts the window), so a larger `limit`\n * simply fetches more rows from the top and `pageInfo.hasMore` reports whether\n * still more exist. Growing the limit avoids cursor-merge/fetchMore complexity\n * and never sends `cursor: null` (the page-1 500 guard). Pass `limit` into the\n * query's `pageArg` and render <LoadMore hasMore={...} onClick={more} />.\n */\nexport function usePageLimit(step = 24, initial = 24): PageLimit {\n const [limit, setLimit] = useState(initial);\n return { limit, more: () => setLimit((l) => l + step) };\n}\n"],"mappings":";;;;;AA6NA,SAAgB,EAAQ,IAAQ,IAAI,GAA4D;AAC9F,QAAO,IAAS;EAAE;EAAO;EAAQ,GAAG,EAAE,UAAO;;AAK/C,IAAM,IAAgB,CAAG;;;;;;;;;;;;;;;;GAkBnB,IAAgB,CAAG;;;;;;;;;;;;;GAenB,IAAoB,CAAG;;;;;;;;;;;;;;GAgBvB,IAAiB,CAAG;;;;;;;;;;;;;;;;;;;;GAsBpB,IAAoB,CAAG;;;;;;;;;;;;;;GAgBvB,IAAgB,CAAG;;;;;;;;;;;;;;;;GAkBnB,IAAiB,CAAG;;;;;;;;;;;;;;;;;;GAoBpB,IAAmB,CAAG;;;;;;;;;;;;;;;;;;GAoBtB,IAAc,CAAG;;;;;;;;;;;;;;;;;GAmBjB,IAAqB,CAAG;;;;;;;;;;;;;GAiBxB,IAAe,CAAG;IACpB,EAAc;;;;;;;;;;;;;;;;GAkBZ,IAAa,CAAG;IAClB,EAAc;IACd,EAAc;IACd,EAAkB;;;;;;;;;;;;GAchB,KAAmB,CAAG;IACxB,EAAkB;IAClB,EAAc;;;;;;;;;;;;;;;GAiBZ,KAAoB,CAAG;IACzB,EAAmB;IACnB,EAAc;;;;;;;;;GAWZ,IAAgB,CAAG;IACrB,EAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8Bb,IAAc,CAAG;IACnB,EAAe;IACf,EAAkB;;;;;;;;;GAWhB,IAAmB,CAAG;IACxB,EAAkB;IAClB,EAAe;;;;;;;;;;;;;;;GAiBb,IAAe,CAAG;IACpB,EAAc;;;;;;;;;;;;GAcZ,IAAa,CAAG;IAClB,EAAc;IACd,EAAe;;;;;;;;;GAWb,IAAgB,CAAG;IACrB,EAAe;IACf,EAAc;;;;;;;;;;;;;;;;;;;;;;;;;GA2BZ,IAAkB,CAAG;IACvB,EAAiB;;;;;;;;;;;;GAcf,IAAgB,CAAG;IACrB,EAAiB;IACjB,EAAY;;;;;;;;;GAWV,IAAa,CAAG;IAClB,EAAY;;;;;;;;;;;;GAcV,IAAe,CAAG;IACpB,EAAc;;;;;;;;;;;;GAoBL,KAAmB,MAK9B,EAA4C,GAAc;CACxD,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAkB,MAC7B,EAA0C,GAAY;CACpD,WAAW,EAAE,OAAI;CACjB,MAAM,CAAC;CACP,aAAa;CACd,CAAC,EAES,KAAuB,MAClC,EAAoD,IAAkB;CACpE,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAwB,MACnC,EAAoD,IAAmB;CACrE,WAAW;CACX,aAAa;CACd,CAAC,EAES,KAAoB,MAS/B,EAA8C,GAAe;CAC3D,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAmB,MAC9B,EAA4C,GAAa;CACvD,WAAW,EAAE,OAAI;CACjB,MAAM,CAAC;CACP,aAAa;CACd,CAAC,EAES,KAAuB,MAClC,EAAoD,GAAkB;CACpE,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAmB,MAI9B,EAA4C,GAAc;CACxD,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAkB,MAC7B,EAA0C,GAAY;CACpD,WAAW,EAAE,OAAI;CACjB,MAAM,CAAC;CACP,aAAa;CACd,CAAC,EAES,KAAoB,MAM/B,EAAoD,GAAe;CACjE,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAsB,MAIjC,EAAkD,GAAiB;CACjE,WAAW;EAAE,YAAY,EAAQ,GAAG;EAAE,GAAG;EAAM;CAC/C,aAAa;CACd,CAAC,EAES,KAAqB,MAChC,EAAgD,GAAe;CAC7D,WAAW,EAAE,OAAI;CACjB,MAAM,CAAC;CACP,aAAa;CACd,CAAC,EAES,KACX,GACA,MAEA,EAAiD,GAAY;CAC3D,WAAW;EAAE;EAAa,YAAY,KAAc,EAAQ,GAAG;EAAE;CACjE,MAAM,CAAC;CACP,aAAa;CACd,CAAC,EAES,KACX,GACA,MAEA,EAA4C,GAAc;CACxD,WAAW;EAAE;EAAU,YAAY,KAAc,EAAQ,GAAG;EAAE;CAC9D,MAAM,CAAC;CACP,aAAa;CACd,CAAC,EAIE,KAAmB,MAA2B;AAClD,GAAO,MAAM,wBAAwB,EAAM,WAAW,oBAAoB;GAGtE,IAAU;CACd,SAAS;CACT,aAAa;CACb,UAAU;CACV,aAAa;CACb,SAAS;CACT,UAAU;CACV,YAAY;CACb,EAEK,IAAS,CAAG;IACd,EAAkB;;;;;;GAQhB,IAAkB,CAAG;IACvB,EAAkB;;;;;;GAQhB,IAAkB,CAAG;IACvB,EAAkB;;;;;;GAQhB,IAAe,CAAG;IACpB,EAAe;;;;;;GAQb,IAAiB,CAAG;IACtB,EAAe;;;;;;GAQb,IAAgB,CAAG;IACrB,EAAc;;;;;;GAQZ,IAAgB,CAAG;IACrB,EAAY;;;;;;GAQV,IAAiB,CAAG;IACtB,EAAY;;;;;;GAUV,IAAgB,CAAG;IACrB,EAAc;;;;;;GAQZ,KAAiB,CAAG;IACtB,EAAc;;;;;;GAQZ,KAAiB,CAAG;;;;GAMpB,KAAgB,CAAG;IACrB,EAAc;;;;;;GAQZ,KAAiB,CAAG;IACtB,EAAe;;;;;;GAQb,KAAkB,CAAG;IACvB,EAAe;;;;;;GAQb,KAAmB,CAAG;IACxB,EAAiB;;;;;;GAQf,KAAoB,CAAG;IACzB,EAAiB;;;;;;GAQf,KAAiB,CAAG;IACtB,EAAc;;;;;;GAQZ,KAAa,CAAG;IAClB,EAAY;;;;;;GAQV,KAAkB,CAAG;IACvB,EAAe;;;;;;GAQb,KAAmB,CAAG;IACxB,EAAe;;;;;;GAQb,KAAmB,CAAG;IACxB,EAAkB;;;;;;GAQhB,KAAoB,CAAG;IACzB,EAAmB;;;;;;;AAQI,CAAG;IAC1B,EAAmB;;;;;;;AAQvB,IAAM,KAAkB,CAAG;IACvB,EAAiB;;;;;;GAQf,KAAgB,CAAG;IACrB,EAAiB;;;;;;GAQf,KAAqB,CAAG;IAC1B,EAAiB;;;;;;GAUR,WACX,EAA0C,GAAQ;CAChD,SAAS;CACT,gBAAgB,CAAC,EAAQ,aAAa,EAAQ,QAAQ;CACvD,CAAC,EAES,WACX,EAAkD,GAAiB;CACjE,SAAS;CACT,gBAAgB,CAAC,EAAQ,YAAY;CACtC,CAAC,EAES,WACX,EAAkD,GAAiB;CACjE,SAAS;CACT,gBAAgB,CAAC,EAAQ,YAAY;CACtC,CAAC,EAES,WACX,EAAkD,GAAc;CAC9D,SAAS;CACT,gBAAgB,CAAC,EAAQ,UAAU,EAAQ,QAAQ;CACpD,CAAC,EAES,WACX,EAAoD,GAAgB;CAClE,SAAS;CACT,gBAAgB,CAAC,EAAQ,SAAS;CACnC,CAAC,EAES,WACX,EAA4C,GAAe;CACzD,SAAS;CACT,gBAAgB,CAAC,EAAQ,QAAQ;CAClC,CAAC,EAES,WACX,EAAmD,GAAe;CAChE,SAAS;CACT,gBAAgB,CAAC,EAAQ,WAAW;CACrC,CAAC,EAES,WACX,EAAoD,GAAgB,EAClE,SAAS,GACV,CAAC,EAES,WACX,EAA4C,GAAe;CACzD,SAAS;CACT,gBAAgB,CAAC,EAAQ,QAAQ;CAClC,CAAC,EAES,WACX,EAA6C,IAAgB;CAC3D,SAAS;CACT,gBAAgB,CAAC,EAAQ,QAAQ;CAClC,CAAC,EAES,WACX,EAA2C,IAAgB;CACzD,SAAS;CACT,gBAAgB,CAAC,EAAQ,QAAQ;CAClC,CAAC,EAES,WACX,EAA4C,IAAe,EAAE,SAAS,GAAiB,CAAC,EAE7E,WACX,EAA8C,IAAgB;CAC5D,SAAS;CACT,gBAAgB,CAAC,EAAQ,SAAS;CACnC,CAAC,EAES,WACX,EAA+C,IAAiB;CAC9D,SAAS;CACT,gBAAgB,CAAC,EAAQ,SAAS;CACnC,CAAC,EAES,WACX,EAAkD,IAAkB;CAClE,SAAS;CACT,gBAAgB,CAAC,EAAQ,WAAW;CACrC,CAAC,EAES,WACX,EAAmD,IAAmB;CACpE,SAAS;CACT,gBAAgB,CAAC,EAAQ,WAAW;CACrC,CAAC,EAES,WACX,EAA6C,IAAgB;CAC3D,SAAS;CACT,gBAAgB,CAAC,EAAQ,QAAQ;CAClC,CAAC,EAES,UACX,EAAgD,IAAY,EAAE,SAAS,GAAiB,CAAC,EAE9E,WACX,EAAqD,IAAiB;CACpE,SAAS;CACT,gBAAgB,CAAC,EAAQ,SAAS;CACnC,CAAC,EAES,WACX,EAAsD,IAAkB;CACtE,SAAS;CACT,gBAAgB,CAAC,EAAQ,SAAS;CACnC,CAAC,EAES,WACX,EAAmD,IAAkB;CACnE,SAAS;CACT,gBAAgB,CAAC,EAAQ,YAAY;CACtC,CAAC,EAES,WACX,EAAqD,IAAmB,EACtE,SAAS,GACV,CAAC,EAOS,WACX,EAAiD,IAAiB;CAChE,SAAS;CACT,gBAAgB,CAAC,EAAQ,WAAW;CACrC,CAAC,EAES,WACX,EAA+C,IAAe;CAC5D,SAAS;CACT,gBAAgB,CAAC,EAAQ,WAAW;CACrC,CAAC,EAES,WACX,EAAoD,IAAoB;CACtE,SAAS;CACT,gBAAgB,CAAC,EAAQ,WAAW;CACrC,CAAC;AAiBJ,SAAgB,GAAa,IAAO,IAAI,IAAU,IAAe;CAC/D,IAAM,CAAC,GAAO,KAAY,EAAS,EAAQ;AAC3C,QAAO;EAAE;EAAO,YAAY,GAAU,MAAM,IAAI,EAAK;EAAE"}
@@ -134,7 +134,7 @@ function Ee({ leading: e, children: t, actions: n }) {
134
134
  });
135
135
  }
136
136
  function De({ courseId: e }) {
137
- let { data: t, loading: n, refetch: r } = T(e), [i, { loading: a }] = x(), [s, l] = P(""), [u, d] = P("ARTICLE"), [p, h] = P(""), [g, _] = P(""), [v, y] = P(!1), b = [...t?.tecListLessons ?? []].sort((e, t) => e.position - t.position);
137
+ let { data: t, loading: n, refetch: r } = T(e), [i, { loading: a }] = x(), [s, l] = P(""), [u, d] = P("ARTICLE"), [p, h] = P(""), [g, _] = P(""), [v, y] = P(!1), b = [...t?.tecListLessons.items ?? []].sort((e, t) => e.position - t.position);
138
138
  return /* @__PURE__ */ K("div", {
139
139
  className: "mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4",
140
140
  children: [
@@ -317,7 +317,7 @@ function Oe({ problemId: e }) {
317
317
  });
318
318
  }
319
319
  function ke({ hackathon: e }) {
320
- let { data: t, loading: n, refetch: r } = N(e.id), [i] = k(), [a, o] = P(null), [s, c] = P({}), u = t?.tecListTeams ?? [], d = async (e, t) => {
320
+ let { data: t, loading: n, refetch: r } = N(e.id), [i] = k(), [a, o] = P(null), [s, c] = P({}), u = t?.tecListTeams.items ?? [], d = async (e, t) => {
321
321
  let n = Math.max(0, Number(s[e] ?? "0") || 0);
322
322
  o(e);
323
323
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"AdminAdminDashboardPagePage.js","names":[],"sources":["../../../src/technospam/pages/AdminAdminDashboardPagePage.tsx"],"sourcesContent":["import { useState, type ReactNode } from 'react';\nimport {\n Archive,\n Award,\n BookOpen,\n Code2,\n Gavel,\n ListChecks,\n Play,\n Plus,\n Rocket,\n ShieldAlert,\n Trophy,\n UserCheck,\n Users,\n X,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsList,\n TabsTrigger,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n EmptyView,\n ErrorView,\n LoadingRows,\n PageLayout,\n StatusBadge,\n TagInput,\n coverGradient,\n topicIcon,\n} from '../components';\nimport { cn } from '../utils/cn';\nimport { useTechnoSpam } from '../providers/TechnoSpamProvider';\nimport {\n useApproveMentor,\n useArchiveCourse,\n useCompleteHackathon,\n useCoursesQuery,\n useCreateCourse,\n useCreateHackathon,\n useCreateLesson,\n useCreateProblem,\n useGradeSubmission,\n useHackathonsQuery,\n useLessonsQuery,\n useMentorsQuery,\n useOpenRegistration,\n useProblemsQuery,\n usePublishCourse,\n usePublishProblem,\n useScoreTeam,\n useStartHackathon,\n useStartJudging,\n useSubmissionsQuery,\n useTeamsQuery,\n type TecCourseLevel,\n type TecHackathon,\n type TecLessonKind,\n type TecProblemDifficulty,\n type TecSubmissionVerdict,\n} from '../api/technospamApi';\nimport { formatDateTime, formatDuration, formatMoney, humanizeEnum } from '../utils/format';\nimport { notify } from '../lib/toast';\nimport { nativeConfirm } from '@burdenoff/fe-libs/shared/native';\n\nconst LESSON_KINDS: TecLessonKind[] = ['ARTICLE', 'VIDEO', 'INTERACTIVE', 'QUIZ', 'PROJECT'];\nconst VERDICTS: TecSubmissionVerdict[] = [\n 'ACCEPTED',\n 'WRONG_ANSWER',\n 'TIME_LIMIT_EXCEEDED',\n 'RUNTIME_ERROR',\n 'COMPILE_ERROR',\n];\n\n/* --------------------------------------------------------------- helpers */\n\nconst LEVELS: TecCourseLevel[] = ['BEGINNER', 'INTERMEDIATE', 'ADVANCED', 'EXPERT'];\nconst DIFFICULTIES: TecProblemDifficulty[] = ['EASY', 'MEDIUM', 'HARD'];\n\n/** lowercase-hyphenated, safe for URL slugs. */\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction parseCsv(value: string): string[] {\n return value\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\nfunction parseIntOrUndef(value: string): number | undefined {\n const n = Number.parseInt(value, 10);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction toIsoOrNull(local: string): string | null {\n if (!local) return null;\n const d = new Date(local);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n}\n\n/* ----------------------------------------------------------- form atoms */\n\nfunction Field({\n label,\n required,\n className,\n children,\n}: {\n label: string;\n required?: boolean;\n className?: string;\n children: ReactNode;\n}) {\n return (\n <div className={`flex flex-col gap-1.5 ${className ?? ''}`}>\n <span className=\"text-xs font-medium text-text-secondary\">\n {label}\n {required ? <span className=\"text-status-error-text\"> *</span> : null}\n </span>\n {children}\n </div>\n );\n}\n\n/** A small gradient tile carrying a topic icon — echoes the media covers used on\n * learner-facing cards so admin rows read as vivid, not flat. */\nfunction IconTile({ seed, icon: Icon }: { seed: string; icon: LucideIcon }) {\n return (\n <span\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br text-white shadow-sm',\n coverGradient(seed)\n )}\n >\n <Icon size={18} strokeWidth={2} />\n </span>\n );\n}\n\nfunction FormCard({\n title,\n description,\n icon: Icon,\n children,\n footer,\n}: {\n title: string;\n description?: string;\n icon: LucideIcon;\n children: ReactNode;\n footer: ReactNode;\n}) {\n return (\n <GlassCard className=\"space-y-4 p-4 sm:p-5\">\n <div className=\"flex items-center gap-3 border-b border-border-seam pb-3\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-accent-primary/15 text-accent-primary ring-1 ring-accent-primary/20\">\n <Icon size={17} />\n </span>\n <div className=\"min-w-0\">\n <h3 className=\"text-sm font-semibold text-text-primary\">{title}</h3>\n {description ? <p className=\"text-xs text-text-muted\">{description}</p> : null}\n </div>\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">{children}</div>\n <div className=\"flex justify-end gap-2 border-t border-border-seam pt-3\">{footer}</div>\n </GlassCard>\n );\n}\n\nfunction TabHeader({\n summary,\n actionLabel,\n open,\n onToggle,\n}: {\n summary: string;\n actionLabel?: string;\n open?: boolean;\n onToggle?: () => void;\n}) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"text-sm text-text-secondary\">{summary}</p>\n {actionLabel && onToggle ? (\n <Button size=\"sm\" variant={open ? 'outline' : 'default'} onClick={onToggle}>\n {open ? <X size={15} /> : <Plus size={15} />}\n {open ? 'Close' : actionLabel}\n </Button>\n ) : null}\n </div>\n );\n}\n\nfunction RowShell({\n leading,\n children,\n actions,\n}: {\n leading?: ReactNode;\n children: ReactNode;\n actions?: ReactNode;\n}) {\n return (\n <GlassCard className=\"flex flex-col gap-3 p-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex min-w-0 items-center gap-3\">\n {leading}\n <div className=\"min-w-0\">{children}</div>\n </div>\n {actions ? <div className=\"flex shrink-0 flex-wrap items-center gap-2\">{actions}</div> : null}\n </GlassCard>\n );\n}\n\n/* -------------------------------------------- lesson authoring (per course) */\n\nfunction LessonManager({ courseId }: { courseId: string }) {\n const { data, loading, refetch } = useLessonsQuery(courseId);\n const [createLesson, { loading: creating }] = useCreateLesson();\n const [title, setTitle] = useState('');\n const [kind, setKind] = useState<TecLessonKind>('ARTICLE');\n const [content, setContent] = useState('');\n const [minutes, setMinutes] = useState('');\n const [preview, setPreview] = useState(false);\n\n const lessons = [...(data?.tecListLessons ?? [])].sort((a, b) => a.position - b.position);\n\n const addLesson = async () => {\n const t = title.trim();\n if (!t) return notify.error('Lesson title is required');\n const res = await createLesson({\n variables: {\n input: {\n courseId,\n title: t,\n kind,\n content: content.trim() || undefined,\n position: lessons.length + 1,\n estimatedMinutes: parseIntOrUndef(minutes),\n isPreview: preview,\n },\n },\n });\n if (res.data?.tecCreateLesson) {\n notify.success('Lesson added', t);\n setTitle('');\n setContent('');\n setMinutes('');\n setPreview(false);\n await refetch();\n }\n };\n\n return (\n <div className=\"mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-accent-primary/15 text-accent-primary ring-1 ring-accent-primary/20\">\n <ListChecks size={15} />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Curriculum ({lessons.length})\n </span>\n </div>\n {loading && lessons.length === 0 ? (\n <LoadingRows count={2} height=\"h-10\" />\n ) : lessons.length === 0 ? (\n <p className=\"mb-3 text-xs text-text-muted\">No lessons yet — add the first below.</p>\n ) : (\n <ol className=\"mb-3 space-y-1.5\">\n {lessons.map((l, i) => (\n <li\n key={l.id}\n className=\"flex items-center gap-2 rounded-lg bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-accent-primary/10 text-[11px] font-semibold text-accent-primary\">\n {i + 1}\n </span>\n <span className=\"truncate\">{l.title}</span>\n <Badge variant=\"secondary\" className=\"text-[11px]\">\n {humanizeEnum(l.kind)}\n </Badge>\n {l.isPreview ? (\n <Badge variant=\"outline\" className=\"text-[11px]\">\n Preview\n </Badge>\n ) : null}\n <span className=\"ml-auto text-xs text-text-muted\">\n {formatDuration(l.estimatedMinutes)}\n </span>\n </li>\n ))}\n </ol>\n )}\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <Input\n placeholder=\"Lesson title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n />\n <Select value={kind} onValueChange={(v) => setKind(v as TecLessonKind)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {LESSON_KINDS.map((k) => (\n <SelectItem key={k} value={k}>\n {humanizeEnum(k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <Textarea\n className=\"mt-2\"\n placeholder=\"Lesson content (markdown / notes)\"\n value={content}\n onChange={(e) => setContent(e.target.value)}\n />\n <div className=\"mt-2 flex flex-wrap items-center gap-3\">\n <Input\n type=\"number\"\n className=\"w-28\"\n placeholder=\"Minutes\"\n value={minutes}\n onChange={(e) => setMinutes(e.target.value)}\n />\n <label className=\"flex items-center gap-2 text-xs text-text-secondary\">\n <input type=\"checkbox\" checked={preview} onChange={(e) => setPreview(e.target.checked)} />\n Free preview\n </label>\n <Button size=\"sm\" onClick={addLesson} disabled={creating} className=\"ml-auto\">\n <Plus size={14} /> Add lesson\n </Button>\n </div>\n </div>\n );\n}\n\n/* --------------------------------------- submission grading (per problem) */\n\nfunction SubmissionGrader({ problemId }: { problemId: string }) {\n const { data, loading, refetch } = useSubmissionsQuery({ problemId });\n const [gradeSubmission] = useGradeSubmission();\n const [gradingId, setGradingId] = useState<string | null>(null);\n\n const submissions = data?.tecListSubmissions.items ?? [];\n const grade = async (id: string, verdict: TecSubmissionVerdict) => {\n setGradingId(id);\n try {\n const res = await gradeSubmission({ variables: { id, verdict } });\n if (res.data?.tecGradeSubmission) {\n notify.success('Submission graded', humanizeEnum(verdict));\n await refetch();\n }\n } finally {\n setGradingId(null);\n }\n };\n\n return (\n <div className=\"mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-accent-purple/15 text-accent-purple ring-1 ring-accent-purple/20\">\n <Gavel size={15} />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Submissions ({submissions.length})\n </span>\n </div>\n {loading && submissions.length === 0 ? (\n <LoadingRows count={2} height=\"h-10\" />\n ) : submissions.length === 0 ? (\n <p className=\"text-xs text-text-muted\">No submissions yet.</p>\n ) : (\n <div className=\"space-y-2\">\n {submissions.map((s) => (\n <div\n key={s.id}\n className=\"flex flex-wrap items-center gap-2 rounded-lg bg-bg-surface px-3 py-2 text-sm\"\n >\n <StatusBadge status={s.verdict} />\n <span className=\"text-xs text-text-muted\">{s.language}</span>\n <span className=\"text-xs text-text-muted\">{formatDateTime(s.createdAt)}</span>\n {s.verdict === 'PENDING' ? (\n <div className=\"ml-auto flex flex-wrap gap-1\">\n {VERDICTS.map((v) => (\n <Button\n key={v}\n size=\"sm\"\n variant={v === 'ACCEPTED' ? 'default' : 'outline'}\n onClick={() => grade(s.id, v)}\n disabled={gradingId === s.id}\n >\n {v === 'ACCEPTED' ? 'Accept' : humanizeEnum(v)}\n </Button>\n ))}\n </div>\n ) : (\n <span className=\"ml-auto text-xs text-text-muted\">{s.pointsAwarded} pts</span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* -------------------------------- hackathon lifecycle + judging (per event) */\n\nfunction HackathonManager({ hackathon }: { hackathon: TecHackathon }) {\n const { data, loading, refetch } = useTeamsQuery(hackathon.id);\n const [scoreTeam] = useScoreTeam();\n const [scoringId, setScoringId] = useState<string | null>(null);\n const [scores, setScores] = useState<Record<string, string>>({});\n\n const teams = data?.tecListTeams ?? [];\n const submitScore = async (teamId: string, winner: boolean) => {\n const score = Math.max(0, Number(scores[teamId] ?? '0') || 0);\n setScoringId(teamId);\n try {\n const res = await scoreTeam({ variables: { id: teamId, score, winner } });\n if (res.data?.tecScoreTeam) {\n notify.success('Team scored', `${score} pts${winner ? ' · winner' : ''}`);\n await refetch();\n }\n } finally {\n setScoringId(null);\n }\n };\n\n return (\n <div className=\"mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-accent-teal/15 text-accent-teal ring-1 ring-accent-teal/20\">\n <Users size={15} />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Teams ({teams.length})\n </span>\n </div>\n {loading && teams.length === 0 ? (\n <LoadingRows count={2} height=\"h-10\" />\n ) : teams.length === 0 ? (\n <p className=\"text-xs text-text-muted\">No teams registered yet.</p>\n ) : (\n <div className=\"space-y-2\">\n {teams.map((t) => (\n <div\n key={t.id}\n className=\"flex flex-wrap items-center gap-2 rounded-lg bg-bg-surface px-3 py-2 text-sm\"\n >\n <span className=\"truncate font-medium text-text-primary\">{t.name}</span>\n <StatusBadge status={t.status} />\n {t.projectName ? (\n <span className=\"text-xs text-text-muted\">{t.projectName}</span>\n ) : null}\n {hackathon.status === 'JUDGING' ? (\n <div className=\"ml-auto flex items-center gap-1\">\n <Input\n type=\"number\"\n className=\"w-20\"\n placeholder=\"Score\"\n value={scores[t.id] ?? ''}\n onChange={(e) => setScores((s) => ({ ...s, [t.id]: e.target.value }))}\n />\n <Button\n size=\"sm\"\n onClick={() => submitScore(t.id, false)}\n disabled={scoringId === t.id}\n >\n Score\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => submitScore(t.id, true)}\n disabled={scoringId === t.id}\n >\n <Trophy size={14} /> Winner\n </Button>\n </div>\n ) : (\n <span className=\"ml-auto text-xs text-text-muted\">{t.score} pts</span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* --------------------------------------------------------------- Courses */\n\nfunction CoursesTab() {\n const { data, loading, error, refetch } = useCoursesQuery({});\n const [createCourse, { loading: creating }] = useCreateCourse();\n const [publishCourse] = usePublishCourse();\n const [archiveCourse] = useArchiveCourse();\n\n const [showForm, setShowForm] = useState(false);\n const [actingId, setActingId] = useState<string | null>(null);\n const [lessonsFor, setLessonsFor] = useState<string | null>(null);\n\n const [title, setTitle] = useState('');\n const [slug, setSlug] = useState('');\n const [summary, setSummary] = useState('');\n const [topic, setTopic] = useState('');\n const [level, setLevel] = useState<TecCourseLevel>('BEGINNER');\n const [minutes, setMinutes] = useState('');\n const [tags, setTags] = useState<string[]>([]);\n\n const courses = data?.tecListCourses.items ?? [];\n\n const resetForm = () => {\n setTitle('');\n setSlug('');\n setSummary('');\n setTopic('');\n setLevel('BEGINNER');\n setMinutes('');\n setTags([]);\n setShowForm(false);\n };\n\n const handleCreate = async () => {\n const t = title.trim();\n if (!t) return notify.error('Title is required');\n const finalSlug = slugify(slug || t);\n if (!finalSlug) return notify.error('A valid slug is required');\n const res = await createCourse({\n variables: {\n input: {\n title: t,\n slug: finalSlug,\n summary: summary.trim() || undefined,\n topic: topic.trim() || undefined,\n level,\n estimatedMinutes: parseIntOrUndef(minutes),\n tags,\n },\n },\n });\n if (res.data?.tecCreateCourse) {\n notify.success('Course created', `\"${t}\" saved as a draft.`);\n resetForm();\n await refetch();\n }\n };\n\n const handlePublish = async (id: string) => {\n setActingId(id);\n try {\n const res = await publishCourse({ variables: { id } });\n if (res.data?.tecPublishCourse) {\n notify.success('Course published');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n const handleArchive = async (id: string, title: string) => {\n const confirmed = await nativeConfirm({\n title: 'Archive course',\n message: `Archive \"${title}\"? Learners will no longer be able to enroll.`,\n okButtonTitle: 'Archive',\n cancelButtonTitle: 'Cancel',\n });\n if (!confirmed) return;\n setActingId(id);\n try {\n const res = await archiveCourse({ variables: { id } });\n if (res.data?.tecArchiveCourse) {\n notify.success('Course archived');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${courses.length} course${courses.length === 1 ? '' : 's'}`}\n actionLabel=\"New course\"\n open={showForm}\n onToggle={() => setShowForm((v) => !v)}\n />\n\n {showForm ? (\n <FormCard\n title=\"New course\"\n description=\"Draft a course, then add lessons and publish when it's ready.\"\n icon={BookOpen}\n footer={\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={resetForm}>\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleCreate} disabled={creating}>\n {creating ? 'Creating…' : 'Create course'}\n </Button>\n </>\n }\n >\n <Field label=\"Title\" required>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Intro to TypeScript\"\n />\n </Field>\n <Field label=\"Slug\" required>\n <Input\n value={slug}\n onChange={(e) => setSlug(e.target.value)}\n placeholder=\"auto from title if blank\"\n />\n </Field>\n <Field label=\"Topic\">\n <Input\n value={topic}\n onChange={(e) => setTopic(e.target.value)}\n placeholder=\"e.g. Web, AI, Data, Cloud\"\n />\n </Field>\n <Field label=\"Level\">\n <Select value={level} onValueChange={(v) => setLevel(v as TecCourseLevel)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {LEVELS.map((l) => (\n <SelectItem key={l} value={l}>\n {humanizeEnum(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Estimated minutes\">\n <Input\n type=\"number\"\n min={0}\n value={minutes}\n onChange={(e) => setMinutes(e.target.value)}\n placeholder=\"120\"\n />\n </Field>\n <Field label=\"Tags\">\n <TagInput value={tags} onChange={setTags} placeholder=\"typescript, basics\" />\n </Field>\n <Field label=\"Summary\" className=\"sm:col-span-2\">\n <Textarea\n value={summary}\n onChange={(e) => setSummary(e.target.value)}\n placeholder=\"What learners will build and take away.\"\n />\n </Field>\n </FormCard>\n ) : null}\n\n {loading && !courses.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load courses\" error={error} />\n ) : courses.length === 0 ? (\n <EmptyView\n icon={<BookOpen size={26} />}\n title=\"No courses yet\"\n description=\"Create your first course with the button above. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {courses.map((c) => (\n <div key={c.id}>\n <RowShell\n leading={\n <IconTile\n seed={`${c.topic ?? ''} ${c.title}`}\n icon={topicIcon(c.topic ?? c.title)}\n />\n }\n actions={\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setLessonsFor(lessonsFor === c.id ? null : c.id)}\n >\n <ListChecks size={15} /> Lessons\n </Button>\n {c.status === 'DRAFT' ? (\n <Button\n size=\"sm\"\n onClick={() => handlePublish(c.id)}\n disabled={actingId === c.id}\n >\n <Rocket size={15} /> Publish\n </Button>\n ) : null}\n {c.status !== 'ARCHIVED' ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleArchive(c.id, c.title)}\n disabled={actingId === c.id}\n >\n <Archive size={15} /> Archive\n </Button>\n ) : null}\n </>\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {c.title}\n </span>\n <StatusBadge status={c.status} />\n <StatusBadge status={c.level} kind=\"level\" />\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {c.slug} · {c.topic ?? 'No topic'} · {formatDuration(c.estimatedMinutes)}\n </div>\n </RowShell>\n {lessonsFor === c.id ? <LessonManager courseId={c.id} /> : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* -------------------------------------------------------------- Problems */\n\nfunction ProblemsTab() {\n const { data, loading, error, refetch } = useProblemsQuery({});\n const [createProblem, { loading: creating }] = useCreateProblem();\n const [publishProblem] = usePublishProblem();\n\n const [showForm, setShowForm] = useState(false);\n const [actingId, setActingId] = useState<string | null>(null);\n const [gradeFor, setGradeFor] = useState<string | null>(null);\n\n const [title, setTitle] = useState('');\n const [slug, setSlug] = useState('');\n const [statement, setStatement] = useState('');\n const [topic, setTopic] = useState('');\n const [difficulty, setDifficulty] = useState<TecProblemDifficulty>('EASY');\n const [points, setPoints] = useState('');\n const [languages, setLanguages] = useState('');\n const [starterCode, setStarterCode] = useState('');\n\n const problems = data?.tecListProblems.items ?? [];\n\n const resetForm = () => {\n setTitle('');\n setSlug('');\n setStatement('');\n setTopic('');\n setDifficulty('EASY');\n setPoints('');\n setLanguages('');\n setStarterCode('');\n setShowForm(false);\n };\n\n const handleCreate = async () => {\n const t = title.trim();\n if (!t) return notify.error('Title is required');\n const finalSlug = slugify(slug || t);\n if (!finalSlug) return notify.error('A valid slug is required');\n const res = await createProblem({\n variables: {\n input: {\n title: t,\n slug: finalSlug,\n statement: statement.trim() || undefined,\n topic: topic.trim() || undefined,\n difficulty,\n points: parseIntOrUndef(points),\n languages: parseCsv(languages),\n starterCode: starterCode.trim() || undefined,\n },\n },\n });\n if (res.data?.tecCreateProblem) {\n notify.success('Problem created', `\"${t}\" saved as a draft.`);\n resetForm();\n await refetch();\n }\n };\n\n const handlePublish = async (id: string) => {\n setActingId(id);\n try {\n const res = await publishProblem({ variables: { id } });\n if (res.data?.tecPublishProblem) {\n notify.success('Problem published');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${problems.length} problem${problems.length === 1 ? '' : 's'}`}\n actionLabel=\"New problem\"\n open={showForm}\n onToggle={() => setShowForm((v) => !v)}\n />\n\n {showForm ? (\n <FormCard\n title=\"New problem\"\n description=\"Define a coding challenge learners can solve and submit.\"\n icon={Code2}\n footer={\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={resetForm}>\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleCreate} disabled={creating}>\n {creating ? 'Creating…' : 'Create problem'}\n </Button>\n </>\n }\n >\n <Field label=\"Title\" required>\n <Input value={title} onChange={(e) => setTitle(e.target.value)} placeholder=\"Two Sum\" />\n </Field>\n <Field label=\"Slug\" required>\n <Input\n value={slug}\n onChange={(e) => setSlug(e.target.value)}\n placeholder=\"auto from title if blank\"\n />\n </Field>\n <Field label=\"Topic\">\n <Input value={topic} onChange={(e) => setTopic(e.target.value)} placeholder=\"Arrays\" />\n </Field>\n <Field label=\"Difficulty\">\n <Select\n value={difficulty}\n onValueChange={(v) => setDifficulty(v as TecProblemDifficulty)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DIFFICULTIES.map((d) => (\n <SelectItem key={d} value={d}>\n {humanizeEnum(d)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Points\">\n <Input\n type=\"number\"\n min={0}\n value={points}\n onChange={(e) => setPoints(e.target.value)}\n placeholder=\"100\"\n />\n </Field>\n <Field label=\"Languages (comma-separated)\">\n <Input\n value={languages}\n onChange={(e) => setLanguages(e.target.value)}\n placeholder=\"python, typescript\"\n />\n </Field>\n <Field label=\"Statement\" className=\"sm:col-span-2\">\n <Textarea\n value={statement}\n onChange={(e) => setStatement(e.target.value)}\n placeholder=\"Describe the problem and constraints.\"\n />\n </Field>\n <Field label=\"Starter code\" className=\"sm:col-span-2\">\n <Textarea\n value={starterCode}\n onChange={(e) => setStarterCode(e.target.value)}\n className=\"font-mono\"\n placeholder=\"def solve(nums, target):\\n pass\"\n />\n </Field>\n </FormCard>\n ) : null}\n\n {loading && !problems.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load problems\" error={error} />\n ) : problems.length === 0 ? (\n <EmptyView\n icon={<Code2 size={26} />}\n title=\"No problems yet\"\n description=\"Create your first coding problem with the button above. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {problems.map((p) => (\n <div key={p.id}>\n <RowShell\n leading={\n <IconTile\n seed={`${p.topic ?? ''} ${p.title}`}\n icon={topicIcon(p.topic ?? p.title)}\n />\n }\n actions={\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setGradeFor(gradeFor === p.id ? null : p.id)}\n >\n <Gavel size={15} /> Grade\n </Button>\n {p.status === 'DRAFT' ? (\n <Button\n size=\"sm\"\n onClick={() => handlePublish(p.id)}\n disabled={actingId === p.id}\n >\n <Rocket size={15} /> Publish\n </Button>\n ) : null}\n </>\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {p.title}\n </span>\n <StatusBadge status={p.status} />\n <StatusBadge status={p.difficulty} kind=\"level\" />\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {p.slug} · {p.topic ?? 'No topic'} · {p.points} pts ·{' '}\n {p.languages.length ? p.languages.join(', ') : 'No languages'}\n </div>\n </RowShell>\n {gradeFor === p.id ? <SubmissionGrader problemId={p.id} /> : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------ Hackathons */\n\nfunction HackathonsTab() {\n const { data, loading, error, refetch } = useHackathonsQuery({});\n const [createHackathon, { loading: creating }] = useCreateHackathon();\n const [openRegistration] = useOpenRegistration();\n const [startHackathon] = useStartHackathon();\n const [startJudging] = useStartJudging();\n const [completeHackathon] = useCompleteHackathon();\n\n const [showForm, setShowForm] = useState(false);\n const [actingId, setActingId] = useState<string | null>(null);\n const [judgeFor, setJudgeFor] = useState<string | null>(null);\n\n const [title, setTitle] = useState('');\n const [slug, setSlug] = useState('');\n const [theme, setTheme] = useState('');\n const [description, setDescription] = useState('');\n const [startAt, setStartAt] = useState('');\n const [endAt, setEndAt] = useState('');\n const [prizePool, setPrizePool] = useState('');\n const [maxTeamSize, setMaxTeamSize] = useState('');\n const [tags, setTags] = useState<string[]>([]);\n\n const hackathons = data?.tecListHackathons.items ?? [];\n\n const resetForm = () => {\n setTitle('');\n setSlug('');\n setTheme('');\n setDescription('');\n setStartAt('');\n setEndAt('');\n setPrizePool('');\n setMaxTeamSize('');\n setTags([]);\n setShowForm(false);\n };\n\n const handleCreate = async () => {\n const t = title.trim();\n if (!t) return notify.error('Title is required');\n const finalSlug = slugify(slug || t);\n if (!finalSlug) return notify.error('A valid slug is required');\n const startIso = toIsoOrNull(startAt);\n const endIso = toIsoOrNull(endAt);\n if (!startIso || !endIso) return notify.error('Start and end date/time are required');\n if (new Date(endIso) <= new Date(startIso)) return notify.error('End must be after the start');\n const res = await createHackathon({\n variables: {\n input: {\n title: t,\n slug: finalSlug,\n theme: theme.trim() || undefined,\n description: description.trim() || undefined,\n startAt: startIso,\n endAt: endIso,\n prizePool: parseIntOrUndef(prizePool),\n maxTeamSize: parseIntOrUndef(maxTeamSize),\n tags,\n },\n },\n });\n if (res.data?.tecCreateHackathon) {\n notify.success('Hackathon created', `\"${t}\" saved as a draft.`);\n resetForm();\n await refetch();\n }\n };\n\n const handleOpen = async (id: string) => {\n setActingId(id);\n try {\n const res = await openRegistration({ variables: { id } });\n if (res.data?.tecOpenRegistration) {\n notify.success('Registration open', 'Teams can now register.');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n const advance = async (\n id: string,\n run: (v: { variables: { id: string } }) => Promise<{ data?: unknown }>,\n message: string\n ) => {\n setActingId(id);\n try {\n const res = await run({ variables: { id } });\n if (res.data) {\n notify.success(message);\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${hackathons.length} hackathon${hackathons.length === 1 ? '' : 's'}`}\n actionLabel=\"New hackathon\"\n open={showForm}\n onToggle={() => setShowForm((v) => !v)}\n />\n\n {showForm ? (\n <FormCard\n title=\"New hackathon\"\n description=\"Set up an event, open registration, then run judging to completion.\"\n icon={Trophy}\n footer={\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={resetForm}>\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleCreate} disabled={creating}>\n {creating ? 'Creating…' : 'Create hackathon'}\n </Button>\n </>\n }\n >\n <Field label=\"Title\" required>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Build Days 2026\"\n />\n </Field>\n <Field label=\"Slug\" required>\n <Input\n value={slug}\n onChange={(e) => setSlug(e.target.value)}\n placeholder=\"auto from title if blank\"\n />\n </Field>\n <Field label=\"Theme\">\n <Input\n value={theme}\n onChange={(e) => setTheme(e.target.value)}\n placeholder=\"AI for good\"\n />\n </Field>\n <Field label=\"Tags\">\n <TagInput value={tags} onChange={setTags} placeholder=\"ai, web\" />\n </Field>\n <Field label=\"Starts\" required>\n <Input\n type=\"datetime-local\"\n value={startAt}\n onChange={(e) => setStartAt(e.target.value)}\n />\n </Field>\n <Field label=\"Ends\" required>\n <Input type=\"datetime-local\" value={endAt} onChange={(e) => setEndAt(e.target.value)} />\n </Field>\n <Field label=\"Prize pool\">\n <Input\n type=\"number\"\n min={0}\n value={prizePool}\n onChange={(e) => setPrizePool(e.target.value)}\n placeholder=\"5000\"\n />\n </Field>\n <Field label=\"Max team size\">\n <Input\n type=\"number\"\n min={1}\n value={maxTeamSize}\n onChange={(e) => setMaxTeamSize(e.target.value)}\n placeholder=\"4\"\n />\n </Field>\n <Field label=\"Description\" className=\"sm:col-span-2\">\n <Textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"What the hackathon is about and how judging works.\"\n />\n </Field>\n </FormCard>\n ) : null}\n\n {loading && !hackathons.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load hackathons\" error={error} />\n ) : hackathons.length === 0 ? (\n <EmptyView\n icon={<Trophy size={26} />}\n title=\"No hackathons yet\"\n description=\"Create your first hackathon with the button above. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {hackathons.map((h) => (\n <div key={h.id}>\n <RowShell\n leading={<IconTile seed={h.title} icon={topicIcon(h.title, Trophy)} />}\n actions={\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setJudgeFor(judgeFor === h.id ? null : h.id)}\n >\n <Users size={15} /> Teams\n </Button>\n {h.status === 'DRAFT' ? (\n <Button\n size=\"sm\"\n onClick={() => handleOpen(h.id)}\n disabled={actingId === h.id}\n >\n <Rocket size={15} /> Open registration\n </Button>\n ) : null}\n {h.status === 'REGISTRATION_OPEN' ? (\n <Button\n size=\"sm\"\n onClick={() => advance(h.id, startHackathon, 'Hackathon started')}\n disabled={actingId === h.id}\n >\n <Play size={15} /> Start\n </Button>\n ) : null}\n {h.status === 'IN_PROGRESS' ? (\n <Button\n size=\"sm\"\n onClick={() => advance(h.id, startJudging, 'Judging started')}\n disabled={actingId === h.id}\n >\n <Gavel size={15} /> Start judging\n </Button>\n ) : null}\n {h.status === 'JUDGING' ? (\n <Button\n size=\"sm\"\n onClick={() => advance(h.id, completeHackathon, 'Hackathon completed')}\n disabled={actingId === h.id}\n >\n <Award size={15} /> Complete\n </Button>\n ) : null}\n </>\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {h.title}\n </span>\n <StatusBadge status={h.status} />\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {h.slug} · {formatDateTime(h.startAt)} → {formatDateTime(h.endAt)}\n {h.prizePool ? ` · ${formatMoney(h.prizePool, h.currency)} prize` : ''}\n </div>\n </RowShell>\n {judgeFor === h.id ? <HackathonManager hackathon={h} /> : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* --------------------------------------------------------------- Mentors */\n\nfunction MentorsTab() {\n const { data, loading, error, refetch } = useMentorsQuery({});\n const [approveMentor] = useApproveMentor();\n const [actingId, setActingId] = useState<string | null>(null);\n\n const mentors = data?.tecListMentors.items ?? [];\n const pending = mentors.filter((m) => m.status === 'PENDING').length;\n\n const handleApprove = async (id: string) => {\n setActingId(id);\n try {\n const res = await approveMentor({ variables: { id } });\n if (res.data?.tecApproveMentor) {\n notify.success('Mentor approved', 'They can now accept mentees.');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${mentors.length} mentor${mentors.length === 1 ? '' : 's'}${\n pending ? ` · ${pending} pending approval` : ''\n }`}\n />\n\n {loading && !mentors.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load mentors\" error={error} />\n ) : mentors.length === 0 ? (\n <EmptyView\n icon={<Users size={26} />}\n title=\"No mentors yet\"\n description=\"Mentor applications will appear here for review. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {mentors.map((m) => (\n <RowShell\n key={m.id}\n leading={\n <IconTile seed={m.headline} icon={topicIcon(m.expertise[0] ?? m.headline, Users)} />\n }\n actions={\n m.status === 'PENDING' ? (\n <Button\n size=\"sm\"\n onClick={() => handleApprove(m.id)}\n disabled={actingId === m.id}\n >\n <UserCheck size={15} /> Approve\n </Button>\n ) : undefined\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {m.headline}\n </span>\n <StatusBadge status={m.status} />\n {m.isAcceptingMentees ? (\n <Badge variant=\"secondary\" className=\"text-[11px]\">\n Accepting mentees\n </Badge>\n ) : null}\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {m.expertise.length ? m.expertise.slice(0, 4).join(', ') : 'No expertise listed'} ·{' '}\n {formatMoney(m.hourlyRate, m.currency)}/hr · {m.sessionsCount} sessions\n </div>\n </RowShell>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------ page shell */\n\ntype AdminTab = 'courses' | 'problems' | 'hackathons' | 'mentors';\n\nexport function AdminAdminDashboardPagePage() {\n const [tab, setTab] = useState<AdminTab>('courses');\n const { currentUser } = useTechnoSpam();\n const role = (currentUser?.role ?? '').toLowerCase();\n const privileged =\n role.includes('admin') || role.includes('owner') || role.includes('instructor');\n\n return (\n <PageLayout\n hero\n title=\"Authoring Console\"\n description=\"Create and manage TechnoSpam content — courses, problems, hackathons, and mentor applications.\"\n >\n {!privileged ? (\n <GlassCard className=\"mb-5 flex items-start gap-3 border-status-warning-border p-4\">\n <ShieldAlert size={18} className=\"mt-0.5 shrink-0 text-status-warning-text\" />\n <div className=\"text-sm text-text-secondary\">\n <span className=\"font-medium text-text-primary\">\n Authoring is limited to workspace admins.\n </span>{' '}\n You can review content here, but create/publish actions require the right permission and\n will be rejected at the gateway otherwise.\n </div>\n </GlassCard>\n ) : null}\n <Tabs value={tab} onValueChange={(v) => setTab(v as AdminTab)}>\n <TabsList className=\"mb-5\">\n <TabsTrigger value=\"courses\">\n <BookOpen size={15} /> Courses\n </TabsTrigger>\n <TabsTrigger value=\"problems\">\n <Code2 size={15} /> Problems\n </TabsTrigger>\n <TabsTrigger value=\"hackathons\">\n <Trophy size={15} /> Hackathons\n </TabsTrigger>\n <TabsTrigger value=\"mentors\">\n <Users size={15} /> Mentors\n </TabsTrigger>\n </TabsList>\n </Tabs>\n\n {tab === 'courses' ? (\n <CoursesTab />\n ) : tab === 'problems' ? (\n <ProblemsTab />\n ) : tab === 'hackathons' ? (\n <HackathonsTab />\n ) : (\n <MentorsTab />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminAdminDashboardPagePage.js","names":[],"sources":["../../../src/technospam/pages/AdminAdminDashboardPagePage.tsx"],"sourcesContent":["import { useState, type ReactNode } from 'react';\nimport {\n Archive,\n Award,\n BookOpen,\n Code2,\n Gavel,\n ListChecks,\n Play,\n Plus,\n Rocket,\n ShieldAlert,\n Trophy,\n UserCheck,\n Users,\n X,\n type LucideIcon,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsList,\n TabsTrigger,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n EmptyView,\n ErrorView,\n LoadingRows,\n PageLayout,\n StatusBadge,\n TagInput,\n coverGradient,\n topicIcon,\n} from '../components';\nimport { cn } from '../utils/cn';\nimport { useTechnoSpam } from '../providers/TechnoSpamProvider';\nimport {\n useApproveMentor,\n useArchiveCourse,\n useCompleteHackathon,\n useCoursesQuery,\n useCreateCourse,\n useCreateHackathon,\n useCreateLesson,\n useCreateProblem,\n useGradeSubmission,\n useHackathonsQuery,\n useLessonsQuery,\n useMentorsQuery,\n useOpenRegistration,\n useProblemsQuery,\n usePublishCourse,\n usePublishProblem,\n useScoreTeam,\n useStartHackathon,\n useStartJudging,\n useSubmissionsQuery,\n useTeamsQuery,\n type TecCourseLevel,\n type TecHackathon,\n type TecLessonKind,\n type TecProblemDifficulty,\n type TecSubmissionVerdict,\n} from '../api/technospamApi';\nimport { formatDateTime, formatDuration, formatMoney, humanizeEnum } from '../utils/format';\nimport { notify } from '../lib/toast';\nimport { nativeConfirm } from '@burdenoff/fe-libs/shared/native';\n\nconst LESSON_KINDS: TecLessonKind[] = ['ARTICLE', 'VIDEO', 'INTERACTIVE', 'QUIZ', 'PROJECT'];\nconst VERDICTS: TecSubmissionVerdict[] = [\n 'ACCEPTED',\n 'WRONG_ANSWER',\n 'TIME_LIMIT_EXCEEDED',\n 'RUNTIME_ERROR',\n 'COMPILE_ERROR',\n];\n\n/* --------------------------------------------------------------- helpers */\n\nconst LEVELS: TecCourseLevel[] = ['BEGINNER', 'INTERMEDIATE', 'ADVANCED', 'EXPERT'];\nconst DIFFICULTIES: TecProblemDifficulty[] = ['EASY', 'MEDIUM', 'HARD'];\n\n/** lowercase-hyphenated, safe for URL slugs. */\nfunction slugify(value: string): string {\n return value\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction parseCsv(value: string): string[] {\n return value\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\nfunction parseIntOrUndef(value: string): number | undefined {\n const n = Number.parseInt(value, 10);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction toIsoOrNull(local: string): string | null {\n if (!local) return null;\n const d = new Date(local);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n}\n\n/* ----------------------------------------------------------- form atoms */\n\nfunction Field({\n label,\n required,\n className,\n children,\n}: {\n label: string;\n required?: boolean;\n className?: string;\n children: ReactNode;\n}) {\n return (\n <div className={`flex flex-col gap-1.5 ${className ?? ''}`}>\n <span className=\"text-xs font-medium text-text-secondary\">\n {label}\n {required ? <span className=\"text-status-error-text\"> *</span> : null}\n </span>\n {children}\n </div>\n );\n}\n\n/** A small gradient tile carrying a topic icon — echoes the media covers used on\n * learner-facing cards so admin rows read as vivid, not flat. */\nfunction IconTile({ seed, icon: Icon }: { seed: string; icon: LucideIcon }) {\n return (\n <span\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br text-white shadow-sm',\n coverGradient(seed)\n )}\n >\n <Icon size={18} strokeWidth={2} />\n </span>\n );\n}\n\nfunction FormCard({\n title,\n description,\n icon: Icon,\n children,\n footer,\n}: {\n title: string;\n description?: string;\n icon: LucideIcon;\n children: ReactNode;\n footer: ReactNode;\n}) {\n return (\n <GlassCard className=\"space-y-4 p-4 sm:p-5\">\n <div className=\"flex items-center gap-3 border-b border-border-seam pb-3\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-accent-primary/15 text-accent-primary ring-1 ring-accent-primary/20\">\n <Icon size={17} />\n </span>\n <div className=\"min-w-0\">\n <h3 className=\"text-sm font-semibold text-text-primary\">{title}</h3>\n {description ? <p className=\"text-xs text-text-muted\">{description}</p> : null}\n </div>\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">{children}</div>\n <div className=\"flex justify-end gap-2 border-t border-border-seam pt-3\">{footer}</div>\n </GlassCard>\n );\n}\n\nfunction TabHeader({\n summary,\n actionLabel,\n open,\n onToggle,\n}: {\n summary: string;\n actionLabel?: string;\n open?: boolean;\n onToggle?: () => void;\n}) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"text-sm text-text-secondary\">{summary}</p>\n {actionLabel && onToggle ? (\n <Button size=\"sm\" variant={open ? 'outline' : 'default'} onClick={onToggle}>\n {open ? <X size={15} /> : <Plus size={15} />}\n {open ? 'Close' : actionLabel}\n </Button>\n ) : null}\n </div>\n );\n}\n\nfunction RowShell({\n leading,\n children,\n actions,\n}: {\n leading?: ReactNode;\n children: ReactNode;\n actions?: ReactNode;\n}) {\n return (\n <GlassCard className=\"flex flex-col gap-3 p-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex min-w-0 items-center gap-3\">\n {leading}\n <div className=\"min-w-0\">{children}</div>\n </div>\n {actions ? <div className=\"flex shrink-0 flex-wrap items-center gap-2\">{actions}</div> : null}\n </GlassCard>\n );\n}\n\n/* -------------------------------------------- lesson authoring (per course) */\n\nfunction LessonManager({ courseId }: { courseId: string }) {\n const { data, loading, refetch } = useLessonsQuery(courseId);\n const [createLesson, { loading: creating }] = useCreateLesson();\n const [title, setTitle] = useState('');\n const [kind, setKind] = useState<TecLessonKind>('ARTICLE');\n const [content, setContent] = useState('');\n const [minutes, setMinutes] = useState('');\n const [preview, setPreview] = useState(false);\n\n const lessons = [...(data?.tecListLessons.items ?? [])].sort((a, b) => a.position - b.position);\n\n const addLesson = async () => {\n const t = title.trim();\n if (!t) return notify.error('Lesson title is required');\n const res = await createLesson({\n variables: {\n input: {\n courseId,\n title: t,\n kind,\n content: content.trim() || undefined,\n position: lessons.length + 1,\n estimatedMinutes: parseIntOrUndef(minutes),\n isPreview: preview,\n },\n },\n });\n if (res.data?.tecCreateLesson) {\n notify.success('Lesson added', t);\n setTitle('');\n setContent('');\n setMinutes('');\n setPreview(false);\n await refetch();\n }\n };\n\n return (\n <div className=\"mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-accent-primary/15 text-accent-primary ring-1 ring-accent-primary/20\">\n <ListChecks size={15} />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Curriculum ({lessons.length})\n </span>\n </div>\n {loading && lessons.length === 0 ? (\n <LoadingRows count={2} height=\"h-10\" />\n ) : lessons.length === 0 ? (\n <p className=\"mb-3 text-xs text-text-muted\">No lessons yet — add the first below.</p>\n ) : (\n <ol className=\"mb-3 space-y-1.5\">\n {lessons.map((l, i) => (\n <li\n key={l.id}\n className=\"flex items-center gap-2 rounded-lg bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-accent-primary/10 text-[11px] font-semibold text-accent-primary\">\n {i + 1}\n </span>\n <span className=\"truncate\">{l.title}</span>\n <Badge variant=\"secondary\" className=\"text-[11px]\">\n {humanizeEnum(l.kind)}\n </Badge>\n {l.isPreview ? (\n <Badge variant=\"outline\" className=\"text-[11px]\">\n Preview\n </Badge>\n ) : null}\n <span className=\"ml-auto text-xs text-text-muted\">\n {formatDuration(l.estimatedMinutes)}\n </span>\n </li>\n ))}\n </ol>\n )}\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n <Input\n placeholder=\"Lesson title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n />\n <Select value={kind} onValueChange={(v) => setKind(v as TecLessonKind)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {LESSON_KINDS.map((k) => (\n <SelectItem key={k} value={k}>\n {humanizeEnum(k)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <Textarea\n className=\"mt-2\"\n placeholder=\"Lesson content (markdown / notes)\"\n value={content}\n onChange={(e) => setContent(e.target.value)}\n />\n <div className=\"mt-2 flex flex-wrap items-center gap-3\">\n <Input\n type=\"number\"\n className=\"w-28\"\n placeholder=\"Minutes\"\n value={minutes}\n onChange={(e) => setMinutes(e.target.value)}\n />\n <label className=\"flex items-center gap-2 text-xs text-text-secondary\">\n <input type=\"checkbox\" checked={preview} onChange={(e) => setPreview(e.target.checked)} />\n Free preview\n </label>\n <Button size=\"sm\" onClick={addLesson} disabled={creating} className=\"ml-auto\">\n <Plus size={14} /> Add lesson\n </Button>\n </div>\n </div>\n );\n}\n\n/* --------------------------------------- submission grading (per problem) */\n\nfunction SubmissionGrader({ problemId }: { problemId: string }) {\n const { data, loading, refetch } = useSubmissionsQuery({ problemId });\n const [gradeSubmission] = useGradeSubmission();\n const [gradingId, setGradingId] = useState<string | null>(null);\n\n const submissions = data?.tecListSubmissions.items ?? [];\n const grade = async (id: string, verdict: TecSubmissionVerdict) => {\n setGradingId(id);\n try {\n const res = await gradeSubmission({ variables: { id, verdict } });\n if (res.data?.tecGradeSubmission) {\n notify.success('Submission graded', humanizeEnum(verdict));\n await refetch();\n }\n } finally {\n setGradingId(null);\n }\n };\n\n return (\n <div className=\"mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-accent-purple/15 text-accent-purple ring-1 ring-accent-purple/20\">\n <Gavel size={15} />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Submissions ({submissions.length})\n </span>\n </div>\n {loading && submissions.length === 0 ? (\n <LoadingRows count={2} height=\"h-10\" />\n ) : submissions.length === 0 ? (\n <p className=\"text-xs text-text-muted\">No submissions yet.</p>\n ) : (\n <div className=\"space-y-2\">\n {submissions.map((s) => (\n <div\n key={s.id}\n className=\"flex flex-wrap items-center gap-2 rounded-lg bg-bg-surface px-3 py-2 text-sm\"\n >\n <StatusBadge status={s.verdict} />\n <span className=\"text-xs text-text-muted\">{s.language}</span>\n <span className=\"text-xs text-text-muted\">{formatDateTime(s.createdAt)}</span>\n {s.verdict === 'PENDING' ? (\n <div className=\"ml-auto flex flex-wrap gap-1\">\n {VERDICTS.map((v) => (\n <Button\n key={v}\n size=\"sm\"\n variant={v === 'ACCEPTED' ? 'default' : 'outline'}\n onClick={() => grade(s.id, v)}\n disabled={gradingId === s.id}\n >\n {v === 'ACCEPTED' ? 'Accept' : humanizeEnum(v)}\n </Button>\n ))}\n </div>\n ) : (\n <span className=\"ml-auto text-xs text-text-muted\">{s.pointsAwarded} pts</span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* -------------------------------- hackathon lifecycle + judging (per event) */\n\nfunction HackathonManager({ hackathon }: { hackathon: TecHackathon }) {\n const { data, loading, refetch } = useTeamsQuery(hackathon.id);\n const [scoreTeam] = useScoreTeam();\n const [scoringId, setScoringId] = useState<string | null>(null);\n const [scores, setScores] = useState<Record<string, string>>({});\n\n const teams = data?.tecListTeams.items ?? [];\n const submitScore = async (teamId: string, winner: boolean) => {\n const score = Math.max(0, Number(scores[teamId] ?? '0') || 0);\n setScoringId(teamId);\n try {\n const res = await scoreTeam({ variables: { id: teamId, score, winner } });\n if (res.data?.tecScoreTeam) {\n notify.success('Team scored', `${score} pts${winner ? ' · winner' : ''}`);\n await refetch();\n }\n } finally {\n setScoringId(null);\n }\n };\n\n return (\n <div className=\"mt-3 rounded-xl border border-border-seam bg-bg-sunken p-4\">\n <div className=\"mb-3 flex items-center gap-2\">\n <span className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-accent-teal/15 text-accent-teal ring-1 ring-accent-teal/20\">\n <Users size={15} />\n </span>\n <span className=\"text-xs font-semibold uppercase tracking-wide text-text-secondary\">\n Teams ({teams.length})\n </span>\n </div>\n {loading && teams.length === 0 ? (\n <LoadingRows count={2} height=\"h-10\" />\n ) : teams.length === 0 ? (\n <p className=\"text-xs text-text-muted\">No teams registered yet.</p>\n ) : (\n <div className=\"space-y-2\">\n {teams.map((t) => (\n <div\n key={t.id}\n className=\"flex flex-wrap items-center gap-2 rounded-lg bg-bg-surface px-3 py-2 text-sm\"\n >\n <span className=\"truncate font-medium text-text-primary\">{t.name}</span>\n <StatusBadge status={t.status} />\n {t.projectName ? (\n <span className=\"text-xs text-text-muted\">{t.projectName}</span>\n ) : null}\n {hackathon.status === 'JUDGING' ? (\n <div className=\"ml-auto flex items-center gap-1\">\n <Input\n type=\"number\"\n className=\"w-20\"\n placeholder=\"Score\"\n value={scores[t.id] ?? ''}\n onChange={(e) => setScores((s) => ({ ...s, [t.id]: e.target.value }))}\n />\n <Button\n size=\"sm\"\n onClick={() => submitScore(t.id, false)}\n disabled={scoringId === t.id}\n >\n Score\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => submitScore(t.id, true)}\n disabled={scoringId === t.id}\n >\n <Trophy size={14} /> Winner\n </Button>\n </div>\n ) : (\n <span className=\"ml-auto text-xs text-text-muted\">{t.score} pts</span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* --------------------------------------------------------------- Courses */\n\nfunction CoursesTab() {\n const { data, loading, error, refetch } = useCoursesQuery({});\n const [createCourse, { loading: creating }] = useCreateCourse();\n const [publishCourse] = usePublishCourse();\n const [archiveCourse] = useArchiveCourse();\n\n const [showForm, setShowForm] = useState(false);\n const [actingId, setActingId] = useState<string | null>(null);\n const [lessonsFor, setLessonsFor] = useState<string | null>(null);\n\n const [title, setTitle] = useState('');\n const [slug, setSlug] = useState('');\n const [summary, setSummary] = useState('');\n const [topic, setTopic] = useState('');\n const [level, setLevel] = useState<TecCourseLevel>('BEGINNER');\n const [minutes, setMinutes] = useState('');\n const [tags, setTags] = useState<string[]>([]);\n\n const courses = data?.tecListCourses.items ?? [];\n\n const resetForm = () => {\n setTitle('');\n setSlug('');\n setSummary('');\n setTopic('');\n setLevel('BEGINNER');\n setMinutes('');\n setTags([]);\n setShowForm(false);\n };\n\n const handleCreate = async () => {\n const t = title.trim();\n if (!t) return notify.error('Title is required');\n const finalSlug = slugify(slug || t);\n if (!finalSlug) return notify.error('A valid slug is required');\n const res = await createCourse({\n variables: {\n input: {\n title: t,\n slug: finalSlug,\n summary: summary.trim() || undefined,\n topic: topic.trim() || undefined,\n level,\n estimatedMinutes: parseIntOrUndef(minutes),\n tags,\n },\n },\n });\n if (res.data?.tecCreateCourse) {\n notify.success('Course created', `\"${t}\" saved as a draft.`);\n resetForm();\n await refetch();\n }\n };\n\n const handlePublish = async (id: string) => {\n setActingId(id);\n try {\n const res = await publishCourse({ variables: { id } });\n if (res.data?.tecPublishCourse) {\n notify.success('Course published');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n const handleArchive = async (id: string, title: string) => {\n const confirmed = await nativeConfirm({\n title: 'Archive course',\n message: `Archive \"${title}\"? Learners will no longer be able to enroll.`,\n okButtonTitle: 'Archive',\n cancelButtonTitle: 'Cancel',\n });\n if (!confirmed) return;\n setActingId(id);\n try {\n const res = await archiveCourse({ variables: { id } });\n if (res.data?.tecArchiveCourse) {\n notify.success('Course archived');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${courses.length} course${courses.length === 1 ? '' : 's'}`}\n actionLabel=\"New course\"\n open={showForm}\n onToggle={() => setShowForm((v) => !v)}\n />\n\n {showForm ? (\n <FormCard\n title=\"New course\"\n description=\"Draft a course, then add lessons and publish when it's ready.\"\n icon={BookOpen}\n footer={\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={resetForm}>\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleCreate} disabled={creating}>\n {creating ? 'Creating…' : 'Create course'}\n </Button>\n </>\n }\n >\n <Field label=\"Title\" required>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Intro to TypeScript\"\n />\n </Field>\n <Field label=\"Slug\" required>\n <Input\n value={slug}\n onChange={(e) => setSlug(e.target.value)}\n placeholder=\"auto from title if blank\"\n />\n </Field>\n <Field label=\"Topic\">\n <Input\n value={topic}\n onChange={(e) => setTopic(e.target.value)}\n placeholder=\"e.g. Web, AI, Data, Cloud\"\n />\n </Field>\n <Field label=\"Level\">\n <Select value={level} onValueChange={(v) => setLevel(v as TecCourseLevel)}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {LEVELS.map((l) => (\n <SelectItem key={l} value={l}>\n {humanizeEnum(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Estimated minutes\">\n <Input\n type=\"number\"\n min={0}\n value={minutes}\n onChange={(e) => setMinutes(e.target.value)}\n placeholder=\"120\"\n />\n </Field>\n <Field label=\"Tags\">\n <TagInput value={tags} onChange={setTags} placeholder=\"typescript, basics\" />\n </Field>\n <Field label=\"Summary\" className=\"sm:col-span-2\">\n <Textarea\n value={summary}\n onChange={(e) => setSummary(e.target.value)}\n placeholder=\"What learners will build and take away.\"\n />\n </Field>\n </FormCard>\n ) : null}\n\n {loading && !courses.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load courses\" error={error} />\n ) : courses.length === 0 ? (\n <EmptyView\n icon={<BookOpen size={26} />}\n title=\"No courses yet\"\n description=\"Create your first course with the button above. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {courses.map((c) => (\n <div key={c.id}>\n <RowShell\n leading={\n <IconTile\n seed={`${c.topic ?? ''} ${c.title}`}\n icon={topicIcon(c.topic ?? c.title)}\n />\n }\n actions={\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setLessonsFor(lessonsFor === c.id ? null : c.id)}\n >\n <ListChecks size={15} /> Lessons\n </Button>\n {c.status === 'DRAFT' ? (\n <Button\n size=\"sm\"\n onClick={() => handlePublish(c.id)}\n disabled={actingId === c.id}\n >\n <Rocket size={15} /> Publish\n </Button>\n ) : null}\n {c.status !== 'ARCHIVED' ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleArchive(c.id, c.title)}\n disabled={actingId === c.id}\n >\n <Archive size={15} /> Archive\n </Button>\n ) : null}\n </>\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {c.title}\n </span>\n <StatusBadge status={c.status} />\n <StatusBadge status={c.level} kind=\"level\" />\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {c.slug} · {c.topic ?? 'No topic'} · {formatDuration(c.estimatedMinutes)}\n </div>\n </RowShell>\n {lessonsFor === c.id ? <LessonManager courseId={c.id} /> : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* -------------------------------------------------------------- Problems */\n\nfunction ProblemsTab() {\n const { data, loading, error, refetch } = useProblemsQuery({});\n const [createProblem, { loading: creating }] = useCreateProblem();\n const [publishProblem] = usePublishProblem();\n\n const [showForm, setShowForm] = useState(false);\n const [actingId, setActingId] = useState<string | null>(null);\n const [gradeFor, setGradeFor] = useState<string | null>(null);\n\n const [title, setTitle] = useState('');\n const [slug, setSlug] = useState('');\n const [statement, setStatement] = useState('');\n const [topic, setTopic] = useState('');\n const [difficulty, setDifficulty] = useState<TecProblemDifficulty>('EASY');\n const [points, setPoints] = useState('');\n const [languages, setLanguages] = useState('');\n const [starterCode, setStarterCode] = useState('');\n\n const problems = data?.tecListProblems.items ?? [];\n\n const resetForm = () => {\n setTitle('');\n setSlug('');\n setStatement('');\n setTopic('');\n setDifficulty('EASY');\n setPoints('');\n setLanguages('');\n setStarterCode('');\n setShowForm(false);\n };\n\n const handleCreate = async () => {\n const t = title.trim();\n if (!t) return notify.error('Title is required');\n const finalSlug = slugify(slug || t);\n if (!finalSlug) return notify.error('A valid slug is required');\n const res = await createProblem({\n variables: {\n input: {\n title: t,\n slug: finalSlug,\n statement: statement.trim() || undefined,\n topic: topic.trim() || undefined,\n difficulty,\n points: parseIntOrUndef(points),\n languages: parseCsv(languages),\n starterCode: starterCode.trim() || undefined,\n },\n },\n });\n if (res.data?.tecCreateProblem) {\n notify.success('Problem created', `\"${t}\" saved as a draft.`);\n resetForm();\n await refetch();\n }\n };\n\n const handlePublish = async (id: string) => {\n setActingId(id);\n try {\n const res = await publishProblem({ variables: { id } });\n if (res.data?.tecPublishProblem) {\n notify.success('Problem published');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${problems.length} problem${problems.length === 1 ? '' : 's'}`}\n actionLabel=\"New problem\"\n open={showForm}\n onToggle={() => setShowForm((v) => !v)}\n />\n\n {showForm ? (\n <FormCard\n title=\"New problem\"\n description=\"Define a coding challenge learners can solve and submit.\"\n icon={Code2}\n footer={\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={resetForm}>\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleCreate} disabled={creating}>\n {creating ? 'Creating…' : 'Create problem'}\n </Button>\n </>\n }\n >\n <Field label=\"Title\" required>\n <Input value={title} onChange={(e) => setTitle(e.target.value)} placeholder=\"Two Sum\" />\n </Field>\n <Field label=\"Slug\" required>\n <Input\n value={slug}\n onChange={(e) => setSlug(e.target.value)}\n placeholder=\"auto from title if blank\"\n />\n </Field>\n <Field label=\"Topic\">\n <Input value={topic} onChange={(e) => setTopic(e.target.value)} placeholder=\"Arrays\" />\n </Field>\n <Field label=\"Difficulty\">\n <Select\n value={difficulty}\n onValueChange={(v) => setDifficulty(v as TecProblemDifficulty)}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DIFFICULTIES.map((d) => (\n <SelectItem key={d} value={d}>\n {humanizeEnum(d)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n <Field label=\"Points\">\n <Input\n type=\"number\"\n min={0}\n value={points}\n onChange={(e) => setPoints(e.target.value)}\n placeholder=\"100\"\n />\n </Field>\n <Field label=\"Languages (comma-separated)\">\n <Input\n value={languages}\n onChange={(e) => setLanguages(e.target.value)}\n placeholder=\"python, typescript\"\n />\n </Field>\n <Field label=\"Statement\" className=\"sm:col-span-2\">\n <Textarea\n value={statement}\n onChange={(e) => setStatement(e.target.value)}\n placeholder=\"Describe the problem and constraints.\"\n />\n </Field>\n <Field label=\"Starter code\" className=\"sm:col-span-2\">\n <Textarea\n value={starterCode}\n onChange={(e) => setStarterCode(e.target.value)}\n className=\"font-mono\"\n placeholder=\"def solve(nums, target):\\n pass\"\n />\n </Field>\n </FormCard>\n ) : null}\n\n {loading && !problems.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load problems\" error={error} />\n ) : problems.length === 0 ? (\n <EmptyView\n icon={<Code2 size={26} />}\n title=\"No problems yet\"\n description=\"Create your first coding problem with the button above. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {problems.map((p) => (\n <div key={p.id}>\n <RowShell\n leading={\n <IconTile\n seed={`${p.topic ?? ''} ${p.title}`}\n icon={topicIcon(p.topic ?? p.title)}\n />\n }\n actions={\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setGradeFor(gradeFor === p.id ? null : p.id)}\n >\n <Gavel size={15} /> Grade\n </Button>\n {p.status === 'DRAFT' ? (\n <Button\n size=\"sm\"\n onClick={() => handlePublish(p.id)}\n disabled={actingId === p.id}\n >\n <Rocket size={15} /> Publish\n </Button>\n ) : null}\n </>\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {p.title}\n </span>\n <StatusBadge status={p.status} />\n <StatusBadge status={p.difficulty} kind=\"level\" />\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {p.slug} · {p.topic ?? 'No topic'} · {p.points} pts ·{' '}\n {p.languages.length ? p.languages.join(', ') : 'No languages'}\n </div>\n </RowShell>\n {gradeFor === p.id ? <SubmissionGrader problemId={p.id} /> : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------ Hackathons */\n\nfunction HackathonsTab() {\n const { data, loading, error, refetch } = useHackathonsQuery({});\n const [createHackathon, { loading: creating }] = useCreateHackathon();\n const [openRegistration] = useOpenRegistration();\n const [startHackathon] = useStartHackathon();\n const [startJudging] = useStartJudging();\n const [completeHackathon] = useCompleteHackathon();\n\n const [showForm, setShowForm] = useState(false);\n const [actingId, setActingId] = useState<string | null>(null);\n const [judgeFor, setJudgeFor] = useState<string | null>(null);\n\n const [title, setTitle] = useState('');\n const [slug, setSlug] = useState('');\n const [theme, setTheme] = useState('');\n const [description, setDescription] = useState('');\n const [startAt, setStartAt] = useState('');\n const [endAt, setEndAt] = useState('');\n const [prizePool, setPrizePool] = useState('');\n const [maxTeamSize, setMaxTeamSize] = useState('');\n const [tags, setTags] = useState<string[]>([]);\n\n const hackathons = data?.tecListHackathons.items ?? [];\n\n const resetForm = () => {\n setTitle('');\n setSlug('');\n setTheme('');\n setDescription('');\n setStartAt('');\n setEndAt('');\n setPrizePool('');\n setMaxTeamSize('');\n setTags([]);\n setShowForm(false);\n };\n\n const handleCreate = async () => {\n const t = title.trim();\n if (!t) return notify.error('Title is required');\n const finalSlug = slugify(slug || t);\n if (!finalSlug) return notify.error('A valid slug is required');\n const startIso = toIsoOrNull(startAt);\n const endIso = toIsoOrNull(endAt);\n if (!startIso || !endIso) return notify.error('Start and end date/time are required');\n if (new Date(endIso) <= new Date(startIso)) return notify.error('End must be after the start');\n const res = await createHackathon({\n variables: {\n input: {\n title: t,\n slug: finalSlug,\n theme: theme.trim() || undefined,\n description: description.trim() || undefined,\n startAt: startIso,\n endAt: endIso,\n prizePool: parseIntOrUndef(prizePool),\n maxTeamSize: parseIntOrUndef(maxTeamSize),\n tags,\n },\n },\n });\n if (res.data?.tecCreateHackathon) {\n notify.success('Hackathon created', `\"${t}\" saved as a draft.`);\n resetForm();\n await refetch();\n }\n };\n\n const handleOpen = async (id: string) => {\n setActingId(id);\n try {\n const res = await openRegistration({ variables: { id } });\n if (res.data?.tecOpenRegistration) {\n notify.success('Registration open', 'Teams can now register.');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n const advance = async (\n id: string,\n run: (v: { variables: { id: string } }) => Promise<{ data?: unknown }>,\n message: string\n ) => {\n setActingId(id);\n try {\n const res = await run({ variables: { id } });\n if (res.data) {\n notify.success(message);\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${hackathons.length} hackathon${hackathons.length === 1 ? '' : 's'}`}\n actionLabel=\"New hackathon\"\n open={showForm}\n onToggle={() => setShowForm((v) => !v)}\n />\n\n {showForm ? (\n <FormCard\n title=\"New hackathon\"\n description=\"Set up an event, open registration, then run judging to completion.\"\n icon={Trophy}\n footer={\n <>\n <Button variant=\"outline\" size=\"sm\" onClick={resetForm}>\n Cancel\n </Button>\n <Button size=\"sm\" onClick={handleCreate} disabled={creating}>\n {creating ? 'Creating…' : 'Create hackathon'}\n </Button>\n </>\n }\n >\n <Field label=\"Title\" required>\n <Input\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Build Days 2026\"\n />\n </Field>\n <Field label=\"Slug\" required>\n <Input\n value={slug}\n onChange={(e) => setSlug(e.target.value)}\n placeholder=\"auto from title if blank\"\n />\n </Field>\n <Field label=\"Theme\">\n <Input\n value={theme}\n onChange={(e) => setTheme(e.target.value)}\n placeholder=\"AI for good\"\n />\n </Field>\n <Field label=\"Tags\">\n <TagInput value={tags} onChange={setTags} placeholder=\"ai, web\" />\n </Field>\n <Field label=\"Starts\" required>\n <Input\n type=\"datetime-local\"\n value={startAt}\n onChange={(e) => setStartAt(e.target.value)}\n />\n </Field>\n <Field label=\"Ends\" required>\n <Input type=\"datetime-local\" value={endAt} onChange={(e) => setEndAt(e.target.value)} />\n </Field>\n <Field label=\"Prize pool\">\n <Input\n type=\"number\"\n min={0}\n value={prizePool}\n onChange={(e) => setPrizePool(e.target.value)}\n placeholder=\"5000\"\n />\n </Field>\n <Field label=\"Max team size\">\n <Input\n type=\"number\"\n min={1}\n value={maxTeamSize}\n onChange={(e) => setMaxTeamSize(e.target.value)}\n placeholder=\"4\"\n />\n </Field>\n <Field label=\"Description\" className=\"sm:col-span-2\">\n <Textarea\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"What the hackathon is about and how judging works.\"\n />\n </Field>\n </FormCard>\n ) : null}\n\n {loading && !hackathons.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load hackathons\" error={error} />\n ) : hackathons.length === 0 ? (\n <EmptyView\n icon={<Trophy size={26} />}\n title=\"No hackathons yet\"\n description=\"Create your first hackathon with the button above. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {hackathons.map((h) => (\n <div key={h.id}>\n <RowShell\n leading={<IconTile seed={h.title} icon={topicIcon(h.title, Trophy)} />}\n actions={\n <>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setJudgeFor(judgeFor === h.id ? null : h.id)}\n >\n <Users size={15} /> Teams\n </Button>\n {h.status === 'DRAFT' ? (\n <Button\n size=\"sm\"\n onClick={() => handleOpen(h.id)}\n disabled={actingId === h.id}\n >\n <Rocket size={15} /> Open registration\n </Button>\n ) : null}\n {h.status === 'REGISTRATION_OPEN' ? (\n <Button\n size=\"sm\"\n onClick={() => advance(h.id, startHackathon, 'Hackathon started')}\n disabled={actingId === h.id}\n >\n <Play size={15} /> Start\n </Button>\n ) : null}\n {h.status === 'IN_PROGRESS' ? (\n <Button\n size=\"sm\"\n onClick={() => advance(h.id, startJudging, 'Judging started')}\n disabled={actingId === h.id}\n >\n <Gavel size={15} /> Start judging\n </Button>\n ) : null}\n {h.status === 'JUDGING' ? (\n <Button\n size=\"sm\"\n onClick={() => advance(h.id, completeHackathon, 'Hackathon completed')}\n disabled={actingId === h.id}\n >\n <Award size={15} /> Complete\n </Button>\n ) : null}\n </>\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {h.title}\n </span>\n <StatusBadge status={h.status} />\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {h.slug} · {formatDateTime(h.startAt)} → {formatDateTime(h.endAt)}\n {h.prizePool ? ` · ${formatMoney(h.prizePool, h.currency)} prize` : ''}\n </div>\n </RowShell>\n {judgeFor === h.id ? <HackathonManager hackathon={h} /> : null}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* --------------------------------------------------------------- Mentors */\n\nfunction MentorsTab() {\n const { data, loading, error, refetch } = useMentorsQuery({});\n const [approveMentor] = useApproveMentor();\n const [actingId, setActingId] = useState<string | null>(null);\n\n const mentors = data?.tecListMentors.items ?? [];\n const pending = mentors.filter((m) => m.status === 'PENDING').length;\n\n const handleApprove = async (id: string) => {\n setActingId(id);\n try {\n const res = await approveMentor({ variables: { id } });\n if (res.data?.tecApproveMentor) {\n notify.success('Mentor approved', 'They can now accept mentees.');\n await refetch();\n }\n } finally {\n setActingId(null);\n }\n };\n\n return (\n <div className=\"space-y-4\">\n <TabHeader\n summary={`${mentors.length} mentor${mentors.length === 1 ? '' : 's'}${\n pending ? ` · ${pending} pending approval` : ''\n }`}\n />\n\n {loading && !mentors.length ? (\n <LoadingRows count={4} />\n ) : error ? (\n <ErrorView title=\"Couldn't load mentors\" error={error} />\n ) : mentors.length === 0 ? (\n <EmptyView\n icon={<Users size={26} />}\n title=\"No mentors yet\"\n description=\"Mentor applications will appear here for review. TechnoSpam is pre-launch.\"\n />\n ) : (\n <div className=\"space-y-3\">\n {mentors.map((m) => (\n <RowShell\n key={m.id}\n leading={\n <IconTile seed={m.headline} icon={topicIcon(m.expertise[0] ?? m.headline, Users)} />\n }\n actions={\n m.status === 'PENDING' ? (\n <Button\n size=\"sm\"\n onClick={() => handleApprove(m.id)}\n disabled={actingId === m.id}\n >\n <UserCheck size={15} /> Approve\n </Button>\n ) : undefined\n }\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"truncate text-sm font-semibold text-text-primary\">\n {m.headline}\n </span>\n <StatusBadge status={m.status} />\n {m.isAcceptingMentees ? (\n <Badge variant=\"secondary\" className=\"text-[11px]\">\n Accepting mentees\n </Badge>\n ) : null}\n </div>\n <div className=\"mt-1 truncate text-xs text-text-muted\">\n {m.expertise.length ? m.expertise.slice(0, 4).join(', ') : 'No expertise listed'} ·{' '}\n {formatMoney(m.hourlyRate, m.currency)}/hr · {m.sessionsCount} sessions\n </div>\n </RowShell>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/* ------------------------------------------------------------ page shell */\n\ntype AdminTab = 'courses' | 'problems' | 'hackathons' | 'mentors';\n\nexport function AdminAdminDashboardPagePage() {\n const [tab, setTab] = useState<AdminTab>('courses');\n const { currentUser } = useTechnoSpam();\n const role = (currentUser?.role ?? '').toLowerCase();\n const privileged =\n role.includes('admin') || role.includes('owner') || role.includes('instructor');\n\n return (\n <PageLayout\n hero\n title=\"Authoring Console\"\n description=\"Create and manage TechnoSpam content — courses, problems, hackathons, and mentor applications.\"\n >\n {!privileged ? (\n <GlassCard className=\"mb-5 flex items-start gap-3 border-status-warning-border p-4\">\n <ShieldAlert size={18} className=\"mt-0.5 shrink-0 text-status-warning-text\" />\n <div className=\"text-sm text-text-secondary\">\n <span className=\"font-medium text-text-primary\">\n Authoring is limited to workspace admins.\n </span>{' '}\n You can review content here, but create/publish actions require the right permission and\n will be rejected at the gateway otherwise.\n </div>\n </GlassCard>\n ) : null}\n <Tabs value={tab} onValueChange={(v) => setTab(v as AdminTab)}>\n <TabsList className=\"mb-5\">\n <TabsTrigger value=\"courses\">\n <BookOpen size={15} /> Courses\n </TabsTrigger>\n <TabsTrigger value=\"problems\">\n <Code2 size={15} /> Problems\n </TabsTrigger>\n <TabsTrigger value=\"hackathons\">\n <Trophy size={15} /> Hackathons\n </TabsTrigger>\n <TabsTrigger value=\"mentors\">\n <Users size={15} /> Mentors\n </TabsTrigger>\n </TabsList>\n </Tabs>\n\n {tab === 'courses' ? (\n <CoursesTab />\n ) : tab === 'problems' ? (\n <ProblemsTab />\n ) : tab === 'hackathons' ? (\n <HackathonsTab />\n ) : (\n <MentorsTab />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -123,7 +123,7 @@ function I({ title: e, subtitle: t, icon: n, tone: r = "teal", isEmpty: i, empty
123
123
  });
124
124
  }
125
125
  function L() {
126
- let n = t(), { currentUser: P } = e(), L = P?.id, R = ie(L ? { learnerId: L } : {}), z = ce(L ? { learnerId: L } : {}), B = se(L ? { menteeId: L } : {}), V = ne(L ? { learnerId: L } : {}), xe = re({ status: "PUBLISHED" }), Se = oe({ status: "PUBLISHED" }), Ce = ae({}), H = g(() => R.data?.tecListEnrollments.items ?? [], [R.data]), U = g(() => z.data?.tecListSubmissions.items ?? [], [z.data]), W = B.data?.tecListSessions ?? [], G = V.data?.tecListCertificates ?? [], we = xe.data?.tecListCourses.items.length ?? 0, Te = Se.data?.tecListProblems.items.length ?? 0, Ee = Ce.data?.tecListHackathons.items.length ?? 0, K = g(() => {
126
+ let n = t(), { currentUser: P } = e(), L = P?.id, R = ie(L ? { learnerId: L } : {}), z = ce(L ? { learnerId: L } : {}), B = se(L ? { menteeId: L } : {}), V = ne(L ? { learnerId: L } : {}), xe = re({ status: "PUBLISHED" }), Se = oe({ status: "PUBLISHED" }), Ce = ae({}), H = g(() => R.data?.tecListEnrollments.items ?? [], [R.data]), U = g(() => z.data?.tecListSubmissions.items ?? [], [z.data]), W = B.data?.tecListSessions.items ?? [], G = V.data?.tecListCertificates ?? [], we = xe.data?.tecListCourses.items.length ?? 0, Te = Se.data?.tecListProblems.items.length ?? 0, Ee = Ce.data?.tecListHackathons.items.length ?? 0, K = g(() => {
127
127
  let e = H.filter((e) => e.status === "COMPLETED").length, t = H.length ? Math.round(H.reduce((e, t) => e + t.progressPct, 0) / H.length) : 0, n = U.filter((e) => e.verdict === "ACCEPTED");
128
128
  return {
129
129
  coursesCompleted: e,