import { useEffect } from 'react'; import { TabbedHubPage } from '../../components/shared/TabbedHubPage'; import { useAdminRouting } from '../../lib/adminRouting'; import type { SikshyaReactConfig } from '../../types'; import { WpEntityListPage } from '../WpEntityListPage'; import { WpUserListPage } from '../WpUserListPage'; import { InstructorApplicationsPage } from '../InstructorApplicationsPage'; import { IssuedCertificatesPage } from '../IssuedCertificatesPage'; import { OrdersPage } from '../OrdersPage'; import { PaymentsPage } from '../PaymentsPage'; import { EmailPage } from '../EmailPage'; import { EmailTemplatesListPage } from '../EmailTemplatesListPage'; import { WhiteLabelPage } from '../WhiteLabelPage'; import { SocialLoginPage } from '../SocialLoginPage'; import { IntegrationsPage } from '../IntegrationsPage'; import { EmailMarketingPage } from '../EmailMarketingPage'; import { ContentDripPage } from '../ContentDripPage'; import { PrerequisitesPage } from '../PrerequisitesPage'; import { CalendarPage } from '../CalendarPage'; import { ActivityLogPage } from '../ActivityLogPage'; import { AddonSettingsPage } from '../AddonSettingsPage'; import { QuizAdvancedWorkspacePage } from '../QuizAdvancedWorkspacePage'; import { LiveClassesWorkspacePage } from '../LiveClassesWorkspacePage'; import { ScormH5pWorkspacePage } from '../ScormH5pWorkspacePage'; import { ReportsPage } from '../ReportsPage'; import { ToolsPage } from '../ToolsPage'; import { isFeatureEnabled } from '../../lib/licensing'; import { appViewHref } from '../../lib/appUrl'; import { term } from '../../lib/terminology'; import { __ } from '../../lib/i18n'; type Props = { embedded?: boolean; config: SikshyaReactConfig; title: string }; /** * Library hub: a single nav entry that fans out to the five "all rows of one * post type" lists (Lessons / Quizzes / Assignments / Questions / Chapters). * Replaces five separate sidebar entries that each rendered the same component * with a different `restBase`. */ export function ContentLibraryHubPage({ config, title }: Props) { const T = { lessons: term(config, 'lessons'), quizzes: term(config, 'quizzes'), assignments: term(config, 'assignments'), chapters: term(config, 'chapters'), lesson: term(config, 'lesson'), quiz: term(config, 'quiz'), assignment: term(config, 'assignment'), chapter: term(config, 'chapter'), }; return ( ( ), }, { id: 'quizzes', label: T.quizzes, icon: 'puzzle', render: (c) => ( ), }, { id: 'assignments', label: T.assignments, icon: 'clipboard', render: (c) => ( ), }, { id: 'questions', label: 'Questions', icon: 'helpCircle', render: (c) => ( ), }, { id: 'chapters', label: T.chapters, icon: 'chapterStack', render: (c) => ( ), }, { id: 'question-banks', label: 'Question banks', icon: 'layers', hidden: !isFeatureEnabled(config, 'quiz_advanced'), render: (c) => ( ), }, ]} /> ); } export function PeopleHubPage({ config, title }: Props) { const students = term(config, 'students'); const instructors = term(config, 'instructors'); return ( ( ), }, { id: 'instructors', label: instructors, icon: 'userCircle', render: (c) => ( ), }, { id: 'instructor-applications', label: 'Applications', icon: 'userPlus', render: (c) => ( ), }, ]} /> ); } export function CertificatesHubPage({ config, title }: Props) { return ( ( ), }, { id: 'issued', label: 'Issued', icon: 'documentText', render: (c) => , }, { id: 'settings', label: 'Add-on defaults', icon: 'settings', hidden: !isFeatureEnabled(config, 'certificates_advanced'), render: (c) => ( ), }, ]} /> ); } export function SalesHubPage({ config, title }: Props) { const salesSubtitle = config.offlineCheckoutEnabled === false ? 'Orders (Stripe, PayPal, offline) and payment records. Use Orders → New manual order or Mark paid on pending offline rows. Enable offline checkout under Settings → Payment if learners should see it on checkout.' : 'Orders (Stripe, PayPal, offline) and payment records. Use Orders → New manual order or Mark paid on pending offline rows after you confirm payment.'; return ( , }, { id: 'payments', label: 'Payments', icon: 'creditCard', render: (c) => , }, ]} /> ); } export function EmailHubPage({ config, title }: Props) { const { route, navigateView } = useAdminRouting(); // Legacy `view=email-templates` loads this page too; normalize the URL to the hub // so bookmarks, support links, and the server redirect all converge on one shape. useEffect(() => { if (route.page !== 'email-templates') { return; } const q = route.query; const nextTab = (q.tab || '').trim() || 'templates'; const extra: Record = { ...q }; delete extra.tab; navigateView('email-hub', { tab: nextTab, ...extra }, { replace: true }); }, [route.page, route.query, navigateView]); return ( , }, { id: 'templates', label: 'Templates', icon: 'documentText', render: (c) => , }, ]} /> ); } export function BrandingHubPage({ config, title }: Props) { // Show the social-login tab only when the feature exists in this build, so unlicensed // customers don't see an empty rail of options promising features they can't use yet. const hasSocial = isFeatureEnabled(config, 'social_login'); return ( , }, { id: 'social-login', label: 'Social login', icon: 'users', hidden: !hasSocial, render: (c) => , }, ]} /> ); } export function IntegrationsHubPage({ config, title }: Props) { return ( , }, { id: 'email-marketing', label: 'Email marketing', icon: 'mail', render: (c) => , }, { id: 'live-classes', label: 'Live classes', icon: 'schedule', hidden: !isFeatureEnabled(config, 'live_classes'), render: (c) => , }, { id: 'scorm-h5p', label: 'SCORM / H5P', icon: 'layers', hidden: !isFeatureEnabled(config, 'scorm_h5p_pro'), render: (c) => , }, { id: 'multilingual', label: 'Multilingual', icon: 'translate', hidden: !isFeatureEnabled(config, 'multilingual_enterprise'), render: (c) => ( ), }, ]} /> ); } export function LearningRulesHubPage({ embedded, config, title }: Props) { return ( , }, { id: 'prerequisites', label: 'Prerequisites', icon: 'lockClosed', render: (c) => , }, ]} /> ); } /** * Reports hub. Calendar lived under the Reports group anyway and is really a * dated event feed, so it now sits next to Overview as a peer tab. Gradebook * keeps its own sidebar entry because it is a true second job ("grade work") * rather than a different view of the same dataset. */ export function ReportsHubPage({ embedded, config, title }: Props) { return ( , }, { id: 'calendar', label: 'Calendar', icon: 'schedule', render: (c) => , }, ]} /> ); } /** * Tools hub. Activity log was previously misfiled under Reports — it is an * audit trail used during support / compliance, not a metric. Putting it next * to system diagnostics is a better mental model. */ export function ToolsHubPage({ embedded, config, title }: Props) { return ( , }, { id: 'activity', label: 'Activity log', icon: 'bolt', render: (c) => , }, ]} /> ); }