@fayz-ai/plugin-courses 0.10.50 → 0.10.51
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.
- package/dist/CourseEditorPage-GEBTVW7G.js +939 -0
- package/dist/CourseEditorPage-GEBTVW7G.js.map +1 -0
- package/dist/CourseOrderDetailView-LWHDQNZ7.js +122 -0
- package/dist/CourseOrderDetailView-LWHDQNZ7.js.map +1 -0
- package/dist/CoursesListPage-WDG3YHF4.js +95 -0
- package/dist/CoursesListPage-WDG3YHF4.js.map +1 -0
- package/dist/CoursesSettings-RLLYRP2R.js +56 -0
- package/dist/CoursesSettings-RLLYRP2R.js.map +1 -0
- package/dist/FinancialPage-UXD25JYA.js +53 -0
- package/dist/FinancialPage-UXD25JYA.js.map +1 -0
- package/dist/ReportsPage-ZC3QUISB.js +50 -0
- package/dist/ReportsPage-ZC3QUISB.js.map +1 -0
- package/dist/SalesPage-VNYJXPTU.js +85 -0
- package/dist/SalesPage-VNYJXPTU.js.map +1 -0
- package/dist/SubscriptionsPage-IGV723DM.js +66 -0
- package/dist/SubscriptionsPage-IGV723DM.js.map +1 -0
- package/dist/chunk-4DMJIPDN.js +11 -0
- package/dist/chunk-4DMJIPDN.js.map +1 -0
- package/dist/chunk-A4BEN6VV.js +15 -0
- package/dist/chunk-A4BEN6VV.js.map +1 -0
- package/dist/chunk-U5LQDCGG.js +92 -0
- package/dist/chunk-U5LQDCGG.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1478
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/CourseEditorPage.tsx"],"names":[],"mappings":"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","file":"CourseEditorPage-GEBTVW7G.js","sourcesContent":["import * as React from 'react'\nimport {\n Button, Input, Badge, Textarea, toast, Skeleton,\n Tabs, TabsList, TabsTrigger, TabsContent,\n Select, SelectTrigger, SelectValue, SelectContent, SelectItem,\n SegmentedControl, type SegmentedOption,\n Checkbox, ConfirmDialog, useSaveBar,\n Separator, PageHeader,\n} from '@fayz-ai/ui'\nimport { useTranslation, getSupabaseClientOptional, formatCurrency } from '@fayz-ai/core'\nimport {\n getCoursesProvider,\n type Course, type Module, type Lesson, type CourseStatus,\n type Offer, type OfferKind, type RecurringInterval, type Order,\n} from '@fayz-ai/courses'\n\n/** Derived from the Course model (the package doesn't re-export the union name). */\ntype CourseDeliveryType = Course['deliveryType']\nimport {\n Plus, Trash2, Check, ImagePlus, UploadCloud,\n Layers, Tag, Users, ShoppingCart, Loader2, Clock,\n GripVertical, ChevronDown, Video, FileText, PlayCircle, Lock, Info,\n} from 'lucide-react'\nimport {\n DndContext, closestCenter, PointerSensor, KeyboardSensor,\n useSensor, useSensors, type DragEndEvent,\n} from '@dnd-kit/core'\nimport {\n SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy,\n useSortable, arrayMove,\n} from '@dnd-kit/sortable'\nimport { CSS } from '@dnd-kit/utilities'\nimport { navigateTo } from '../lib/nav'\nimport { EmptyState, SectionCard, InfoNote } from '../components/CommerceUI'\n\n/** Local alias for the translate function used across the tree builder below. */\ntype TFn = (key: string) => string\n\n/** A distinct enrolled student for this course, derived from its paid orders. */\ninterface CourseStudent {\n key: string\n name: string\n email: string | null\n since: string | null\n}\n\n/** Dedupe paid orders into one row per buyer (latest purchase kept). */\nfunction buildCourseStudents(orders: Order[]): CourseStudent[] {\n const byKey = new Map<string, CourseStudent>()\n for (const o of orders) {\n const key = o.customerId ?? o.customerEmail ?? o.id\n const existing = byKey.get(key)\n if (!existing || (o.createdAt && existing.since && o.createdAt > existing.since)) {\n byKey.set(key, {\n key,\n name: o.customerName ?? o.customerEmail ?? '—',\n email: o.customerEmail ?? null,\n since: o.createdAt ?? null,\n })\n }\n }\n return [...byKey.values()].sort((a, b) => (b.since ?? '').localeCompare(a.since ?? ''))\n}\n\nconst STATUSES: CourseStatus[] = ['draft', 'published', 'archived']\nconst DELIVERY_TYPES: CourseDeliveryType[] = ['online', 'in_person', 'hybrid']\n\nconst TABS = ['details', 'curriculum', 'offers', 'members'] as const\ntype Tab = (typeof TABS)[number]\n\nconst TAB_ICON: Record<Tab, React.ElementType> = {\n details: Tag,\n curriculum: Layers,\n offers: ShoppingCart,\n members: Users,\n}\n\n/** The editable subset of a course — used to detect unsaved changes on the Geral tab. */\nfunction editSnapshot(c: Course): string {\n return JSON.stringify({\n title: c.title, subtitle: c.subtitle, description: c.description,\n price: c.price, status: c.status, deliveryType: c.deliveryType, thumbnailUrl: c.thumbnailUrl,\n })\n}\n\nexport function CourseEditorPage({ id }: { id?: string }) {\n const t = useTranslation()\n const [tab, setTab] = React.useState<Tab>('details')\n const [course, setCourse] = React.useState<Course | null>(null)\n const [modules, setModules] = React.useState<Module[]>([])\n const [lessons, setLessons] = React.useState<Lesson[]>([])\n const [offers, setOffers] = React.useState<Offer[]>([])\n const [students, setStudents] = React.useState<CourseStudent[]>([])\n const [loading, setLoading] = React.useState(true)\n\n // Geral tab: explicit-save model with dirty tracking.\n const [savedSnap, setSavedSnap] = React.useState('')\n const [saving, setSaving] = React.useState(false)\n const [uploading, setUploading] = React.useState(false)\n const fileRef = React.useRef<HTMLInputElement>(null)\n\n // Delete confirmation for the curriculum tab.\n const [pendingDelete, setPendingDelete] = React.useState<\n { kind: 'module' | 'lesson'; id: string } | null\n >(null)\n // Id of a just-created module/lesson whose title input should grab focus.\n const [autoFocusId, setAutoFocusId] = React.useState<string | null>(null)\n\n const reload = React.useCallback(async () => {\n if (!id) return\n const provider = getCoursesProvider()\n const c = await provider.getCourse(id)\n setCourse(c)\n if (c) {\n setSavedSnap(editSnapshot(c))\n const [m, l, o, paidOrders] = await Promise.all([\n provider.listModules(c.id),\n provider.listLessons(c.id),\n provider.listOffers(c.id),\n provider.listOrders({ courseId: c.id, financialStatus: 'paid' }),\n ])\n setModules(m)\n setLessons(l)\n setOffers(o)\n setStudents(buildCourseStudents(paidOrders))\n }\n setLoading(false)\n }, [id])\n\n React.useEffect(() => { void reload() }, [reload])\n\n const dirty = !!course && editSnapshot(course) !== savedSnap\n\n // Persist the Geral tab through the app's generic floating unsaved-changes bar\n // (the same SaveBar the rest of the CRUD uses) instead of an inline button.\n useSaveBar({\n dirty,\n saving,\n onSave: () => { void saveDetails() },\n onDiscard: () => { void reload() },\n saveLabel: t('courses.editor.save') || 'Salvar',\n })\n\n // A volta vai para a barra de topo da shell, não para uma linha acima do\n // título — empilhados, a barra dizia \"Cursos\" e o link logo abaixo dizia\n // \"Voltar aos cursos\": a mesma navegação duas vezes, com uma linha de\n // distância. É o que CrudDetailPage já faz em toda ficha de registro, e de\n // quebra liga o Esc e o voltar entre módulos, que o botão inline não tinha.\n //\n // Chamado ANTES do early return do skeleton (regra dos hooks); com `current`\n // vazio o Breadcrumb desenha um placeholder pulsando enquanto o curso carrega.\n const header = (\n <PageHeader\n title={course?.title ?? ''}\n parentLabel={t('courses.title') || 'Courses'}\n onBack={() => navigateTo('/courses')}\n />\n )\n\n if (loading || !course) return <>{header}<EditorSkeleton /></>\n\n function patchCourse(patch: Partial<Course>) {\n setCourse((c) => (c ? { ...c, ...patch } : c))\n }\n\n async function saveDetails() {\n if (!course) return\n setSaving(true)\n try {\n await getCoursesProvider().updateCourse(course.id, {\n title: course.title,\n subtitle: course.subtitle ?? undefined,\n description: course.description ?? undefined,\n thumbnailUrl: course.thumbnailUrl ?? undefined,\n price: course.price,\n status: course.status,\n deliveryType: course.deliveryType,\n })\n setSavedSnap(editSnapshot(course))\n toast.success(t('courses.editor.saved') || 'Course saved')\n } catch {\n toast.error(t('courses.editor.saveFailed') || 'Could not save the course')\n } finally {\n setSaving(false)\n }\n }\n\n async function onPickThumbnail(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0]\n if (!file || !course) return\n const supabase = getSupabaseClientOptional() as {\n storage?: {\n from: (b: string) => {\n upload: (p: string, f: File, o?: unknown) => Promise<{ error: unknown }>\n getPublicUrl: (p: string) => { data: { publicUrl: string } }\n }\n }\n } | null\n if (!supabase?.storage) {\n toast.error(t('courses.editor.uploadUnavailable') || 'Upload unavailable — paste an image URL instead.')\n if (fileRef.current) fileRef.current.value = ''\n return\n }\n setUploading(true)\n try {\n const ext = file.name.split('.').pop() || 'jpg'\n const path = `${course.id}/cover-${Date.now()}.${ext}`\n const bucket = supabase.storage.from('course-media')\n const { error } = await bucket.upload(path, file, { upsert: true, contentType: file.type })\n if (error) throw error\n const { data } = bucket.getPublicUrl(path)\n patchCourse({ thumbnailUrl: data.publicUrl })\n toast.success(t('courses.editor.thumbnailUploaded') || 'Image uploaded — remember to save.')\n } catch {\n toast.error(t('courses.editor.uploadFailed') || 'Could not upload the image')\n } finally {\n setUploading(false)\n if (fileRef.current) fileRef.current.value = ''\n }\n }\n\n // --- module / lesson mutations (persist immediately, then reload) ---------\n async function addModule() {\n const mod = await getCoursesProvider().createModule({ courseId: course!.id, title: t('courses.editor.untitledModule') || 'New module' })\n toast.success(t('courses.editor.moduleAdded') || 'Module added')\n await reload()\n setAutoFocusId(mod.id)\n }\n async function renameModule(moduleId: string, title: string) {\n await getCoursesProvider().updateModule(moduleId, { title })\n }\n async function addLesson(moduleId: string) {\n // Optimistic: drop the row at the END of the module's list immediately,\n // then persist in the background (swap the temp id for the real one, keeping\n // any edits made meanwhile). No full reload → no flash.\n const tempId = `tmp-${crypto.randomUUID()}`\n const nextOrder = lessons\n .filter((l) => l.moduleId === moduleId)\n .reduce((max, l) => Math.max(max, l.sortOrder), -1) + 1\n const optimistic: Lesson = {\n id: tempId,\n courseId: course!.id,\n moduleId,\n title: t('courses.editor.untitledLesson') || 'New lesson',\n description: null,\n videoUrl: '',\n durationSec: 0,\n sortOrder: nextOrder,\n }\n setLessons((ls) => [...ls, optimistic])\n setAutoFocusId(tempId)\n try {\n const real = await getCoursesProvider().createLesson({\n courseId: course!.id,\n moduleId,\n title: optimistic.title,\n videoUrl: '',\n })\n setLessons((ls) => ls.map((l) => (l.id === tempId ? { ...l, id: real.id } : l)))\n setAutoFocusId((cur) => (cur === tempId ? real.id : cur))\n } catch {\n setLessons((ls) => ls.filter((l) => l.id !== tempId))\n toast.error(t('courses.editor.saveFailed') || 'Could not add the lesson')\n }\n }\n async function patchLesson(lessonId: string, patch: Partial<Lesson>) {\n await getCoursesProvider().updateLesson(lessonId, {\n title: patch.title,\n videoUrl: patch.videoUrl,\n durationSec: patch.durationSec,\n description: patch.description ?? undefined,\n })\n }\n\n // Persist a new module order (optimistic — reload re-sorts by sort_order).\n async function reorderModules(orderedIds: string[]) {\n const prev = modules\n setModules(orderedIds.map((mid, i) => ({ ...prev.find((m) => m.id === mid)!, sortOrder: i })))\n try {\n await Promise.all(orderedIds.map((mid, i) => getCoursesProvider().updateModule(mid, { sortOrder: i })))\n } catch {\n toast.error(t('courses.editor.reorderFailed') || 'Could not reorder')\n } finally {\n await reload()\n }\n }\n // Persist a new lesson order within one module.\n async function reorderLessons(moduleId: string, orderedIds: string[]) {\n const prev = lessons\n const others = prev.filter((l) => l.moduleId !== moduleId)\n const reordered = orderedIds.map((lid, i) => ({ ...prev.find((l) => l.id === lid)!, sortOrder: i }))\n setLessons([...others, ...reordered])\n try {\n await Promise.all(orderedIds.map((lid, i) => getCoursesProvider().updateLesson(lid, { sortOrder: i })))\n } catch {\n toast.error(t('courses.editor.reorderFailed') || 'Could not reorder')\n } finally {\n await reload()\n }\n }\n\n async function confirmDelete() {\n if (!pendingDelete) return\n const provider = getCoursesProvider()\n if (pendingDelete.kind === 'module') await provider.deleteModule(pendingDelete.id)\n else await provider.deleteLesson(pendingDelete.id)\n toast.success(t('courses.editor.deleted') || 'Removed')\n setPendingDelete(null)\n await reload()\n }\n\n // --- offer mutations ------------------------------------------------------\n async function addOffer() {\n await getCoursesProvider().createOffer({\n courseId: course!.id,\n name: t('courses.offers.newName') || 'New offer',\n price: course!.price,\n kind: 'one_time',\n })\n toast.success(t('courses.offers.added') || 'Offer added')\n await reload()\n }\n async function patchOffer(offerId: string, patch: Partial<Offer>) {\n await getCoursesProvider().updateOffer(offerId, {\n name: patch.name,\n price: patch.price,\n kind: patch.kind,\n recurringInterval: patch.recurringInterval,\n isOrderBump: patch.isOrderBump,\n isDefault: patch.isDefault,\n })\n await reload()\n }\n async function deleteOffer(offerId: string) {\n await getCoursesProvider().deleteOffer(offerId)\n toast.success(t('courses.offers.removed') || 'Offer removed')\n await reload()\n }\n\n const deliveryOptions: SegmentedOption<CourseDeliveryType>[] = DELIVERY_TYPES.map((d) => ({\n value: d,\n label: t(`courses.editor.delivery.${d}`) || d,\n }))\n\n return (\n // Sem padding e sem max-width próprios: a shell já envolve toda página em\n // `p-3 md:p-6` (AdminShell). Reaplicar `p-6 md:p-8` aqui empurrava o editor\n // 32px à direita do título na barra de topo e de todas as outras telas, e o\n // `mx-auto max-w-4xl` ainda o centralizava enquanto a barra ficava à esquerda.\n <div className=\"space-y-6\">\n {/* Hero — mesma anatomia da ficha de registro (CrudDetailPage): imagem à\n esquerda, título e selos à direita. A capa 16:9 em w-36 fecha os mesmos\n ~80px de altura do avatar quadrado de lá, então a linha do cabeçalho\n tem a mesma altura em todo o app. Só leitura aqui — quem troca a\n imagem é o uploader na aba Geral. */}\n <div className=\"flex items-start gap-5\">\n <div className=\"aspect-video w-36 shrink-0 overflow-hidden rounded-2xl border border-border bg-muted shadow-sm\">\n {course.thumbnailUrl ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={course.thumbnailUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full w-full items-center justify-center text-muted-foreground\">\n <ImagePlus className=\"h-6 w-6\" />\n </div>\n )}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-2\">\n <h1 className=\"truncate text-2xl font-bold text-foreground\">{course.title || (t('courses.editor.untitledCourse') || 'Untitled course')}</h1>\n <Badge variant={course.status === 'published' ? 'success' : course.status === 'archived' ? 'secondary' : 'outline'}>\n {t(`courses.status.${course.status}`) || course.status}\n </Badge>\n <Badge variant=\"outline\">{t(`courses.editor.delivery.${course.deliveryType}`) || course.deliveryType}</Badge>\n </div>\n </div>\n </div>\n\n <Separator />\n\n <Tabs value={tab} onValueChange={(v) => setTab(v as Tab)}>\n <TabsList className=\"max-w-full justify-start overflow-x-auto scrollbar-none\">\n {TABS.map((tk) => {\n const Icon = TAB_ICON[tk]\n return (\n <TabsTrigger key={tk} value={tk} className=\"gap-1.5\">\n <Icon className=\"h-3.5 w-3.5\" />\n {t(`courses.editor.tab.${tk}`) || tk}\n </TabsTrigger>\n )\n })}\n </TabsList>\n\n {/* ---- Geral ---------------------------------------------------- */}\n <TabsContent value=\"details\" className=\"mt-4 space-y-5\">\n <SectionCard title={t('courses.editor.sectionBasics') || 'Basics'}>\n <div className=\"space-y-4\">\n <Field label={t('courses.editor.fieldTitle') || 'Title'}>\n <Input value={course.title} onChange={(e) => patchCourse({ title: e.target.value })} />\n </Field>\n <Field label={t('courses.editor.fieldSubtitle') || 'Subtitle'}>\n <Input value={course.subtitle ?? ''} onChange={(e) => patchCourse({ subtitle: e.target.value })} />\n </Field>\n <Field label={t('courses.editor.fieldDescription') || 'Description'}>\n <Textarea\n className=\"min-h-[96px] px-2 py-1.5\"\n value={course.description ?? ''}\n onChange={(e) => patchCourse({ description: e.target.value })}\n placeholder={t('courses.editor.descriptionPlaceholder') || 'What will students learn?'}\n />\n </Field>\n <Field label={t('courses.editor.fieldDelivery') || 'Format'} hint={t('courses.editor.deliveryHint') || 'How this course is delivered.'}>\n <SegmentedControl\n size=\"md\"\n options={deliveryOptions}\n value={course.deliveryType}\n onChange={(v) => patchCourse({ deliveryType: v })}\n aria-label={t('courses.editor.fieldDelivery') || 'Format'}\n />\n </Field>\n </div>\n </SectionCard>\n\n <SectionCard title={t('courses.editor.sectionThumbnail') || 'Cover image'} description={t('courses.editor.thumbnailHint') || 'Shown on the storefront and in listings. 1280×720 recommended.'}>\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start\">\n <div className=\"aspect-video w-full shrink-0 overflow-hidden rounded-lg border border-border bg-muted sm:w-56\">\n {course.thumbnailUrl ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={course.thumbnailUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full w-full flex-col items-center justify-center gap-1 text-muted-foreground\">\n <ImagePlus className=\"h-6 w-6\" />\n <span className=\"text-xs\">{t('courses.editor.thumbnailEmpty') || 'No image'}</span>\n </div>\n )}\n </div>\n <div className=\"flex-1 space-y-3\">\n <input ref={fileRef} type=\"file\" accept=\"image/*\" className=\"hidden\" onChange={onPickThumbnail} />\n <Button variant=\"outline\" size=\"sm\" disabled={uploading} onClick={() => fileRef.current?.click()}>\n {uploading ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <UploadCloud className=\"h-4 w-4\" />}\n {uploading ? (t('courses.editor.uploading') || 'Uploading…') : (t('courses.editor.thumbnailUpload') || 'Upload image')}\n </Button>\n <Field label={t('courses.editor.thumbnailUrl') || 'Or paste an image URL'}>\n <Input\n value={course.thumbnailUrl ?? ''}\n placeholder=\"https://…\"\n onChange={(e) => patchCourse({ thumbnailUrl: e.target.value || null })}\n />\n </Field>\n </div>\n </div>\n </SectionCard>\n\n <SectionCard title={t('courses.editor.sectionPricing') || 'Pricing & status'}>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <Field label={t('courses.editor.fieldPrice') || 'Price'} hint={course.currency}>\n <Input\n type=\"number\"\n min={0}\n step=\"0.01\"\n inputMode=\"decimal\"\n value={String(course.price)}\n onChange={(e) => patchCourse({ price: Number(e.target.value) || 0 })}\n />\n </Field>\n <Field label={t('courses.editor.fieldStatus') || 'Status'}>\n <Select value={course.status} onValueChange={(v) => patchCourse({ status: v as CourseStatus })}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUSES.map((s) => (\n <SelectItem key={s} value={s}>{t(`courses.status.${s}`) || s}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </div>\n </SectionCard>\n </TabsContent>\n\n {/* ---- Conteúdo ------------------------------------------------- */}\n <TabsContent value=\"curriculum\" className=\"mt-4 space-y-4\">\n <CurriculumBuilder\n t={t}\n modules={modules}\n lessons={lessons}\n autoFocusId={autoFocusId}\n onAutoFocused={() => setAutoFocusId(null)}\n onAddModule={addModule}\n onRenameModule={renameModule}\n onAddLesson={addLesson}\n onPatchLesson={patchLesson}\n onRequestDelete={(kind, delId) => setPendingDelete({ kind, id: delId })}\n onReorderModules={reorderModules}\n onReorderLessons={reorderLessons}\n />\n </TabsContent>\n\n {/* ---- Ofertas -------------------------------------------------- */}\n <TabsContent value=\"offers\" className=\"mt-4 space-y-4\">\n <InfoNote icon={<Info className=\"h-4 w-4\" />}>\n {t('courses.offers.help') || 'Price points for this course. Sales run through orders and the Financeiro module.'}\n </InfoNote>\n {offers.length === 0 ? (\n <EmptyState\n icon={<Tag className=\"h-5 w-5\" />}\n title={t('courses.offers.empty') || 'No offers yet'}\n description={t('courses.offers.emptyHint') || 'Create an offer to sell this course.'}\n action={<Button onClick={addOffer}><Plus className=\"h-4 w-4\" />{t('courses.offers.firstOffer') || 'Create first offer'}</Button>}\n />\n ) : (\n <>\n {offers.map((offer) => (\n <div key={offer.id} className=\"rounded-card border border-border bg-card p-4 shadow-sm md:p-5\">\n <div className=\"mb-4 flex items-start justify-between gap-3\">\n <Badge variant=\"outline\" className=\"gap-1\">\n {offer.kind === 'subscription'\n ? (t('courses.offers.subscription') || 'Subscription')\n : (t('courses.offers.oneTime') || 'One-time')}\n </Badge>\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => deleteOffer(offer.id)}\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground/60 transition-colors hover:bg-destructive/10 hover:text-destructive\"\n aria-label={t('courses.offers.remove') || 'Remove'}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-[1fr_140px_160px]\">\n <Field label={t('courses.offers.name') || 'Offer name'}>\n <Input defaultValue={offer.name} onBlur={(e) => patchOffer(offer.id, { name: e.target.value })} />\n </Field>\n <Field label={t('courses.offers.price') || 'Price'} hint={offer.currency}>\n <Input type=\"number\" min={0} step=\"0.01\" inputMode=\"decimal\" defaultValue={String(offer.price)} onBlur={(e) => patchOffer(offer.id, { price: Number(e.target.value) || 0 })} />\n </Field>\n <Field label={t('courses.offers.kind') || 'Type'}>\n <Select\n value={offer.kind}\n onValueChange={(v) => patchOffer(offer.id, { kind: v as OfferKind, recurringInterval: v === 'subscription' ? (offer.recurringInterval ?? 'month') : null })}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"one_time\">{t('courses.offers.oneTime') || 'One-time'}</SelectItem>\n <SelectItem value=\"subscription\">{t('courses.offers.subscription') || 'Subscription'}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n </div>\n\n {offer.kind === 'subscription' && (\n <div className=\"mt-3 max-w-[200px]\">\n <Field label={t('courses.offers.interval') || 'Billing interval'}>\n <Select\n value={offer.recurringInterval ?? 'month'}\n onValueChange={(v) => patchOffer(offer.id, { recurringInterval: v as RecurringInterval })}\n >\n <SelectTrigger><SelectValue /></SelectTrigger>\n <SelectContent>\n <SelectItem value=\"month\">{t('courses.interval.month') || 'month'}</SelectItem>\n <SelectItem value=\"year\">{t('courses.interval.year') || 'year'}</SelectItem>\n </SelectContent>\n </Select>\n </Field>\n </div>\n )}\n\n {/* Storefront-only flags — de-emphasized: they persist but only take\n effect once the public checkout ships (deferred / bridge scope). */}\n <div className=\"mt-4 rounded-lg border border-dashed border-border bg-muted/30 p-3\">\n <p className=\"mb-2.5 flex items-center gap-1.5 text-xs text-muted-foreground\">\n <Clock className=\"h-3.5 w-3.5\" />\n {t('courses.offers.checkoutFlagsNote') || 'Apply once the public checkout ships (coming soon).'}\n </p>\n <div className=\"flex flex-wrap items-center gap-x-5 gap-y-2\">\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-muted-foreground\">\n <Checkbox checked={offer.isDefault} onChange={(v) => patchOffer(offer.id, { isDefault: v })} />\n {t('courses.offers.default') || 'Default'}\n </label>\n <label className=\"flex cursor-pointer items-center gap-2 text-sm text-muted-foreground\">\n <Checkbox checked={offer.isOrderBump} onChange={(v) => patchOffer(offer.id, { isOrderBump: v })} />\n {t('courses.offers.bump') || 'Order bump'}\n </label>\n </div>\n </div>\n </div>\n ))}\n <Button variant=\"outline\" onClick={addOffer} className=\"w-full border-dashed\">\n <Plus className=\"h-4 w-4\" />{t('courses.offers.add') || 'Add offer'}\n </Button>\n </>\n )}\n </TabsContent>\n\n {/* ---- Área de membros ----------------------------------------- */}\n <TabsContent value=\"members\" className=\"mt-4 space-y-4\">\n <InfoNote icon={<Users className=\"h-4 w-4\" />}>\n {t('courses.editor.membersHelp') || 'Buyers are enrolled automatically through orders and get access to all of this course’s content.'}\n </InfoNote>\n\n {/* Enrolled students for THIS course (the actual \"área de membros\"). */}\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {(t('courses.editor.enrolledStudents') || 'Enrolled students')} ({students.length})\n </p>\n {students.length === 0 ? (\n <EmptyState\n icon={<Users className=\"h-5 w-5\" />}\n title={t('courses.editor.membersEmpty') || 'No students yet'}\n description={t('courses.editor.membersEmptyHint') || 'Buyers are enrolled here automatically after a paid order.'}\n />\n ) : (\n <div className=\"divide-y divide-border overflow-hidden rounded-card border border-border bg-card\">\n {students.map((s) => (\n <div key={s.key} className=\"flex items-center gap-3 px-4 py-3\">\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-semibold uppercase text-muted-foreground\" aria-hidden>\n {(s.name || s.email || '?').charAt(0)}\n </span>\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate font-medium text-foreground\">{s.name}</span>\n {s.email && <span className=\"truncate text-xs text-muted-foreground\">{s.email}</span>}\n </span>\n {s.since && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {new Date(s.since).toLocaleDateString()}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Which offers grant access — kept as secondary context. */}\n {offers.length > 0 && (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {t('courses.editor.accessUnlockedBy') || 'Access is unlocked by'}\n </p>\n <div className=\"divide-y divide-border overflow-hidden rounded-card border border-border bg-card\">\n {offers.map((offer) => (\n <div key={offer.id} className=\"flex items-center gap-3 px-4 py-3\">\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground\" aria-hidden>\n <Lock className=\"h-4 w-4\" />\n </span>\n <span className=\"min-w-0 flex-1 truncate font-medium text-foreground\">{offer.name}</span>\n <span className=\"shrink-0 text-sm tabular-nums text-muted-foreground\">{formatCurrency(offer.price, offer.currency)}</span>\n </div>\n ))}\n </div>\n </div>\n )}\n </TabsContent>\n </Tabs>\n\n <ConfirmDialog\n open={pendingDelete !== null}\n variant=\"destructive\"\n title={pendingDelete?.kind === 'module'\n ? (t('courses.editor.deleteModuleConfirm') || 'Delete this module?')\n : (t('courses.editor.deleteLessonConfirm') || 'Remove this lesson?')}\n description={pendingDelete?.kind === 'module'\n ? (t('courses.editor.deleteModuleConfirmBody') || 'Its lessons will be removed too. This cannot be undone.')\n : (t('courses.editor.deleteLessonConfirmBody') || 'This cannot be undone.')}\n confirmLabel={t('courses.editor.confirmDelete') || 'Delete'}\n cancelLabel={t('courses.editor.cancel') || 'Cancel'}\n onConfirm={confirmDelete}\n onCancel={() => setPendingDelete(null)}\n />\n </div>\n )\n}\nCourseEditorPage.displayName = 'CourseEditorPage'\n\n// ===========================================================================\n// Curriculum tree builder (module → lesson), Kiwify/Hotmart style.\n// ===========================================================================\n\ninterface CurriculumBuilderProps {\n t: TFn\n modules: Module[]\n lessons: Lesson[]\n autoFocusId: string | null\n onAutoFocused: () => void\n onAddModule: () => void\n onRenameModule: (moduleId: string, title: string) => void\n onAddLesson: (moduleId: string) => void\n onPatchLesson: (lessonId: string, patch: Partial<Lesson>) => void\n onRequestDelete: (kind: 'module' | 'lesson', id: string) => void\n onReorderModules: (orderedIds: string[]) => void\n onReorderLessons: (moduleId: string, orderedIds: string[]) => void\n}\n\n/** Human-friendly total duration, e.g. \"8 min\" or \"1 h 20 min\". */\nfunction formatDuration(sec: number, t: TFn): string {\n const min = Math.max(0, Math.round(sec / 60))\n const mLabel = t('courses.editor.minShort') || 'min'\n if (min < 60) return `${min} ${mLabel}`\n const h = Math.floor(min / 60)\n const rem = min % 60\n const hLabel = t('courses.editor.hourShort') || 'h'\n return rem ? `${h} ${hLabel} ${rem} ${mLabel}` : `${h} ${hLabel}`\n}\n\nfunction CurriculumBuilder({\n t, modules, lessons, autoFocusId, onAutoFocused,\n onAddModule, onRenameModule, onAddLesson, onPatchLesson,\n onRequestDelete, onReorderModules, onReorderLessons,\n}: CurriculumBuilderProps) {\n // Track only the *collapsed* modules so freshly-created ones default to open.\n const [collapsed, setCollapsed] = React.useState<Set<string>>(new Set())\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n )\n\n function toggleModule(id: string) {\n setCollapsed((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }\n\n function handleModuleDragEnd(e: DragEndEvent) {\n const { active, over } = e\n if (!over || active.id === over.id) return\n const ids = modules.map((m) => m.id)\n const from = ids.indexOf(String(active.id))\n const to = ids.indexOf(String(over.id))\n if (from < 0 || to < 0) return\n onReorderModules(arrayMove(ids, from, to))\n }\n\n if (modules.length === 0) {\n return (\n <div className=\"space-y-4\">\n <AutosaveHint t={t} />\n <EmptyState\n icon={<Layers className=\"h-5 w-5\" />}\n title={t('courses.editor.modulesEmpty') || 'No modules yet'}\n description={t('courses.editor.modulesEmptyHint') || 'Create a module to start organizing your lessons.'}\n action={<Button onClick={onAddModule}><Plus className=\"h-4 w-4\" />{t('courses.editor.firstModule') || 'Create first module'}</Button>}\n />\n </div>\n )\n }\n\n const totalLessons = lessons.length\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <AutosaveHint t={t} />\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {modules.length} {modules.length === 1 ? (t('courses.editor.moduleLabel') || 'module') : (t('courses.editor.moduleLabelPlural') || 'modules')}\n {' · '}\n {totalLessons} {totalLessons === 1 ? (t('courses.editor.lessonUnitOne') || 'lesson') : (t('courses.editor.lessonUnitOther') || 'lessons')}\n </span>\n </div>\n\n <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleModuleDragEnd}>\n <SortableContext items={modules.map((m) => m.id)} strategy={verticalListSortingStrategy}>\n <div className=\"space-y-3\">\n {modules.map((mod, i) => (\n <SortableModuleCard\n key={mod.id}\n t={t}\n index={i}\n mod={mod}\n lessons={lessons.filter((l) => l.moduleId === mod.id)}\n expanded={!collapsed.has(mod.id)}\n onToggle={() => toggleModule(mod.id)}\n autoFocusId={autoFocusId}\n onAutoFocused={onAutoFocused}\n onRenameModule={onRenameModule}\n onAddLesson={onAddLesson}\n onPatchLesson={onPatchLesson}\n onRequestDelete={onRequestDelete}\n onReorderLessons={onReorderLessons}\n />\n ))}\n </div>\n </SortableContext>\n </DndContext>\n\n <Button variant=\"outline\" onClick={onAddModule} className=\"w-full border-dashed\">\n <Plus className=\"h-4 w-4\" />{t('courses.editor.newModule') || 'New module'}\n </Button>\n </div>\n )\n}\n\ninterface SortableModuleCardProps {\n t: TFn\n index: number\n mod: Module\n lessons: Lesson[]\n expanded: boolean\n onToggle: () => void\n autoFocusId: string | null\n onAutoFocused: () => void\n onRenameModule: (moduleId: string, title: string) => void\n onAddLesson: (moduleId: string) => void\n onPatchLesson: (lessonId: string, patch: Partial<Lesson>) => void\n onRequestDelete: (kind: 'module' | 'lesson', id: string) => void\n onReorderLessons: (moduleId: string, orderedIds: string[]) => void\n}\n\nfunction SortableModuleCard({\n t, index, mod, lessons, expanded, onToggle, autoFocusId, onAutoFocused,\n onRenameModule, onAddLesson, onPatchLesson, onRequestDelete, onReorderLessons,\n}: SortableModuleCardProps) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: mod.id })\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n )\n const style: React.CSSProperties = {\n transform: CSS.Transform.toString(transform),\n transition,\n opacity: isDragging ? 0.6 : 1,\n zIndex: isDragging ? 20 : undefined,\n }\n\n const count = lessons.length\n const totalSec = lessons.reduce((s, l) => s + (l.durationSec || 0), 0)\n\n function handleLessonDragEnd(e: DragEndEvent) {\n const { active, over } = e\n if (!over || active.id === over.id) return\n const ids = lessons.map((l) => l.id)\n const from = ids.indexOf(String(active.id))\n const to = ids.indexOf(String(over.id))\n if (from < 0 || to < 0) return\n onReorderLessons(mod.id, arrayMove(ids, from, to))\n }\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className=\"overflow-hidden rounded-card border border-border bg-card shadow-sm\"\n >\n {/* Module header */}\n <div className=\"flex items-center gap-1.5 px-2 py-2 sm:gap-2 sm:px-3\">\n <Button variant=\"bare\" size=\"bare\"\n {...attributes}\n {...listeners}\n className=\"hidden h-8 w-6 shrink-0 cursor-grab touch-none items-center justify-center rounded-md text-muted-foreground/40 transition-colors hover:text-muted-foreground active:cursor-grabbing sm:flex\"\n aria-label={t('courses.editor.dragToReorder') || 'Drag to reorder'}\n >\n <GripVertical className=\"h-4 w-4\" />\n </Button>\n\n <Button variant=\"bare\" size=\"bare\"\n onClick={onToggle}\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\"\n aria-label={expanded ? (t('courses.editor.collapse') || 'Collapse') : (t('courses.editor.expand') || 'Expand')}\n aria-expanded={expanded}\n >\n <ChevronDown className={'h-4 w-4 transition-transform ' + (expanded ? '' : '-rotate-90')} />\n </Button>\n\n <span className=\"hidden shrink-0 items-center rounded-md bg-muted px-2 py-1 text-xs font-semibold tabular-nums text-muted-foreground sm:inline-flex\">\n {String(index + 1).padStart(2, '0')}\n </span>\n\n <TitleField\n value={mod.title}\n autoFocus={autoFocusId === mod.id}\n onAutoFocused={onAutoFocused}\n onCommit={(v) => onRenameModule(mod.id, v)}\n placeholder={t('courses.editor.moduleTitle') || 'Module title'}\n ariaLabel={t('courses.editor.moduleTitle') || 'Module title'}\n className=\"text-sm font-semibold\"\n />\n\n <span className=\"hidden shrink-0 text-xs text-muted-foreground tabular-nums md:inline\">\n {count > 0\n ? `${count} ${count === 1 ? (t('courses.editor.lessonUnitOne') || 'lesson') : (t('courses.editor.lessonUnitOther') || 'lessons')} · ${formatDuration(totalSec, t)}`\n : (t('courses.editor.noLessons') || 'No lessons')}\n </span>\n\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => onRequestDelete('module', mod.id)}\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground/60 transition-colors hover:bg-destructive/10 hover:text-destructive\"\n aria-label={t('courses.editor.deleteModule') || 'Delete module'}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {/* Module body */}\n {expanded && (\n <div className=\"border-t border-border/60 bg-muted/20 p-2 sm:p-3\">\n {count === 0 ? (\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => onAddLesson(mod.id)}\n className=\"flex w-full items-center justify-center gap-2 rounded-lg border border-dashed border-border px-3 py-4 text-sm text-muted-foreground transition-colors hover:border-primary/40 hover:bg-card hover:text-foreground font-normal\"\n >\n <Plus className=\"h-4 w-4\" /> {t('courses.editor.firstLesson') || 'Add the first lesson'}\n </Button>\n ) : (\n <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleLessonDragEnd}>\n <SortableContext items={lessons.map((l) => l.id)} strategy={verticalListSortingStrategy}>\n <div className=\"space-y-1.5\">\n {lessons.map((lesson) => (\n <SortableLessonRow\n key={lesson.id}\n t={t}\n lesson={lesson}\n autoFocusId={autoFocusId}\n onAutoFocused={onAutoFocused}\n onPatchLesson={onPatchLesson}\n onRequestDelete={onRequestDelete}\n />\n ))}\n </div>\n </SortableContext>\n </DndContext>\n )}\n\n {count > 0 && (\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => onAddLesson(mod.id)}\n className=\"mt-2 flex items-center gap-1.5 rounded-md px-2 py-1.5 text-sm font-medium text-primary transition-colors hover:bg-primary/10\"\n >\n <Plus className=\"h-4 w-4\" /> {t('courses.editor.newLesson') || 'New lesson'}\n </Button>\n )}\n </div>\n )}\n </div>\n )\n}\n\ninterface SortableLessonRowProps {\n t: TFn\n lesson: Lesson\n autoFocusId: string | null\n onAutoFocused: () => void\n onPatchLesson: (lessonId: string, patch: Partial<Lesson>) => void\n onRequestDelete: (kind: 'module' | 'lesson', id: string) => void\n}\n\nfunction SortableLessonRow({ t, lesson, autoFocusId, onAutoFocused, onPatchLesson, onRequestDelete }: SortableLessonRowProps) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: lesson.id })\n const [open, setOpen] = React.useState(false)\n // Local mirrors so the type icon + duration chip refresh on blur without a reload.\n const [videoUrl, setVideoUrl] = React.useState(lesson.videoUrl)\n const [durationSec, setDurationSec] = React.useState(lesson.durationSec)\n React.useEffect(() => { setVideoUrl(lesson.videoUrl) }, [lesson.videoUrl])\n React.useEffect(() => { setDurationSec(lesson.durationSec) }, [lesson.durationSec])\n\n const hasVideo = videoUrl.trim().length > 0\n const style: React.CSSProperties = {\n transform: CSS.Transform.toString(transform),\n transition,\n opacity: isDragging ? 0.6 : 1,\n zIndex: isDragging ? 10 : undefined,\n }\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={\n 'group rounded-card border bg-card transition-colors ' +\n (open ? 'border-border' : 'border-transparent hover:border-border')\n }\n >\n <div className=\"flex items-center gap-1.5 px-1.5 py-1.5 sm:gap-2 sm:px-2\">\n <Button variant=\"bare\" size=\"bare\"\n {...attributes}\n {...listeners}\n className=\"hidden h-8 w-5 shrink-0 cursor-grab touch-none items-center justify-center text-muted-foreground/40 transition-colors hover:text-muted-foreground active:cursor-grabbing sm:flex\"\n aria-label={t('courses.editor.dragToReorder') || 'Drag to reorder'}\n >\n <GripVertical className=\"h-4 w-4\" />\n </Button>\n\n <span\n className={\n 'flex h-8 w-8 shrink-0 items-center justify-center rounded-lg ' +\n (hasVideo ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground')\n }\n aria-hidden\n >\n {hasVideo ? <Video className=\"h-4 w-4\" /> : <FileText className=\"h-4 w-4\" />}\n </span>\n\n <TitleField\n value={lesson.title}\n autoFocus={autoFocusId === lesson.id}\n onAutoFocused={onAutoFocused}\n onCommit={(v) => onPatchLesson(lesson.id, { title: v })}\n placeholder={t('courses.editor.lessonTitle') || 'Lesson title'}\n ariaLabel={t('courses.editor.lessonTitle') || 'Lesson title'}\n className=\"text-sm\"\n />\n\n <span className=\"hidden shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs tabular-nums text-muted-foreground sm:inline-flex\">\n <Clock className=\"h-3 w-3\" />\n {Math.round(durationSec / 60)}\n {' '}\n {t('courses.editor.minShort') || 'min'}\n </span>\n\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => setOpen((v) => !v)}\n className={\n 'inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-1 text-xs font-medium transition-colors ' +\n (hasVideo\n ? 'border-border text-muted-foreground hover:text-foreground'\n : 'border-dashed border-border text-muted-foreground hover:border-primary/40 hover:text-foreground') +\n ' opacity-100 sm:opacity-0 sm:group-hover:opacity-100 ' + (open ? 'sm:opacity-100' : '')\n }\n aria-label={t('courses.editor.editLesson') || 'Edit lesson'}\n aria-expanded={open}\n >\n <PlayCircle className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">\n {hasVideo ? (t('courses.editor.videoSet') || 'Video') : (t('courses.editor.addVideo') || 'Add video')}\n </span>\n </Button>\n\n <Button variant=\"bare\" size=\"bare\"\n onClick={() => onRequestDelete('lesson', lesson.id)}\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground/60 transition-colors hover:bg-destructive/10 hover:text-destructive sm:opacity-0 sm:group-hover:opacity-100\"\n aria-label={t('courses.editor.deleteLesson') || 'Remove lesson'}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {open && (\n <div className=\"space-y-3 border-t border-border/60 px-3 py-3 sm:pl-11\">\n <div className=\"space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('courses.editor.videoUrlLabel') || 'Video URL'}\n </label>\n <Input\n defaultValue={lesson.videoUrl}\n placeholder={t('courses.editor.videoUrlPlaceholder') || 'Paste the video link (YouTube, Vimeo…)'}\n onBlur={(e) => { setVideoUrl(e.target.value); onPatchLesson(lesson.id, { videoUrl: e.target.value }) }}\n aria-label={t('courses.editor.videoUrlLabel') || 'Video URL'}\n />\n </div>\n <div className=\"max-w-[160px] space-y-1.5\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('courses.editor.lessonDuration') || 'Duration (min)'}\n </label>\n <Input\n type=\"number\"\n min={0}\n inputMode=\"numeric\"\n defaultValue={String(Math.round(lesson.durationSec / 60))}\n onBlur={(e) => { const s = (Number(e.target.value) || 0) * 60; setDurationSec(s); onPatchLesson(lesson.id, { durationSec: s }) }}\n aria-label={t('courses.editor.lessonDuration') || 'Duration (min)'}\n />\n </div>\n </div>\n )}\n </div>\n )\n}\n\n/**\n * Borderless, text-like inline title input. Uncontrolled (defaultValue + onBlur\n * autosave) so it plays nicely with the reload-after-mutation flow, and focuses\n * itself when it is the freshly-created item.\n */\nfunction TitleField({ value, autoFocus, onAutoFocused, onCommit, placeholder, ariaLabel, className }: {\n value: string\n autoFocus?: boolean\n onAutoFocused?: () => void\n onCommit: (v: string) => void\n placeholder?: string\n ariaLabel?: string\n className?: string\n}) {\n const ref = React.useRef<HTMLInputElement>(null)\n React.useEffect(() => {\n if (autoFocus && ref.current) {\n ref.current.focus()\n ref.current.select()\n onAutoFocused?.()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [autoFocus])\n return (\n <div className=\"min-w-0 flex-1\">\n <Input\n ref={ref}\n defaultValue={value}\n placeholder={placeholder}\n aria-label={ariaLabel}\n onBlur={(e) => onCommit(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') e.currentTarget.blur() }}\n className={\n 'h-auto rounded-md border-0 bg-transparent px-2 py-1.5 shadow-none transition-colors placeholder:text-muted-foreground/60 hover:bg-muted/60 focus:bg-background focus-visible:ring-offset-0 ' +\n (className ?? '')\n }\n />\n </div>\n )\n}\n\nfunction Field({ label, hint, children }: { label: string; hint?: string; children: React.ReactNode }) {\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <label className=\"text-sm font-medium text-foreground\">{label}</label>\n {hint && <span className=\"text-xs text-muted-foreground\">{hint}</span>}\n </div>\n {children}\n </div>\n )\n}\n\nfunction AutosaveHint({ t }: { t: (k: string) => string }) {\n return (\n <p className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <Check className=\"h-3.5 w-3.5 text-success\" />\n {t('courses.editor.autosaved') || 'Changes are saved automatically.'}\n </p>\n )\n}\n\nfunction EditorSkeleton() {\n return (\n <div className=\"mx-auto max-w-4xl p-6 md:p-8\">\n <Skeleton className=\"mb-4 h-4 w-28\" />\n <Skeleton className=\"mb-6 h-8 w-64\" />\n <Skeleton className=\"mb-6 h-10 w-full\" />\n <div className=\"space-y-4\">\n <Skeleton className=\"h-40 w-full rounded-xl\" />\n <Skeleton className=\"h-40 w-full rounded-xl\" />\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { navigateTo } from './chunk-4DMJIPDN.js';
|
|
2
|
+
import { EmptyState } from './chunk-U5LQDCGG.js';
|
|
3
|
+
import { formatDate } from './chunk-A4BEN6VV.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { useTranslation, formatCurrency } from '@fayz-ai/core';
|
|
6
|
+
import { OrderDetailSkeleton, PersonLink, OrderDetailView } from '@fayz-ai/admin';
|
|
7
|
+
import { getCoursesProvider } from '@fayz-ai/courses';
|
|
8
|
+
import { Button } from '@fayz-ai/ui';
|
|
9
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
var Page = ({ children }) => /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-6xl p-6 md:p-8", children });
|
|
12
|
+
var orderCache = /* @__PURE__ */ new Map();
|
|
13
|
+
function statusTone(s) {
|
|
14
|
+
if (s === "paid") return "success";
|
|
15
|
+
if (s === "pending") return "warning";
|
|
16
|
+
if (s === "refunded" || s === "chargeback") return "destructive";
|
|
17
|
+
return "muted";
|
|
18
|
+
}
|
|
19
|
+
function instTone(s) {
|
|
20
|
+
if (s === "paid") return "success";
|
|
21
|
+
if (s === "overdue") return "destructive";
|
|
22
|
+
return "warning";
|
|
23
|
+
}
|
|
24
|
+
function CourseOrderDetailView({ id, ordersRoute = "/courses/sales" }) {
|
|
25
|
+
const t = useTranslation();
|
|
26
|
+
const [order, setOrder] = React.useState(() => id ? orderCache.get(id) ?? null : null);
|
|
27
|
+
const [loading, setLoading] = React.useState(() => !(id && orderCache.has(id)));
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
let alive = true;
|
|
30
|
+
if (!id) {
|
|
31
|
+
setLoading(false);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const cached = orderCache.get(id);
|
|
35
|
+
if (cached) {
|
|
36
|
+
setOrder(cached);
|
|
37
|
+
setLoading(false);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
setLoading(true);
|
|
41
|
+
void getCoursesProvider().getOrder(id).then((o) => {
|
|
42
|
+
if (!alive) return;
|
|
43
|
+
if (o) orderCache.set(id, o);
|
|
44
|
+
setOrder(o);
|
|
45
|
+
setLoading(false);
|
|
46
|
+
});
|
|
47
|
+
return () => {
|
|
48
|
+
alive = false;
|
|
49
|
+
};
|
|
50
|
+
}, [id]);
|
|
51
|
+
const back = () => navigateTo(ordersRoute);
|
|
52
|
+
if (loading) return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(OrderDetailSkeleton, {}) });
|
|
53
|
+
if (!order) {
|
|
54
|
+
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(
|
|
55
|
+
EmptyState,
|
|
56
|
+
{
|
|
57
|
+
title: t("courses.order.notFound") || "Pedido n\xE3o encontrado",
|
|
58
|
+
description: "",
|
|
59
|
+
action: /* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", className: "text-sm text-primary underline font-normal", onClick: back, children: t("common.back") || "Voltar" })
|
|
60
|
+
}
|
|
61
|
+
) });
|
|
62
|
+
}
|
|
63
|
+
const cur = order.currency;
|
|
64
|
+
const installments = order.installments.map((m) => ({
|
|
65
|
+
number: m.installmentNumber,
|
|
66
|
+
amount: formatCurrency(m.amount, cur),
|
|
67
|
+
status: m.status,
|
|
68
|
+
statusTone: instTone(m.status),
|
|
69
|
+
dueDate: m.dueDate ? formatDate(m.dueDate) : null,
|
|
70
|
+
paymentDate: m.paymentDate ? formatDate(m.paymentDate) : null,
|
|
71
|
+
note: m.cardBrand ? `${m.cardBrand}${m.cardInstallments ? ` ${m.cardInstallments}x` : ""}` : null
|
|
72
|
+
}));
|
|
73
|
+
const data = {
|
|
74
|
+
title: `${t("courses.order.title") || "Pedido"} #${order.id.slice(0, 8)}`,
|
|
75
|
+
subtitle: formatDate(order.createdAt),
|
|
76
|
+
badges: [
|
|
77
|
+
{ label: t(`courses.financialStatus.${order.financialStatus}`) || order.financialStatus, tone: statusTone(order.financialStatus) },
|
|
78
|
+
...order.installmentCount && order.installmentCount > 1 ? [{ label: `${order.installmentCount}x`, tone: "muted" }] : []
|
|
79
|
+
],
|
|
80
|
+
customer: { name: order.customerName, email: order.customerEmail },
|
|
81
|
+
customerNode: /* @__PURE__ */ jsxs("div", { className: "space-y-1 text-sm", children: [
|
|
82
|
+
order.customerId ? /* @__PURE__ */ jsx(
|
|
83
|
+
PersonLink,
|
|
84
|
+
{
|
|
85
|
+
personId: order.customerId,
|
|
86
|
+
name: order.customerName ?? order.customerEmail ?? "Cliente",
|
|
87
|
+
className: "font-medium"
|
|
88
|
+
}
|
|
89
|
+
) : /* @__PURE__ */ jsx("p", { className: "font-medium", children: order.customerName ?? "\u2014" }),
|
|
90
|
+
order.customerEmail && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: order.customerEmail })
|
|
91
|
+
] }),
|
|
92
|
+
items: [{
|
|
93
|
+
name: order.courseTitle ?? "\u2014",
|
|
94
|
+
description: order.offerName,
|
|
95
|
+
quantity: 1,
|
|
96
|
+
unitPrice: formatCurrency(order.total, cur),
|
|
97
|
+
total: formatCurrency(order.total, cur)
|
|
98
|
+
}],
|
|
99
|
+
totals: [
|
|
100
|
+
{ label: "Total", value: formatCurrency(order.total, cur), strong: true },
|
|
101
|
+
...order.platformFee > 0 ? [{ label: "Taxa", value: `\u2212 ${formatCurrency(order.platformFee, cur)}`, muted: true }] : [],
|
|
102
|
+
{ label: "L\xEDquido", value: formatCurrency(order.netValue, cur) }
|
|
103
|
+
],
|
|
104
|
+
paymentMethod: order.paymentMethod ?? void 0,
|
|
105
|
+
receivable: {
|
|
106
|
+
rows: [
|
|
107
|
+
{ label: "Recebido", value: formatCurrency(order.paidAmount, cur) },
|
|
108
|
+
{ label: "Saldo", value: formatCurrency(order.balance, cur), strong: order.balance > 0 }
|
|
109
|
+
],
|
|
110
|
+
installments,
|
|
111
|
+
emptyLabel: t("courses.order.noInstallments") || "Sem parcelas."
|
|
112
|
+
},
|
|
113
|
+
onBack: back,
|
|
114
|
+
backLabel: t("courses.sales.title") || "Vendas"
|
|
115
|
+
};
|
|
116
|
+
return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(OrderDetailView, { ...data }) });
|
|
117
|
+
}
|
|
118
|
+
CourseOrderDetailView.displayName = "CourseOrderDetailView";
|
|
119
|
+
|
|
120
|
+
export { CourseOrderDetailView };
|
|
121
|
+
//# sourceMappingURL=CourseOrderDetailView-LWHDQNZ7.js.map
|
|
122
|
+
//# sourceMappingURL=CourseOrderDetailView-LWHDQNZ7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/CourseOrderDetailView.tsx"],"names":["SharedOrderDetailView"],"mappings":"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","file":"CourseOrderDetailView-LWHDQNZ7.js","sourcesContent":["import * as React from 'react'\nimport { useTranslation, formatCurrency } from '@fayz-ai/core'\nimport {\n OrderDetailView as SharedOrderDetailView, OrderDetailSkeleton, PersonLink,\n type OrderDetailData, type OrderDetailInstallment, type OrderDetailTone,\n} from '@fayz-ai/admin'\nimport { getCoursesProvider, type OrderDetail, type FinancialStatus } from '@fayz-ai/courses'\nimport { Button } from '@fayz-ai/ui'\nimport { EmptyState } from '../components/CommerceUI'\nimport { formatDate } from '../lib/format'\nimport { navigateTo } from '../lib/nav'\n\nconst Page = ({ children }: { children: React.ReactNode }) => (\n <div className=\"mx-auto max-w-6xl p-6 md:p-8\">{children}</div>\n)\n\n// Cache por id (fora do componente) — trocar de aba remonta a view; sem cache\n// isso refaz o getOrder (skeleton + request) toda vez. Cache-first evita o refetch.\nconst orderCache = new Map<string, OrderDetail>()\n\nfunction statusTone(s: FinancialStatus): OrderDetailTone {\n if (s === 'paid') return 'success'\n if (s === 'pending') return 'warning'\n if (s === 'refunded' || s === 'chargeback') return 'destructive'\n return 'muted'\n}\nfunction instTone(s: string): OrderDetailTone {\n if (s === 'paid') return 'success'\n if (s === 'overdue') return 'destructive'\n return 'warning'\n}\n\n/** Order detail (`${ordersRoute}/:id`). Loads the canonical order and renders the\n * SHARED archetype OrderDetailView (@fayz-ai/admin) — same component the shop uses. */\nexport function CourseOrderDetailView({ id, ordersRoute = '/courses/sales' }: { id?: string; ordersRoute?: string }) {\n const t = useTranslation()\n const [order, setOrder] = React.useState<OrderDetail | null>(() => (id ? orderCache.get(id) ?? null : null))\n const [loading, setLoading] = React.useState(() => !(id && orderCache.has(id)))\n\n React.useEffect(() => {\n let alive = true\n if (!id) { setLoading(false); return }\n const cached = orderCache.get(id)\n if (cached) { setOrder(cached); setLoading(false); return } // cache hit → sem request\n setLoading(true)\n void getCoursesProvider().getOrder(id).then((o) => {\n if (!alive) return\n if (o) orderCache.set(id, o)\n setOrder(o); setLoading(false)\n })\n return () => { alive = false }\n }, [id])\n\n // A lista de onde este pedido veio — não '/courses/sales' fixo: o host pode\n // ter reposicionado a tela (routes.orders), e voltar para o caminho antigo só\n // funcionava de carona no redirecionamento.\n const back = () => navigateTo(ordersRoute)\n\n if (loading) return <Page><OrderDetailSkeleton /></Page>\n if (!order) {\n return (\n <Page>\n <EmptyState\n title={t('courses.order.notFound') || 'Pedido não encontrado'}\n description=\"\"\n action={<Button variant=\"bare\" size=\"bare\" className=\"text-sm text-primary underline font-normal\" onClick={back}>{t('common.back') || 'Voltar'}</Button>}\n />\n </Page>\n )\n }\n\n const cur = order.currency\n const installments: OrderDetailInstallment[] = order.installments.map((m) => ({\n number: m.installmentNumber,\n amount: formatCurrency(m.amount, cur),\n status: m.status,\n statusTone: instTone(m.status),\n dueDate: m.dueDate ? formatDate(m.dueDate) : null,\n paymentDate: m.paymentDate ? formatDate(m.paymentDate) : null,\n note: m.cardBrand ? `${m.cardBrand}${m.cardInstallments ? ` ${m.cardInstallments}x` : ''}` : null,\n }))\n\n const data: OrderDetailData = {\n title: `${t('courses.order.title') || 'Pedido'} #${order.id.slice(0, 8)}`,\n subtitle: formatDate(order.createdAt),\n badges: [\n { label: t(`courses.financialStatus.${order.financialStatus}`) || order.financialStatus, tone: statusTone(order.financialStatus) },\n ...(order.installmentCount && order.installmentCount > 1 ? [{ label: `${order.installmentCount}x`, tone: 'muted' as OrderDetailTone }] : []),\n ],\n customer: { name: order.customerName, email: order.customerEmail },\n customerNode: (\n <div className=\"space-y-1 text-sm\">\n {order.customerId ? (\n <PersonLink\n personId={order.customerId}\n name={order.customerName ?? order.customerEmail ?? 'Cliente'}\n className=\"font-medium\"\n />\n ) : (\n <p className=\"font-medium\">{order.customerName ?? '—'}</p>\n )}\n {order.customerEmail && <p className=\"text-muted-foreground\">{order.customerEmail}</p>}\n </div>\n ),\n items: [{\n name: order.courseTitle ?? '—',\n description: order.offerName,\n quantity: 1,\n unitPrice: formatCurrency(order.total, cur),\n total: formatCurrency(order.total, cur),\n }],\n totals: [\n { label: 'Total', value: formatCurrency(order.total, cur), strong: true },\n ...(order.platformFee > 0 ? [{ label: 'Taxa', value: `− ${formatCurrency(order.platformFee, cur)}`, muted: true }] : []),\n { label: 'Líquido', value: formatCurrency(order.netValue, cur) },\n ],\n paymentMethod: order.paymentMethod ?? undefined,\n receivable: {\n rows: [\n { label: 'Recebido', value: formatCurrency(order.paidAmount, cur) },\n { label: 'Saldo', value: formatCurrency(order.balance, cur), strong: order.balance > 0 },\n ],\n installments,\n emptyLabel: t('courses.order.noInstallments') || 'Sem parcelas.',\n },\n onBack: back,\n backLabel: t('courses.sales.title') || 'Vendas',\n }\n\n return (\n <Page>\n <SharedOrderDetailView {...data} />\n </Page>\n )\n}\nCourseOrderDetailView.displayName = 'CourseOrderDetailView'\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { navigateTo } from './chunk-4DMJIPDN.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useModuleLayout, PageHeaderActions, Button, Badge, Skeleton } from '@fayz-ai/ui';
|
|
4
|
+
import { useTranslation } from '@fayz-ai/core';
|
|
5
|
+
import { getCoursesProvider } from '@fayz-ai/courses';
|
|
6
|
+
import { useLimitGuard, usePermissionOptional, PermissionGate, invalidateLimit } from '@fayz-ai/admin';
|
|
7
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function statusVariant(status) {
|
|
10
|
+
if (status === "published") return "success";
|
|
11
|
+
if (status === "archived") return "outline";
|
|
12
|
+
return "secondary";
|
|
13
|
+
}
|
|
14
|
+
function CoursesListPage() {
|
|
15
|
+
const t = useTranslation();
|
|
16
|
+
const shellOwnsHeader = useModuleLayout() === "tabs";
|
|
17
|
+
const [courses, setCourses] = React.useState(null);
|
|
18
|
+
const [creating, setCreating] = React.useState(false);
|
|
19
|
+
const guardCourses = useLimitGuard("courses");
|
|
20
|
+
const can = usePermissionOptional();
|
|
21
|
+
const load = React.useCallback(async () => {
|
|
22
|
+
setCourses(await getCoursesProvider().listCourses());
|
|
23
|
+
}, []);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
void load();
|
|
26
|
+
}, [load]);
|
|
27
|
+
async function onCreate() {
|
|
28
|
+
if (!can("courses", "create")) return;
|
|
29
|
+
if (await guardCourses() === "blocked") return;
|
|
30
|
+
setCreating(true);
|
|
31
|
+
try {
|
|
32
|
+
const course = await getCoursesProvider().createCourse({
|
|
33
|
+
title: t("courses.editor.untitledCourse") || "Untitled course",
|
|
34
|
+
status: "draft"
|
|
35
|
+
});
|
|
36
|
+
invalidateLimit("courses");
|
|
37
|
+
navigateTo(`/courses/${course.id}`);
|
|
38
|
+
} finally {
|
|
39
|
+
setCreating(false);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-6xl p-6 md:p-8", children: [
|
|
43
|
+
shellOwnsHeader ? /* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsx(PermissionGate, { feature: "courses", action: "create", children: /* @__PURE__ */ jsx(Button, { onClick: onCreate, disabled: creating, children: t("courses.new") || "New course" }) }) }) : /* @__PURE__ */ jsxs("div", { className: "mb-6 flex items-center justify-between", children: [
|
|
44
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
45
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-foreground", children: t("courses.title") || "Courses" }),
|
|
46
|
+
courses && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: (t("courses.count") || "{count} courses").replace("{count}", String(courses.length)) })
|
|
47
|
+
] }),
|
|
48
|
+
/* @__PURE__ */ jsx(PermissionGate, { feature: "courses", action: "create", children: /* @__PURE__ */ jsx(Button, { onClick: onCreate, disabled: creating, children: t("courses.new") || "New course" }) })
|
|
49
|
+
] }),
|
|
50
|
+
courses && courses.length === 0 && /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-dashed border-border p-12 text-center text-muted-foreground", children: t("courses.empty") || "No courses yet. Create your first one." }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: [
|
|
52
|
+
courses === null && Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(CourseCardSkeleton, {}, i)),
|
|
53
|
+
courses?.map((course) => /* @__PURE__ */ jsxs(
|
|
54
|
+
Button,
|
|
55
|
+
{
|
|
56
|
+
variant: "bare",
|
|
57
|
+
size: "bare",
|
|
58
|
+
onClick: () => navigateTo(`/courses/${course.id}`),
|
|
59
|
+
className: "group overflow-hidden rounded-card border border-border bg-card text-left transition hover:border-primary hover:shadow-md block whitespace-normal font-normal",
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ jsx("div", { className: "aspect-video w-full overflow-hidden bg-muted", children: course.thumbnailUrl && // eslint-disable-next-line @next/next/no-img-element
|
|
62
|
+
/* @__PURE__ */ jsx("img", { src: course.thumbnailUrl, alt: "", className: "h-full w-full object-cover" }) }),
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2 p-4", children: [
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
65
|
+
/* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground line-clamp-2", children: course.title }),
|
|
66
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant(course.status), children: t(`courses.status.${course.status}`) || course.status })
|
|
67
|
+
] }),
|
|
68
|
+
course.subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground line-clamp-2", children: course.subtitle }),
|
|
69
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: course.price > 0 ? `${course.currency} ${course.price.toFixed(2)}` : "\u2014" })
|
|
70
|
+
] })
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
course.id
|
|
74
|
+
))
|
|
75
|
+
] })
|
|
76
|
+
] });
|
|
77
|
+
}
|
|
78
|
+
CoursesListPage.displayName = "CoursesListPage";
|
|
79
|
+
function CourseCardSkeleton() {
|
|
80
|
+
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-card border border-border bg-card", children: [
|
|
81
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "aspect-video w-full rounded-none" }),
|
|
82
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3 p-4", children: [
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
84
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-2/3" }),
|
|
85
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16 rounded-full" })
|
|
86
|
+
] }),
|
|
87
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" }),
|
|
88
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-20" })
|
|
89
|
+
] })
|
|
90
|
+
] });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { CoursesListPage };
|
|
94
|
+
//# sourceMappingURL=CoursesListPage-WDG3YHF4.js.map
|
|
95
|
+
//# sourceMappingURL=CoursesListPage-WDG3YHF4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/views/CoursesListPage.tsx"],"names":[],"mappings":";;;;;;;;AAOA,SAAS,cAAc,MAAA,EAA+D;AACpF,EAAA,IAAI,MAAA,KAAW,aAAa,OAAO,SAAA;AACnC,EAAA,IAAI,MAAA,KAAW,YAAY,OAAO,SAAA;AAClC,EAAA,OAAO,WAAA;AACT;AAEO,SAAS,eAAA,GAAkB;AAChC,EAAA,MAAM,IAAI,cAAA,EAAe;AAGzB,EAAA,MAAM,eAAA,GAAkB,iBAAgB,KAAM,MAAA;AAC9C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAU,eAA0B,IAAI,CAAA;AAClE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAS,KAAK,CAAA;AACpD,EAAA,MAAM,YAAA,GAAe,cAAc,SAAS,CAAA;AAC5C,EAAA,MAAM,MAAM,qBAAA,EAAsB;AAElC,EAAA,MAAM,IAAA,GAAa,kBAAY,YAAY;AACzC,IAAA,UAAA,CAAW,MAAM,kBAAA,EAAmB,CAAE,WAAA,EAAa,CAAA;AAAA,EACrD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAM,gBAAU,MAAM;AACpB,IAAA,KAAK,IAAA,EAAK;AAAA,EACZ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,eAAe,QAAA,GAAW;AAExB,IAAA,IAAI,CAAC,GAAA,CAAI,SAAA,EAAW,QAAQ,CAAA,EAAG;AAG/B,IAAA,IAAK,MAAM,YAAA,EAAa,KAAO,SAAA,EAAW;AAC1C,IAAA,WAAA,CAAY,IAAI,CAAA;AAChB,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,kBAAA,EAAmB,CAAE,YAAA,CAAa;AAAA,QACrD,KAAA,EAAO,CAAA,CAAE,+BAA+B,CAAA,IAAK,iBAAA;AAAA,QAC7C,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,eAAA,CAAgB,SAAS,CAAA;AACzB,MAAA,UAAA,CAAW,CAAA,SAAA,EAAY,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AAAA,IACpC,CAAA,SAAE;AACA,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACnB;AAAA,EACF;AAEA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACZ,QAAA,EAAA;AAAA,IAAA,eAAA,mBACC,GAAA,CAAC,iBAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAQ,WAAU,MAAA,EAAO,QAAA,EACvC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAS,QAAA,EAAU,UAAU,QAAA,EAClC,QAAA,EAAA,CAAA,CAAE,aAAa,CAAA,IAAK,YAAA,EACvB,CAAA,EACF,GACF,CAAA,mBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wCAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAG,SAAA,EAAU,oCAAA,EAAsC,QAAA,EAAA,CAAA,CAAE,eAAe,KAAK,SAAA,EAAU,CAAA;AAAA,QACnF,OAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCACT,QAAA,EAAA,CAAA,CAAA,CAAE,eAAe,CAAA,IAAK,iBAAA,EAAmB,QAAQ,SAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAC,CAAA,EACtF;AAAA,OAAA,EAEJ,CAAA;AAAA,0BACC,cAAA,EAAA,EAAe,OAAA,EAAQ,SAAA,EAAU,MAAA,EAAO,UACvC,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAS,QAAA,EAAU,UAAU,QAAA,EAClC,QAAA,EAAA,CAAA,CAAE,aAAa,CAAA,IAAK,cACvB,CAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,IAGD,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,CAAA,oBAC7B,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sFAAA,EACZ,QAAA,EAAA,CAAA,CAAE,eAAe,CAAA,IAAK,wCAAA,EACzB,CAAA;AAAA,oBAGF,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sDAAA,EACZ,QAAA,EAAA;AAAA,MAAA,OAAA,KAAY,IAAA,IACX,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,CAAA,EAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBAAM,GAAA,CAAC,kBAAA,EAAA,EAAA,EAAwB,CAAG,CAAE,CAAA;AAAA,MACvE,OAAA,EAAS,GAAA,CAAI,CAAC,MAAA,qBACb,IAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAAO,OAAA,EAAQ,MAAA;AAAA,UAAO,IAAA,EAAK,MAAA;AAAA,UAE1B,SAAS,MAAM,UAAA,CAAW,CAAA,SAAA,EAAY,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AAAA,UACjD,SAAA,EAAU,+JAAA;AAAA,UAEV,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8CAAA,EACZ,QAAA,EAAA,MAAA,CAAO,YAAA;AAAA,4BAEN,GAAA,CAAC,SAAI,GAAA,EAAK,MAAA,CAAO,cAAc,GAAA,EAAI,EAAA,EAAG,SAAA,EAAU,4BAAA,EAA6B,CAAA,EAEjF,CAAA;AAAA,4BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wCAAA,EACb,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4CAAA,EAA8C,QAAA,EAAA,MAAA,CAAO,KAAA,EAAM,CAAA;AAAA,gCACzE,GAAA,CAAC,KAAA,EAAA,EAAM,OAAA,EAAS,aAAA,CAAc,OAAO,MAAM,CAAA,EACxC,QAAA,EAAA,CAAA,CAAE,CAAA,eAAA,EAAkB,MAAA,CAAO,MAAM,CAAA,CAAE,CAAA,IAAK,OAAO,MAAA,EAClD;AAAA,eAAA,EACF,CAAA;AAAA,cACC,OAAO,QAAA,oBACN,GAAA,CAAC,OAAE,SAAA,EAAU,4CAAA,EAA8C,iBAAO,QAAA,EAAS,CAAA;AAAA,kCAE5E,GAAA,EAAA,EAAE,SAAA,EAAU,qCAAA,EACV,QAAA,EAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,CAAA,EAAG,MAAA,CAAO,QAAQ,IAAI,MAAA,CAAO,KAAA,CAAM,QAAQ,CAAC,CAAC,KAAK,QAAA,EACxE;AAAA,aAAA,EACF;AAAA;AAAA,SAAA;AAAA,QAvBK,MAAA,CAAO;AAAA,OAyBf;AAAA,KAAA,EACH;AAAA,GAAA,EACF,CAAA;AAEJ;AACA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAG9B,SAAS,kBAAA,GAAqB;AAC5B,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2DAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,WAAU,kCAAA,EAAmC,CAAA;AAAA,oBACvD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wCAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,WAAU,WAAA,EAAY,CAAA;AAAA,wBAChC,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,uBAAA,EAAwB;AAAA,OAAA,EAC9C,CAAA;AAAA,sBACA,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,YAAA,EAAa,CAAA;AAAA,sBACjC,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,UAAA,EAAW;AAAA,KAAA,EACjC;AAAA,GAAA,EACF,CAAA;AAEJ","file":"CoursesListPage-WDG3YHF4.js","sourcesContent":["import * as React from 'react'\nimport { Button, Badge, PageHeaderActions, useModuleLayout, Skeleton } from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport { getCoursesProvider, type Course } from '@fayz-ai/courses'\nimport { useLimitGuard, invalidateLimit, PermissionGate, usePermissionOptional } from '@fayz-ai/admin'\nimport { navigateTo } from '../lib/nav'\n\nfunction statusVariant(status: Course['status']): 'success' | 'secondary' | 'outline' {\n if (status === 'published') return 'success'\n if (status === 'archived') return 'outline'\n return 'secondary'\n}\n\nexport function CoursesListPage() {\n const t = useTranslation()\n // When the app shell owns the page header (sidebar/GHL-style layouts), don't\n // render our own title — and project the action button into the top bar.\n const shellOwnsHeader = useModuleLayout() === 'tabs'\n const [courses, setCourses] = React.useState<Course[] | null>(null)\n const [creating, setCreating] = React.useState(false)\n const guardCourses = useLimitGuard('courses')\n const can = usePermissionOptional()\n\n const load = React.useCallback(async () => {\n setCourses(await getCoursesProvider().listCourses())\n }, [])\n\n React.useEffect(() => {\n void load()\n }, [load])\n\n async function onCreate() {\n // Defense in depth: never create without the role's `create` action.\n if (!can('courses', 'create')) return\n // Plan quantity guard (client-side, before the provider call). Opens the\n // global UpgradeModal and aborts when the plan's course cap is reached.\n if ((await guardCourses()) === 'blocked') return\n setCreating(true)\n try {\n const course = await getCoursesProvider().createCourse({\n title: t('courses.editor.untitledCourse') || 'Untitled course',\n status: 'draft',\n })\n invalidateLimit('courses')\n navigateTo(`/courses/${course.id}`)\n } finally {\n setCreating(false)\n }\n }\n\n return (\n <div className=\"mx-auto max-w-6xl p-6 md:p-8\">\n {shellOwnsHeader ? (\n <PageHeaderActions>\n <PermissionGate feature=\"courses\" action=\"create\">\n <Button onClick={onCreate} disabled={creating}>\n {t('courses.new') || 'New course'}\n </Button>\n </PermissionGate>\n </PageHeaderActions>\n ) : (\n <div className=\"mb-6 flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-foreground\">{t('courses.title') || 'Courses'}</h1>\n {courses && (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {(t('courses.count') || '{count} courses').replace('{count}', String(courses.length))}\n </p>\n )}\n </div>\n <PermissionGate feature=\"courses\" action=\"create\">\n <Button onClick={onCreate} disabled={creating}>\n {t('courses.new') || 'New course'}\n </Button>\n </PermissionGate>\n </div>\n )}\n\n {courses && courses.length === 0 && (\n <div className=\"rounded-xl border border-dashed border-border p-12 text-center text-muted-foreground\">\n {t('courses.empty') || 'No courses yet. Create your first one.'}\n </div>\n )}\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {courses === null &&\n Array.from({ length: 6 }).map((_, i) => <CourseCardSkeleton key={i} />)}\n {courses?.map((course) => (\n <Button variant=\"bare\" size=\"bare\"\n key={course.id}\n onClick={() => navigateTo(`/courses/${course.id}`)}\n className=\"group overflow-hidden rounded-card border border-border bg-card text-left transition hover:border-primary hover:shadow-md block whitespace-normal font-normal\"\n >\n <div className=\"aspect-video w-full overflow-hidden bg-muted\">\n {course.thumbnailUrl && (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={course.thumbnailUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n )}\n </div>\n <div className=\"space-y-2 p-4\">\n <div className=\"flex items-start justify-between gap-2\">\n <h3 className=\"font-semibold text-foreground line-clamp-2\">{course.title}</h3>\n <Badge variant={statusVariant(course.status)}>\n {t(`courses.status.${course.status}`) || course.status}\n </Badge>\n </div>\n {course.subtitle && (\n <p className=\"text-sm text-muted-foreground line-clamp-2\">{course.subtitle}</p>\n )}\n <p className=\"text-sm font-medium text-foreground\">\n {course.price > 0 ? `${course.currency} ${course.price.toFixed(2)}` : '—'}\n </p>\n </div>\n </Button>\n ))}\n </div>\n </div>\n )\n}\nCoursesListPage.displayName = 'CoursesListPage'\n\n/** Loading placeholder mirroring the course card layout. */\nfunction CourseCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-card border border-border bg-card\">\n <Skeleton className=\"aspect-video w-full rounded-none\" />\n <div className=\"space-y-3 p-4\">\n <div className=\"flex items-start justify-between gap-2\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"h-5 w-16 rounded-full\" />\n </div>\n <Skeleton className=\"h-3 w-full\" />\n <Skeleton className=\"h-4 w-20\" />\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useTranslation } from '@fayz-ai/core';
|
|
3
|
+
import { PluginSettingsPanel, SettingsGroup, SelectRow, ToggleRow } from '@fayz-ai/admin';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/settings/CoursesSettings.tsx
|
|
7
|
+
function CoursesGeneralSettings() {
|
|
8
|
+
const t = useTranslation();
|
|
9
|
+
const [currency, setCurrency] = React.useState("BRL");
|
|
10
|
+
const [methods, setMethods] = React.useState({ card: true, pix: true, boleto: true });
|
|
11
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
12
|
+
/* @__PURE__ */ jsx(
|
|
13
|
+
SettingsGroup,
|
|
14
|
+
{
|
|
15
|
+
title: t("courses.settings.payments") || "Payments",
|
|
16
|
+
description: t("courses.settings.paymentsHelp") || "Connect Stripe in the Integrations tab; the platform fee applies automatically.",
|
|
17
|
+
children: /* @__PURE__ */ jsx(
|
|
18
|
+
SelectRow,
|
|
19
|
+
{
|
|
20
|
+
label: t("courses.settings.currency") || "Default currency",
|
|
21
|
+
value: currency,
|
|
22
|
+
onChange: setCurrency,
|
|
23
|
+
options: [
|
|
24
|
+
{ value: "BRL", label: "BRL (R$)" },
|
|
25
|
+
{ value: "USD", label: "USD ($)" },
|
|
26
|
+
{ value: "EUR", label: "EUR (\u20AC)" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ jsxs(SettingsGroup, { title: t("courses.settings.methods") || "Payment methods", children: [
|
|
33
|
+
/* @__PURE__ */ jsx(ToggleRow, { label: t("courses.editor.payCard") || "Credit card", checked: methods.card, onChange: (v) => setMethods((m) => ({ ...m, card: v })) }),
|
|
34
|
+
/* @__PURE__ */ jsx(ToggleRow, { label: t("courses.editor.payPix") || "Pix", checked: methods.pix, onChange: (v) => setMethods((m) => ({ ...m, pix: v })) }),
|
|
35
|
+
/* @__PURE__ */ jsx(ToggleRow, { label: t("courses.editor.payBoleto") || "Boleto", checked: methods.boleto, onChange: (v) => setMethods((m) => ({ ...m, boleto: v })) })
|
|
36
|
+
] })
|
|
37
|
+
] });
|
|
38
|
+
}
|
|
39
|
+
CoursesGeneralSettings.displayName = "CoursesGeneralSettings";
|
|
40
|
+
function CoursesSettingsTab() {
|
|
41
|
+
const t = useTranslation();
|
|
42
|
+
return /* @__PURE__ */ jsx(
|
|
43
|
+
PluginSettingsPanel,
|
|
44
|
+
{
|
|
45
|
+
title: t("courses.settings.title") || "Course settings",
|
|
46
|
+
generalSettings: /* @__PURE__ */ jsx(CoursesGeneralSettings, {}),
|
|
47
|
+
hostPluginId: "courses",
|
|
48
|
+
routeBase: "/settings/courses"
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
CoursesSettingsTab.displayName = "CoursesSettingsTab";
|
|
53
|
+
|
|
54
|
+
export { CoursesSettingsTab };
|
|
55
|
+
//# sourceMappingURL=CoursesSettings-RLLYRP2R.js.map
|
|
56
|
+
//# sourceMappingURL=CoursesSettings-RLLYRP2R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/settings/CoursesSettings.tsx"],"names":[],"mappings":";;;;;;AASA,SAAS,sBAAA,GAAyB;AAChC,EAAA,MAAM,IAAI,cAAA,EAAe;AACzB,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAU,KAAA,CAAA,QAAA,CAAS,EAAE,IAAA,EAAM,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAA;AAEpF,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,CAAA,CAAE,2BAA2B,CAAA,IAAK,UAAA;AAAA,QACzC,WAAA,EAAa,CAAA,CAAE,+BAA+B,CAAA,IAAK,iFAAA;AAAA,QAEnD,QAAA,kBAAA,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,CAAA,CAAE,2BAA2B,CAAA,IAAK,kBAAA;AAAA,YACzC,KAAA,EAAO,QAAA;AAAA,YACP,QAAA,EAAU,WAAA;AAAA,YACV,OAAA,EAAS;AAAA,cACP,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,UAAA,EAAW;AAAA,cAClC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,SAAA,EAAU;AAAA,cACjC,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,cAAA;AAAU;AACnC;AAAA;AACF;AAAA,KACF;AAAA,yBAEC,aAAA,EAAA,EAAc,KAAA,EAAO,CAAA,CAAE,0BAA0B,KAAK,iBAAA,EACrD,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,OAAO,CAAA,CAAE,wBAAwB,KAAK,aAAA,EAAe,OAAA,EAAS,QAAQ,IAAA,EAAM,QAAA,EAAU,CAAC,CAAA,KAAM,UAAA,CAAW,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,CAAA,EAAE,CAAE,CAAA,EAAG,CAAA;AAAA,sBAChJ,GAAA,CAAC,aAAU,KAAA,EAAO,CAAA,CAAE,uBAAuB,CAAA,IAAK,KAAA,EAAO,OAAA,EAAS,OAAA,CAAQ,GAAA,EAAK,QAAA,EAAU,CAAC,CAAA,KAAM,UAAA,CAAW,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,GAAA,EAAK,CAAA,EAAE,CAAE,CAAA,EAAG,CAAA;AAAA,sBACrI,GAAA,CAAC,aAAU,KAAA,EAAO,CAAA,CAAE,0BAA0B,CAAA,IAAK,QAAA,EAAU,OAAA,EAAS,OAAA,CAAQ,MAAA,EAAQ,QAAA,EAAU,CAAC,CAAA,KAAM,UAAA,CAAW,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE,CAAE,CAAA,EAAG;AAAA,KAAA,EACnJ;AAAA,GAAA,EACF,CAAA;AAEJ;AACA,sBAAA,CAAuB,WAAA,GAAc,wBAAA;AAE9B,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,IAAI,cAAA,EAAe;AACzB,EAAA,uBACE,GAAA;AAAA,IAAC,mBAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,CAAE,wBAAwB,CAAA,IAAK,iBAAA;AAAA,MACtC,eAAA,sBAAkB,sBAAA,EAAA,EAAuB,CAAA;AAAA,MACzC,YAAA,EAAa,SAAA;AAAA,MACb,SAAA,EAAU;AAAA;AAAA,GACZ;AAEJ;AACA,kBAAA,CAAmB,WAAA,GAAc,oBAAA","file":"CoursesSettings-RLLYRP2R.js","sourcesContent":["import * as React from 'react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { PluginSettingsPanel, SettingsGroup, SelectRow, ToggleRow } from '@fayz-ai/admin'\n\n// The course plugin's Settings tab. Reuses the saas settings shell\n// (PluginSettingsPanel + SettingsGroup/SelectRow/ToggleRow) instead of\n// hand-rolling a settings layout — same chrome as every other plugin. Stripe\n// Connect lives in the \"Integrations\" tab (a connector), not here.\n\nfunction CoursesGeneralSettings() {\n const t = useTranslation()\n const [currency, setCurrency] = React.useState('BRL')\n const [methods, setMethods] = React.useState({ card: true, pix: true, boleto: true })\n\n return (\n <div className=\"space-y-6\">\n <SettingsGroup\n title={t('courses.settings.payments') || 'Payments'}\n description={t('courses.settings.paymentsHelp') || 'Connect Stripe in the Integrations tab; the platform fee applies automatically.'}\n >\n <SelectRow\n label={t('courses.settings.currency') || 'Default currency'}\n value={currency}\n onChange={setCurrency}\n options={[\n { value: 'BRL', label: 'BRL (R$)' },\n { value: 'USD', label: 'USD ($)' },\n { value: 'EUR', label: 'EUR (€)' },\n ]}\n />\n </SettingsGroup>\n\n <SettingsGroup title={t('courses.settings.methods') || 'Payment methods'}>\n <ToggleRow label={t('courses.editor.payCard') || 'Credit card'} checked={methods.card} onChange={(v) => setMethods((m) => ({ ...m, card: v }))} />\n <ToggleRow label={t('courses.editor.payPix') || 'Pix'} checked={methods.pix} onChange={(v) => setMethods((m) => ({ ...m, pix: v }))} />\n <ToggleRow label={t('courses.editor.payBoleto') || 'Boleto'} checked={methods.boleto} onChange={(v) => setMethods((m) => ({ ...m, boleto: v }))} />\n </SettingsGroup>\n </div>\n )\n}\nCoursesGeneralSettings.displayName = 'CoursesGeneralSettings'\n\nexport function CoursesSettingsTab() {\n const t = useTranslation()\n return (\n <PluginSettingsPanel\n title={t('courses.settings.title') || 'Course settings'}\n generalSettings={<CoursesGeneralSettings />}\n hostPluginId=\"courses\"\n routeBase=\"/settings/courses\"\n />\n )\n}\nCoursesSettingsTab.displayName = 'CoursesSettingsTab'\n"]}
|