Base app architecture:

    Route groups for customer, staff and owner.
* Reusable design system with around 20 UI components.
* Complete Prisma schema.
* Authentication with email/password and Google.
* Role and permission model.
* Protected routes.
* Clean separation between features, services, components and shared utilities.
This commit is contained in:
Stefan Lazic committed 2026-08-02 17:47:23 +01:00
1 parent 468d163299
commit 090646fdfd
201 files changed
+31984

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
import { Scissors } from "lucide-react";
export default function AuthLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen flex-col bg-stone p-6">
<div className="mx-auto flex w-full max-w-md flex-1 flex-col justify-center">
<div className="mb-8 flex h-16 w-16 items-center justify-center rounded-[1.25rem] bg-ink text-3xl text-white shadow-xl shadow-ink/20">
<Scissors className="h-7 w-7" aria-hidden="true" />
</div>
{children}
</div>
</div>
);
}
+16
View File
@@ -0,0 +1,16 @@
import type { Metadata } from "next";
import { RegisterForm } from "@/features/auth/components/register-form";
export const metadata: Metadata = {
title: "Create Account",
};
export default function RegisterPage() {
return (
<div>
<h1 className="mb-2 text-3xl font-bold tracking-tight">Create Account</h1>
<p className="mb-10 text-muted">Join to track your appointments and loyalty.</p>
<RegisterForm />
</div>
);
}
+22
View File
@@ -0,0 +1,22 @@
import type { Metadata } from "next";
import { Suspense } from "react";
import { SignInForm } from "@/features/auth/components/sign-in-form";
export const metadata: Metadata = {
title: "Sign In",
};
export default function SignInPage() {
return (
<div>
<h1 className="mb-2 text-4xl font-bold tracking-tight">Welcome back</h1>
<p className="mb-12 leading-relaxed text-muted">
Please enter your credentials to access your appointments.
</p>
{/* useSearchParams in SignInForm requires a Suspense boundary. */}
<Suspense>
<SignInForm />
</Suspense>
</div>
);
}