From fe48d889d558664bdad4ab53646a202b99c5f27a Mon Sep 17 00:00:00 2001 From: Mohammed <88824957+majhcc@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:23:49 +0400 Subject: [PATCH 1/3] Update dependencies and add middleware route and add KV --- deno.json | 5 +++-- fresh.gen.ts | 2 ++ routes/_app.tsx | 3 +-- routes/_middleware.ts | 24 ++++++++++++++++++++++ tailwind.config.ts | 1 + utils/KV.ts | 46 +++++++++++++++++++++++++++++++++++++++++++ utils/types.ts | 7 +++++++ 7 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 routes/_middleware.ts create mode 100644 utils/KV.ts diff --git a/deno.json b/deno.json index fd86ad8..6ed1652 100644 --- a/deno.json +++ b/deno.json @@ -4,7 +4,7 @@ "check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx", "cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -", "manifest": "deno task cli manifest $(pwd)", - "start": "deno run -A --watch=static/,routes/ dev.ts", + "start": "deno run -A --watch=static/,routes/ --unstable dev.ts", "build": "deno run -A dev.ts build", "preview": "deno run -A main.ts", "update": "deno run -A -r https://fresh.deno.dev/update ." @@ -31,7 +31,8 @@ "tailwindcss/plugin": "npm:/tailwindcss@3.3.5/plugin.js", "$std/": "https://deno.land/std@0.208.0/", "$gfm": "https://deno.land/x/gfm@0.1.26/mod.ts", - "daisyui": "npm:daisyui@latest" + "daisyui": "npm:daisyui@latest", + "zod": "https://esm.sh/zod@3.22.4" }, "compilerOptions": { "jsx": "react-jsx", diff --git a/fresh.gen.ts b/fresh.gen.ts index ad97083..897abc4 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -5,6 +5,7 @@ import * as $_slug_ from "./routes/[...slug].tsx"; import * as $_404 from "./routes/_404.tsx"; import * as $_app from "./routes/_app.tsx"; +import * as $_middleware from "./routes/_middleware.ts"; import * as $about from "./routes/about.tsx"; import * as $api_test from "./routes/api/test.ts"; import * as $group_slug_ from "./routes/group/[slug].tsx"; @@ -24,6 +25,7 @@ const manifest = { "./routes/[...slug].tsx": $_slug_, "./routes/_404.tsx": $_404, "./routes/_app.tsx": $_app, + "./routes/_middleware.ts": $_middleware, "./routes/about.tsx": $about, "./routes/api/test.ts": $api_test, "./routes/group/[slug].tsx": $group_slug_, diff --git a/routes/_app.tsx b/routes/_app.tsx index 2ba7ffb..eb9879c 100644 --- a/routes/_app.tsx +++ b/routes/_app.tsx @@ -1,10 +1,9 @@ -import { type PageProps } from "$fresh/server.ts"; +import { Handlers, type PageProps, FreshContext } from "$fresh/server.ts"; import NavBar from "../components/Nav.tsx"; import Toast from "../islands/Toast.tsx"; import { populateCache } from "../utils/course-cache.ts"; populateCache(); - export default function App({ Component }: PageProps) { return ( diff --git a/routes/_middleware.ts b/routes/_middleware.ts new file mode 100644 index 0000000..a5a2919 --- /dev/null +++ b/routes/_middleware.ts @@ -0,0 +1,24 @@ +import { FreshContext } from "$fresh/server.ts"; +import {getCookies, Cookie, setCookie} from "$std/http/mod.ts"; +import { createStudent } from "../utils/KV.ts"; +export async function handler( + req: Request, + ctx: FreshContext, + ) { + const resp = await ctx.next(); + const cookies = getCookies(req.headers); + const sessionId = cookies["sessionId"] || ""; + if (!sessionId) { + try { + const student = await createStudent(); + const cookie: Cookie = { + name: "sessionId", + value: student.sessionId, + } + setCookie(resp.headers, cookie); + } catch { + return ctx.renderNotFound(); + } + } + return resp; + } \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 34193ed..0c4afeb 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -10,6 +10,7 @@ export default { ], plugins: [daisyui], daisyui: { + log: false, themes: ["dracula", "nord"], }, } satisfies Config; diff --git a/utils/KV.ts b/utils/KV.ts new file mode 100644 index 0000000..740b48b --- /dev/null +++ b/utils/KV.ts @@ -0,0 +1,46 @@ +import { student, Result } from "./types.ts"; + +const kv = await Deno.openKv(); +export const createStudent = async (): Promise => { + const student: student = { + sessionId: crypto.randomUUID(), + completedCourses: [], + } + const res = await kv.set(["student", student.sessionId], student) + if (res.ok) { + return student + } else { + throw new Error("Failed to create student") + } +} +export const getStudent = async (sessionId: string): Promise => { + const student = await kv.get(["student", sessionId]) + if (student) { + return student.value as student + } else { + throw new Error("Failed to get student") + } +} +export const updateStudent = async (sessionId: string, student: student): Promise => { + const res = await kv.set(["student", sessionId], student) + if (res.ok) { + return res + } else { + throw new Error("Failed to update student") + } +} +export const addCompletedCourse = async (sessionId: string, course: string) : Promise => { + const student = await getStudent(sessionId) + if (student.completedCourses.includes(course)) { + throw new Error("Course already completed") + } + const completedCourses = student.completedCourses + completedCourses.push(course) + student.completedCourses = completedCourses + try { + const res = await updateStudent(sessionId, student) + return res + } catch { + throw new Error("Failed to add completed course") + } +} \ No newline at end of file diff --git a/utils/types.ts b/utils/types.ts index 6dbb25d..c40801d 100644 --- a/utils/types.ts +++ b/utils/types.ts @@ -18,3 +18,10 @@ export interface CourseAttributes { snippet: string; order: number; } +export interface student { + sessionId: string; + completedCourses: string[]; +} +export interface Result { + ok: boolean; +} From d2191ffd73a6982eed2c40cb43af76a4c0f3a968 Mon Sep 17 00:00:00 2001 From: Mohammed <88824957+majhcc@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:27:19 +0400 Subject: [PATCH 2/3] ADD DENO KV --- components/Collapse.tsx | 4 ++-- components/CourseCard.tsx | 6 +++--- components/Courses.tsx | 6 ++++-- components/ProgressCheck.tsx | 8 +++++++ components/ProgressPageSplit.tsx | 37 +++++++++++++++++--------------- fresh.gen.ts | 4 ++-- islands/Editor.tsx | 16 ++++++++++---- routes/api/test.ts | 5 ----- routes/api/test/finsh.ts | 19 ++++++++++++++++ routes/index.tsx | 34 ++++++++++++++++++++--------- utils/course.ts | 12 +++++++++++ 11 files changed, 106 insertions(+), 45 deletions(-) create mode 100644 components/ProgressCheck.tsx delete mode 100644 routes/api/test.ts create mode 100644 routes/api/test/finsh.ts diff --git a/components/Collapse.tsx b/components/Collapse.tsx index 564def5..cc226c3 100644 --- a/components/Collapse.tsx +++ b/components/Collapse.tsx @@ -2,7 +2,7 @@ import { Course } from "../utils/types.ts"; import CourseCard from "./CourseCard.tsx"; export default function Collapse( - { title, courses }: { title: string; courses: Course[] }, + { title, courses, completed }: { title: string; courses: Course[]; completed: string[] }, ) { return (
@@ -12,7 +12,7 @@ export default function Collapse(
{courses.map((course) => ( - + ))}
diff --git a/components/CourseCard.tsx b/components/CourseCard.tsx index f12e001..9efbf1a 100644 --- a/components/CourseCard.tsx +++ b/components/CourseCard.tsx @@ -1,8 +1,8 @@ import { Course } from "../utils/types.ts"; -import ProgressCheck from "../islands/ProgressCheck.tsx"; +import ProgressCheck from "./ProgressCheck.tsx"; -export default function CourseCard(props: { course: Course }) { +export default function CourseCard(props: { course: Course; isDone: boolean }) { const { course } = props; return (

- + {course.title}

diff --git a/components/Courses.tsx b/components/Courses.tsx index e2ee837..cdfc501 100644 --- a/components/Courses.tsx +++ b/components/Courses.tsx @@ -4,8 +4,9 @@ import Collapse from "./Collapse.tsx"; import CourseCard from "./CourseCard.tsx"; export default function Courses( - { courses }: { courses: (Course | CourseGroup)[] }, + { courses, completed }: { courses: (Course | CourseGroup)[], completed: string[] }, ) { + return ( <>

الاساسيات

@@ -16,6 +17,7 @@ export default function Courses( return (
@@ -25,7 +27,7 @@ export default function Courses( // Single course return (
- +
); } diff --git a/components/ProgressCheck.tsx b/components/ProgressCheck.tsx new file mode 100644 index 0000000..d8bde44 --- /dev/null +++ b/components/ProgressCheck.tsx @@ -0,0 +1,8 @@ +import IconCircleCheckFilled from "https://deno.land/x/tabler_icons_tsx@0.0.5/tsx/circle-check-filled.tsx"; +import IconCircle from "https://deno.land/x/tabler_icons_tsx@0.0.5/tsx/circle.tsx"; + +export default function ProgressCheck(props: {isDone : boolean}) { + return props.isDone + ?