From 290d16d0f57d5b8ee6d6fd627df398d39376a8d9 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Mon, 6 Apr 2026 21:37:17 +0100 Subject: [PATCH 1/3] feat: add lesson form and UI components for lesson management --- .../lessons/_components/lesson-form.tsx | 103 ++++++++++++ .../lessons/_components/lesson-ui.tsx | 157 ++++++++++++++++++ 2 files changed, 260 insertions(+) create mode 100644 apps/web/app/t/[tenantSlug]/(workspace)/lessons/_components/lesson-form.tsx create mode 100644 apps/web/app/t/[tenantSlug]/(workspace)/lessons/_components/lesson-ui.tsx diff --git a/apps/web/app/t/[tenantSlug]/(workspace)/lessons/_components/lesson-form.tsx b/apps/web/app/t/[tenantSlug]/(workspace)/lessons/_components/lesson-form.tsx new file mode 100644 index 0000000..711850c --- /dev/null +++ b/apps/web/app/t/[tenantSlug]/(workspace)/lessons/_components/lesson-form.tsx @@ -0,0 +1,103 @@ +import type { ReactNode, TextareaHTMLAttributes } from "react"; +import Link from "next/link"; + +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +export function LessonFormPage({ + title, + description, + backHref, + backLabel = "Lessons", + children, +}: { + title: string; + description?: ReactNode; + backHref: string; + backLabel?: string; + children: ReactNode; +}) { + return ( +
+ +
+

+ {title} +

+ {description ? ( +
{description}
+ ) : null} +
+ {children} +
+ ); +} + +export function LessonFormCard({ + title, + description, + children, +}: { + title: string; + description?: ReactNode; + children: ReactNode; +}) { + return ( + + + {title} + {description ? {description} : null} + + {children} + + ); +} + +export function LessonField({ + label, + htmlFor, + hint, + error, + children, +}: { + label: string; + htmlFor?: string; + hint?: ReactNode; + error?: ReactNode; + children: ReactNode; +}) { + return ( +
+ + {children} + {hint ?

{hint}

: null} + {error ?

{error}

: null} +
+ ); +} + +export function LessonTextarea({ + className, + ...props +}: TextareaHTMLAttributes) { + return ( +