From c8ee97dc44f0e65e8c715d9f9d0952e5ca53637a Mon Sep 17 00:00:00 2001 From: Thyu Htoo Aung Date: Sat, 25 Apr 2026 19:22:09 +0630 Subject: [PATCH] feat: implement authentication pages, configure Convex schema and posts module --- .github/workflows/ci.yml | 3 +- .prettierrc | 11 +++ app/(shared-layout)/create/page.tsx | 121 +++++++++++++++++++++++ app/(shared-layout)/test/page.tsx | 15 --- app/auth/login/page.tsx | 144 +++++++++++++++++++++++++++- app/auth/sign-up/page.tsx | 45 +++++++-- app/layout.tsx | 5 +- app/schemas/auth.ts | 7 +- app/schemas/blog.ts | 6 ++ components/ui/button.tsx | 5 +- components/ui/sonner.tsx | 45 +++++++++ components/ui/textarea.tsx | 18 ++++ components/web/navbar.tsx | 25 ++++- convex/_generated/api.d.ts | 4 +- convex/_generated/api.js | 1 + convex/_generated/dataModel.d.ts | 34 +++---- convex/_generated/server.d.ts | 1 + convex/_generated/server.js | 1 + convex/posts.ts | 23 +++++ convex/schema.ts | 10 ++ convex/tasks.ts | 8 -- eslint.config.mjs | 1 + next.config.ts | 4 +- package.json | 9 +- pnpm-lock.yaml | 17 ++++ pnpm-workspace.yaml | 6 -- tsconfig.json | 2 +- 27 files changed, 501 insertions(+), 70 deletions(-) create mode 100644 .prettierrc create mode 100644 app/(shared-layout)/create/page.tsx delete mode 100644 app/(shared-layout)/test/page.tsx create mode 100644 app/schemas/blog.ts create mode 100644 components/ui/sonner.tsx create mode 100644 components/ui/textarea.tsx create mode 100644 convex/posts.ts create mode 100644 convex/schema.ts delete mode 100644 convex/tasks.ts delete mode 100644 pnpm-workspace.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70697ef..f7912a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,6 @@ name: Nextblog CI on: - push: - branches: [main] pull_request: branches: [main] @@ -47,3 +45,4 @@ jobs: NEXT_PUBLIC_CONVEX_URL: "https://insightful-pheasant-237.convex.cloud" NEXT_PUBLIC_CONVEX_SITE_URL: "https://insightful-pheasant-237.convex.site" NEXT_PUBLIC_SITE_URL: "http://localhost:3000" + BETTER_AUTH_SECRET: "dummy-secret-for-ci-build" diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..c8f22cb --- /dev/null +++ b/.prettierrc @@ -0,0 +1,11 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "printWidth": 80, + "bracketSpacing": true, + "arrowParens": "always", + "endOfLine": "lf" +} diff --git a/app/(shared-layout)/create/page.tsx b/app/(shared-layout)/create/page.tsx new file mode 100644 index 0000000..9525e93 --- /dev/null +++ b/app/(shared-layout)/create/page.tsx @@ -0,0 +1,121 @@ +"use client"; + +import { useTransition } from "react"; +import { Loader2 } from "lucide-react"; +import { Controller, useForm } from "react-hook-form"; +import { useMutation } from "convex/react"; +import { + Card, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { CardContent } from "@/components/ui/card"; +import { + Field, + FieldError, + FieldGroup, + FieldLabel, +} from "@/components/ui/field"; +import { Input } from "@/components/ui/input"; +import { Button } from "@/components/ui/button"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { postSchema } from "@/app/schemas/blog"; +import { api } from "@/convex/_generated/api"; +import { Textarea } from "@/components/ui/textarea"; +import { toast } from "sonner"; +import { z } from "zod/v3"; + +export default function CreatePage() { + const form = useForm>({ + resolver: zodResolver(postSchema), + defaultValues: { + title: "", + content: "", + }, + }); + const createPost = useMutation(api.posts.createPost); + const [isPending, startTransition] = useTransition(); + + const onSubmit = (data: z.infer) => { + startTransition(async () => { + try { + await createPost(data); + toast.success("Post created successfully!"); + form.reset(); + } catch { + toast.error("Failed to create post"); + } + }); + }; + return ( +
+
+

+ Create Blog +

+

+ Share your knowledge and ideas with the world. +

+
+ + + + Create Blog Article + Create a new blog article + + +
+ + ( + + Title + + {fieldState.error && ( + {fieldState.error.message} + )} + + )} + /> + ( + + Content +