Skip to content

Commit a45abdb

Browse files
committed
fixed up folder layout but overall looks good
1 parent 8f9945e commit a45abdb

File tree

17 files changed

+131
-132
lines changed

17 files changed

+131
-132
lines changed

src/actions/admin/lesson.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use server';
2+
import { revalidatePath } from "next/cache";
3+
import { db } from "@/db/index";
4+
import { lessons } from "@/db/schema";
5+
import { lessonFormSchema } from "@/lib/validations/lesson";
6+
import { actionClient } from "@/lib/safe-action";
7+
8+
export const createLessonAction = actionClient
9+
.schema(lessonFormSchema)
10+
.action(async ({ parsedInput }) => {
11+
const {
12+
title,
13+
description,
14+
unitId,
15+
courseId,
16+
mediaType,
17+
contentUrl,
18+
} = parsedInput;
19+
20+
const metadata = JSON.stringify({
21+
title,
22+
description: description ?? "",
23+
});
24+
25+
await db.insert(lessons).values({
26+
unitId,
27+
mediaType, // now real value from the form
28+
metadata,
29+
contentUrl, // real URL from the form
30+
// contentBlobId stays null
31+
});
32+
33+
revalidatePath(`/admin/courses/${courseId}`);
34+
35+
return { success: true };
36+
});

src/actions/admin/tag.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use server';
22
import { tags, users, coursesTags } from "@/db/schema";
3-
import { type TagFormValues } from "@/lib/validations/course";
3+
import { type TagFormValues } from "@/lib/validations/tag";
44
import { db } from "@/db";
55
import { auth } from "@/lib/auth";
66
import { headers } from "next/headers";

src/actions/admin/units.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// src/app/admin/courses/[courseId]/lesson/create/actions.ts
2+
'use server';
3+
4+
import { revalidatePath } from "next/cache";
5+
import { db } from "@/db/index";
6+
import { units } from "@/db/schema";
7+
import { createUnitSchema } from "@/lib/validations/unit";
8+
import { actionClient } from "@/lib/safe-action";
9+
10+
// Create unit (for the modal)
11+
export const createUnitAction = actionClient
12+
.schema(createUnitSchema)
13+
.action(async ({ parsedInput }) => {
14+
const { title, courseId } = parsedInput;
15+
// Minimal insert: courseId (text) + title; position defaults to 1
16+
const [unit] = await db
17+
.insert(units)
18+
.values({
19+
courseId,
20+
title,
21+
})
22+
.returning();
23+
24+
revalidatePath(`/admin/courses/${courseId}`);
25+
26+
return {
27+
success: true,
28+
unitId: unit.id,
29+
unitTitle: unit.title,
30+
};
31+
});

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { db } from "@/db/index";
22
import { units } from "@/db/schema";
33
import { eq } from "drizzle-orm";
4-
import { CreateLessonForm } from "./CreateLessonForm";
4+
import { CreateLessonForm } from "@/components/admin/CreateLessonForm";
55
import {
66
Card,
77
CardHeader,
Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
export default async function Page({
2-
params,
3-
}: {
4-
params: Promise<{ courseId: string }>;
1+
2+
export default async function CourseIdPage({
3+
params
4+
}: {
5+
params: Promise<{ courseId: string}>
56
}) {
6-
const { courseId } = await params;
7-
return <div>This is the admin course page for {courseId}</div>;
8-
}
7+
const { courseId } = await params;
8+
const id = Number(courseId);
9+
10+
return <div className="">
11+
Course ID: {id}
12+
</div>
13+
}

src/app/admin/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import AdminNavbar from "@/components/AdminNavbar";
2+
import AdminNavbar from "@/components/admin/AdminNavbar";
33
import { Toaster } from "sonner"
44

55

src/components/admin/CourseTable.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
import { getAllCourses } from "@/actions/admin/course";
3939
import { CourseWithData } from "@/lib/types";
4040
import { useEffect, useState } from "react";
41+
import Link from "next/link";
4142

4243
const columns: ColumnDef<CourseWithData>[] = [
4344
{
@@ -80,7 +81,14 @@ const columns: ColumnDef<CourseWithData>[] = [
8081
</div>
8182
)
8283
},
83-
cell: ({ row }) => <div className="text-left pl-3">{row.getValue("title")}</div>,
84+
cell: ({ row }) => {
85+
const course = row.original;
86+
return (
87+
<div className="text-left pl-3">
88+
<Link className="hover:underline" href={`/admin/courses/${course.id}`}>{row.getValue("title")}</Link>
89+
</div>
90+
);
91+
},
8492
},
8593
{
8694
accessorKey: "description",

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import { useAction } from "next-safe-action/hooks";
88

99
import {
1010
lessonFormSchema,
11-
type LessonFormSchema,
12-
} from "@/lib/lesson";
13-
import { createLessonAction } from "@/lib/lessonActions";
11+
type LessonFormValues,
12+
} from "@/lib/validations/lesson";
13+
import { createLessonAction } from "@/actions/admin/lesson";
1414

1515
import {
1616
Form,
@@ -31,7 +31,7 @@ import {
3131
SelectValue,
3232
} from "@/components/ui/select";
3333

34-
import { CreateUnitDialog } from "@/components/CreateUnitDialog";
34+
import { CreateUnitDialog } from "./CreateUnitDialog";
3535

3636
type UnitOption = {
3737
id: number;
@@ -56,7 +56,7 @@ export function CreateLessonForm({
5656

5757
// Relaxed typing around resolver to avoid RHF + zod generic noise,
5858
// while still keeping LessonFormSchema as the form's value type.
59-
const form = useForm<LessonFormSchema>({
59+
const form = useForm<LessonFormValues>({
6060
resolver: zodResolver(lessonFormSchema) as any,
6161
defaultValues: {
6262
title: "",
@@ -78,7 +78,7 @@ export function CreateLessonForm({
7878

7979
const isSubmitting = status === "executing";
8080

81-
const onSubmit = (values: LessonFormSchema) => {
81+
const onSubmit = (values: LessonFormValues) => {
8282
execute(values);
8383
};
8484

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { useAction } from "next-safe-action/hooks";
77

88
import {
99
createUnitAction,
10-
} from "@/lib/lessonActions";
10+
} from "@/actions/admin/units";
1111
import {
1212
createUnitSchema,
13-
type CreateUnitSchema,
14-
} from "@/lib/lesson";
13+
type CreateUnitValues,
14+
} from "@/lib/validations/unit";
1515

1616
import {
1717
Dialog,
@@ -44,7 +44,7 @@ export function CreateUnitDialog({
4444
courseId,
4545
onCreated,
4646
}: CreateUnitDialogProps) {
47-
const form = useForm<CreateUnitSchema>({
47+
const form = useForm<CreateUnitValues>({
4848
resolver: zodResolver(createUnitSchema),
4949
defaultValues: {
5050
title: "",
@@ -67,7 +67,7 @@ export function CreateUnitDialog({
6767

6868
const isSubmitting = status === "executing";
6969

70-
const onSubmit = (values: CreateUnitSchema) => {
70+
const onSubmit = (values: CreateUnitValues) => {
7171
execute(values);
7272
};
7373

0 commit comments

Comments
 (0)