diff --git a/thoughts-frontend/app/(auth)/layout.tsx b/thoughts-frontend/app/(auth)/layout.tsx
new file mode 100644
index 0000000..4867b37
--- /dev/null
+++ b/thoughts-frontend/app/(auth)/layout.tsx
@@ -0,0 +1,12 @@
+// app/(auth)/layout.tsx
+export default function AuthLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/thoughts-frontend/app/(auth)/login/page.tsx b/thoughts-frontend/app/(auth)/login/page.tsx
new file mode 100644
index 0000000..c5edd91
--- /dev/null
+++ b/thoughts-frontend/app/(auth)/login/page.tsx
@@ -0,0 +1,112 @@
+"use client";
+
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { z } from "zod";
+import { useRouter } from "next/navigation";
+import Link from "next/link";
+import { Button } from "@/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+} from "@/components/ui/card";
+import {
+ Form,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormControl,
+ FormMessage,
+} from "@/components/ui/form";
+import { Input } from "@/components/ui/input";
+import { LoginSchema, loginUser } from "@/lib/api";
+import { useAuth } from "@/hooks/use-auth";
+import { useState } from "react";
+
+export default function LoginPage() {
+ const router = useRouter();
+ const { setToken } = useAuth();
+ const [error, setError] = useState(null);
+
+ const form = useForm>({
+ resolver: zodResolver(LoginSchema),
+ defaultValues: { username: "", password: "" },
+ });
+
+ async function onSubmit(values: z.infer) {
+ try {
+ setError(null);
+ const { token } = await loginUser(values);
+ setToken(token);
+ router.push("/"); // Redirect to homepage on successful login
+ } catch (err) {
+ setError("Invalid username or password.");
+ }
+ }
+
+ return (
+
+
+ Login
+
+ Enter your credentials to access your account.
+
+
+
+
+
+
+ Don't have an account?{" "}
+
+ Register
+
+
+
+
+ );
+}
diff --git a/thoughts-frontend/app/(auth)/register/page.tsx b/thoughts-frontend/app/(auth)/register/page.tsx
new file mode 100644
index 0000000..0652aa3
--- /dev/null
+++ b/thoughts-frontend/app/(auth)/register/page.tsx
@@ -0,0 +1,125 @@
+"use client";
+
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { z } from "zod";
+import { useRouter } from "next/navigation";
+import Link from "next/link";
+import { Button } from "@/components/ui/button";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+ CardDescription,
+} from "@/components/ui/card";
+import {
+ Form,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormControl,
+ FormMessage,
+} from "@/components/ui/form";
+import { Input } from "@/components/ui/input";
+import { RegisterSchema, registerUser } from "@/lib/api";
+import { useState } from "react";
+
+export default function RegisterPage() {
+ const router = useRouter();
+ const [error, setError] = useState(null);
+
+ const form = useForm>({
+ resolver: zodResolver(RegisterSchema),
+ defaultValues: { username: "", email: "", password: "" },
+ });
+
+ async function onSubmit(values: z.infer) {
+ try {
+ setError(null);
+ await registerUser(values);
+ // You can automatically log the user in here or just redirect them
+ router.push("/login");
+ } catch (err) {
+ setError("Username or email may already be taken.");
+ }
+ }
+
+ return (
+
+
+ Create an Account
+ Enter your details to register.
+
+
+
+
+
+ Already have an account?{" "}
+
+ Login
+
+
+
+
+ );
+}
diff --git a/thoughts-frontend/app/layout.tsx b/thoughts-frontend/app/layout.tsx
index f7fa87e..8cf5f6e 100644
--- a/thoughts-frontend/app/layout.tsx
+++ b/thoughts-frontend/app/layout.tsx
@@ -1,6 +1,8 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
+import { AuthProvider } from "@/hooks/use-auth";
+import { Toaster } from "@/components/ui/sonner";
const geistSans = Geist({
variable: "--font-geist-sans",
@@ -27,7 +29,10 @@ export default function RootLayout({
- {children}
+
+ {children}
+
+