Skip to content

Commit eb466f8

Browse files
committed
Feature Create Lesson Page: Added CSS styling to page
1 parent 546f137 commit eb466f8

File tree

3 files changed

+124
-95
lines changed

3 files changed

+124
-95
lines changed

src/app/admin/courses/[courseId]/lesson/create/CreateLessonForm.tsx

Lines changed: 85 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,19 @@ export function CreateLessonForm({
5454
const [units, setUnits] = React.useState<UnitOption[]>(initialUnits);
5555
const [openUnitDialog, setOpenUnitDialog] = React.useState(false);
5656

57-
const form = useForm<LessonFormSchema>({
58-
resolver: zodResolver(lessonFormSchema) as any,
59-
defaultValues: {
60-
title: "",
61-
description: "",
62-
unitId: 0,
63-
courseId,
64-
mediaType: "markdown", // sensible default
65-
contentUrl: "",
66-
},
67-
}) as any;
68-
57+
// Relaxed typing around resolver to avoid RHF + zod generic noise,
58+
// while still keeping LessonFormSchema as the form's value type.
59+
const form = useForm<LessonFormSchema>({
60+
resolver: zodResolver(lessonFormSchema) as any,
61+
defaultValues: {
62+
title: "",
63+
description: "",
64+
unitId: 0,
65+
courseId,
66+
mediaType: "markdown",
67+
contentUrl: "",
68+
},
69+
}) as any;
6970

7071
const { execute, status, result } = useAction(createLessonAction, {
7172
onSuccess: ({ data }) => {
@@ -109,91 +110,99 @@ export function CreateLessonForm({
109110
<Form {...form}>
110111
<form
111112
onSubmit={form.handleSubmit(onSubmit)}
112-
className="space-y-6 max-w-xl"
113+
className="space-y-8"
113114
>
114-
<FormField
115-
control={form.control}
116-
name="title"
117-
render={({ field }) => (
118-
<FormItem>
119-
<FormLabel>Lesson title</FormLabel>
120-
<FormControl>
121-
<Input placeholder="e.g. What is a variable?" {...field} />
122-
</FormControl>
123-
<FormMessage />
124-
</FormItem>
125-
)}
126-
/>
127-
128-
<FormField
129-
control={form.control}
130-
name="description"
131-
render={({ field }) => (
132-
<FormItem>
133-
<FormLabel>Description</FormLabel>
134-
<FormControl>
135-
<Textarea
136-
placeholder="Short summary of this lesson..."
137-
{...field}
138-
/>
139-
</FormControl>
140-
<FormMessage />
141-
</FormItem>
142-
)}
143-
/>
115+
{/* Top section: basic info */}
116+
<div className="grid gap-6 md:grid-cols-2">
117+
<FormField
118+
control={form.control}
119+
name="title"
120+
render={({ field }) => (
121+
<FormItem className="md:col-span-2">
122+
<FormLabel>Lesson title</FormLabel>
123+
<FormControl>
124+
<Input
125+
placeholder="e.g. Introduction to Variables"
126+
{...field}
127+
/>
128+
</FormControl>
129+
<FormMessage />
130+
</FormItem>
131+
)}
132+
/>
144133

145-
{/* Hidden courseId so it gets sent along with the form */}
146-
<input type="hidden" {...form.register("courseId")} value={courseId} />
134+
<FormField
135+
control={form.control}
136+
name="description"
137+
render={({ field }) => (
138+
<FormItem className="md:col-span-2">
139+
<FormLabel>Description</FormLabel>
140+
<FormControl>
141+
<Textarea
142+
placeholder="Short summary of what this lesson covers..."
143+
className="min-h-[96px]"
144+
{...field}
145+
/>
146+
</FormControl>
147+
<FormMessage />
148+
</FormItem>
149+
)}
150+
/>
151+
</div>
147152

148-
{/* Media type */}
153+
{/* Content section */}
154+
<div className="grid gap-6 md:grid-cols-2 rounded-lg border border-dashed border-border/60 bg-muted/40 p-4">
149155
<FormField
150-
control={form.control}
151-
name="mediaType"
152-
render={({ field }) => (
156+
control={form.control}
157+
name="mediaType"
158+
render={({ field }) => (
153159
<FormItem>
154-
<FormLabel>Content type</FormLabel>
155-
<Select
160+
<FormLabel>Content type</FormLabel>
161+
<Select
156162
value={field.value}
157163
onValueChange={field.onChange}
158-
>
164+
>
159165
<FormControl>
160-
<SelectTrigger>
166+
<SelectTrigger>
161167
<SelectValue placeholder="Select a content type" />
162-
</SelectTrigger>
168+
</SelectTrigger>
163169
</FormControl>
164170
<SelectContent>
165-
<SelectItem value="youtube">YouTube video</SelectItem>
166-
<SelectItem value="markdown">Markdown page</SelectItem>
167-
<SelectItem value="pdf">PDF</SelectItem>
168-
<SelectItem value="image">Image</SelectItem>
169-
<SelectItem value="audio">Audio</SelectItem>
170-
<SelectItem value="other">Other</SelectItem>
171+
<SelectItem value="youtube">YouTube video</SelectItem>
172+
<SelectItem value="markdown">Markdown page</SelectItem>
173+
<SelectItem value="pdf">PDF</SelectItem>
174+
<SelectItem value="image">Image</SelectItem>
175+
<SelectItem value="audio">Audio</SelectItem>
176+
<SelectItem value="other">Other</SelectItem>
171177
</SelectContent>
172-
</Select>
173-
<FormMessage />
178+
</Select>
179+
<FormMessage />
174180
</FormItem>
175-
)}
181+
)}
176182
/>
177183

178-
{/* Main content URL */}
179184
<FormField
180-
control={form.control}
181-
name="contentUrl"
182-
render={({ field }) => (
183-
<FormItem>
184-
<FormLabel>Content URL</FormLabel>
185-
<FormControl>
185+
control={form.control}
186+
name="contentUrl"
187+
render={({ field }) => (
188+
<FormItem className="md:col-span-1">
189+
<FormLabel>Content URL</FormLabel>
190+
<FormControl>
186191
<Input
187-
placeholder="https://..."
188-
{...field}
192+
placeholder="https://..."
193+
{...field}
189194
/>
190-
</FormControl>
191-
<FormMessage />
195+
</FormControl>
196+
<FormMessage />
192197
</FormItem>
193-
)}
198+
)}
194199
/>
200+
</div>
195201

202+
{/* Hidden courseId so it gets sent along with the form */}
203+
<input type="hidden" {...form.register("courseId")} value={courseId} />
196204

205+
{/* Unit selection */}
197206
<FormField
198207
control={form.control}
199208
name="unitId"
@@ -231,7 +240,7 @@ export function CreateLessonForm({
231240
</p>
232241
)}
233242

234-
<div className="flex gap-2">
243+
<div className="flex items-center justify-end gap-2 pt-2">
235244
<Button
236245
type="button"
237246
variant="outline"
Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
// src/app/admin/courses/[courseId]/lesson/create/page.tsx
2-
31
import { db } from "@/db/index";
42
import { units } from "@/db/schema";
53
import { eq } from "drizzle-orm";
64
import { CreateLessonForm } from "./CreateLessonForm";
5+
import {
6+
Card,
7+
CardHeader,
8+
CardTitle,
9+
CardDescription,
10+
CardContent,
11+
} from "@/components/ui/card";
712

813
type PageProps = {
914
params: Promise<{ courseId: string }>;
@@ -12,30 +17,41 @@ type PageProps = {
1217
export default async function CreateLessonPage({ params }: PageProps) {
1318
const { courseId } = await params;
1419

15-
// courseId in the URL will be something like "1"
1620
const courseUnits = await db
1721
.select()
1822
.from(units)
1923
.where(eq(units.courseId, courseId));
2024

2125
return (
22-
<div className="space-y-6">
26+
<div className="mx-auto flex max-w-3xl flex-col gap-6">
2327
<div>
24-
<h1 className="text-2xl font-semibold tracking-tight">
28+
<h1 className="text-3xl font-semibold tracking-tight">
2529
Create lesson
2630
</h1>
27-
<p className="text-sm text-muted-foreground">
28-
Add a new lesson and assign it to a unit in this course.
31+
<p className="mt-1 text-sm text-muted-foreground">
32+
Define lesson details, add content, and assign it to a unit in this
33+
course.
2934
</p>
3035
</div>
3136

32-
<CreateLessonForm
33-
courseId={courseId}
34-
initialUnits={courseUnits.map((u) => ({
35-
id: u.id,
36-
title: u.title ?? `Unit ${u.id}`,
37-
}))}
38-
/>
37+
<Card className="border border-border/60 shadow-sm">
38+
<CardHeader className="pb-4">
39+
<CardTitle className="text-lg">Lesson details</CardTitle>
40+
<CardDescription>
41+
Fill out the fields below to create a new lesson. You can also
42+
create a new unit on the fly if you need one.
43+
</CardDescription>
44+
</CardHeader>
45+
<CardContent className="pt-2">
46+
<CreateLessonForm
47+
courseId={courseId}
48+
initialUnits={courseUnits.map((u) => ({
49+
id: u.id,
50+
title: u.title ?? `Unit ${u.id}`,
51+
}))}
52+
/>
53+
</CardContent>
54+
</Card>
3955
</div>
4056
);
4157
}

src/components/CreateUnitDialog.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ export function CreateUnitDialog({
7373

7474
return (
7575
<Dialog open={open} onOpenChange={onOpenChange}>
76-
<DialogContent>
76+
<DialogContent className="sm:max-w-md">
7777
<DialogHeader>
78-
<DialogTitle>Create new unit</DialogTitle>
78+
<DialogTitle className="text-lg">
79+
Create new unit
80+
</DialogTitle>
7981
</DialogHeader>
8082

8183
<Form {...form}>
@@ -87,7 +89,10 @@ export function CreateUnitDialog({
8789
<FormItem>
8890
<FormLabel>Unit title</FormLabel>
8991
<FormControl>
90-
<Input placeholder="e.g. Introduction" {...field} />
92+
<Input
93+
placeholder="e.g. Week 1: Introduction"
94+
{...field}
95+
/>
9196
</FormControl>
9297
<FormMessage />
9398
</FormItem>
@@ -100,7 +105,7 @@ export function CreateUnitDialog({
100105
</p>
101106
)}
102107

103-
<DialogFooter>
108+
<DialogFooter className="pt-2">
104109
<Button
105110
type="button"
106111
variant="outline"
@@ -118,4 +123,3 @@ export function CreateUnitDialog({
118123
</Dialog>
119124
);
120125
}
121-

0 commit comments

Comments
 (0)