Phase 2
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:
201 files changed
+31984
No files matched your search
@@ -0,0 +1,9 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Users } from "lucide-react";
|
||||
import { ComingSoon } from "@/components/feedback/coming-soon";
|
||||
|
||||
export const metadata: Metadata = { title: "Clients" };
|
||||
|
||||
export default function StaffClientsPage() {
|
||||
return <ComingSoon icon={Users} title="Clients" phase="Phase 3: Barber Tools" />;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Scissors } from "lucide-react";
|
||||
import { ComingSoon } from "@/components/feedback/coming-soon";
|
||||
|
||||
export const metadata: Metadata = { title: "Current Appointment" };
|
||||
|
||||
export default function StaffCurrentPage() {
|
||||
return <ComingSoon icon={Scissors} title="Current Appointment" phase="Phase 3: Barber Tools" />;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { Metadata } from "next";
|
||||
import { CalendarDays } from "lucide-react";
|
||||
import { ComingSoon } from "@/components/feedback/coming-soon";
|
||||
|
||||
export const metadata: Metadata = { title: "Calendar" };
|
||||
|
||||
export default function StaffCalendarPage() {
|
||||
return <ComingSoon icon={CalendarDays} title="Calendar" phase="Phase 3: Barber Tools" />;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { ShieldCheck } from "lucide-react";
|
||||
import { auth } from "@/auth";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ProfileCard } from "@/components/ui/profile-card";
|
||||
import { SignOutButton } from "@/features/auth/components/sign-out-button";
|
||||
import { hasPermission } from "@/lib/auth/permissions";
|
||||
import { Permission } from "@/generated/prisma/enums";
|
||||
|
||||
export const metadata: Metadata = { title: "Staff Settings" };
|
||||
|
||||
export default async function StaffSettingsPage() {
|
||||
const session = await auth();
|
||||
if (!session?.user) return null;
|
||||
|
||||
// Real permission check, not the templates' unconditional mock "Switch to
|
||||
// Admin View" button (see docs/implementation-plan.md §3) — only staff
|
||||
// whose Role actually grants MANAGE_STAFF see a way into the owner area.
|
||||
const canManageStaff = await hasPermission(session.user.id, Permission.MANAGE_STAFF);
|
||||
|
||||
return (
|
||||
<div className="space-y-6 px-6 pt-12">
|
||||
<h1 className="text-2xl font-bold tracking-tight">Staff Settings</h1>
|
||||
<ProfileCard name={session.user.name ?? "Staff member"} meta={session.user.email} avatarUrl={session.user.image ?? undefined} />
|
||||
|
||||
{canManageStaff && (
|
||||
<Link
|
||||
href="/owner"
|
||||
className="flex items-center gap-3 rounded-jumbo border border-line bg-white p-5 text-sm font-bold hover:bg-stone"
|
||||
>
|
||||
<ShieldCheck className="h-5 w-5 text-accent" aria-hidden="true" />
|
||||
Switch to Owner Admin
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<Button variant="ghost" className="w-full" disabled>
|
||||
Working Hours, Breaks & Time Off — Phase 3
|
||||
</Button>
|
||||
<SignOutButton />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user