From 7224c87cef725beb0c4c34d4d475e050e89aebfb Mon Sep 17 00:00:00 2001 From: Stefan Lazic Date: Sat, 12 Sep 2026 17:24:47 +0100 Subject: [PATCH] Header Update Updated the header of these pages to match the rest of the pages. --- src/app/(owner)/owner/reports/page.tsx | 227 +++++++++--------- src/app/(owner)/owner/services/page.tsx | 47 ++-- src/app/(owner)/owner/team/page.tsx | 147 ++++++------ .../(staff)/staff/settings/calendar/page.tsx | 4 +- 4 files changed, 216 insertions(+), 209 deletions(-) diff --git a/src/app/(owner)/owner/reports/page.tsx b/src/app/(owner)/owner/reports/page.tsx index 5e0a980..d065a18 100644 --- a/src/app/(owner)/owner/reports/page.tsx +++ b/src/app/(owner)/owner/reports/page.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { redirect } from "next/navigation"; import { auth } from "@/auth"; import { Card } from "@/components/ui/card"; +import { TopNav } from "@/components/navigation/top-nav"; import { prisma } from "@/lib/db/prisma"; import { hasPermission } from "@/lib/auth/permissions"; import { Permission } from "@/generated/prisma/enums"; @@ -70,132 +71,132 @@ export default async function OwnerReportsPage({ ]); return ( -
-
-

Reports

+
+ +

{fromDate} to {toDate}

-
-
- {PRESETS.map((preset) => ( - - Last {preset.label} - - ))} -
- -
-

Appointments

-
- - - - +
+ {PRESETS.map((preset) => ( + + Last {preset.label} + + ))}
-
- - - -
-
-
-

Services

- - {serviceReport.length === 0 ? ( -

No completed appointments in this range.

- ) : ( - serviceReport.map((s) => ( -
-
-

{s.name}

-

{s.timesCompleted} completed

-
- £{s.revenue} -
- )) - )} -
-
+
+

Appointments

+
+ + + + +
+
+ + + +
+
-
-

Staff

- - {staffReport.length === 0 ? ( -

No appointments in this range.

- ) : ( - staffReport.map((s) => ( -
-
-

{s.name}

-

- {s.completed} completed · {s.cancelled} cancelled · {s.noShow} no-show -

-
- £{s.revenue} -
- )) - )} -
-
- -
-

Customers

-
- - -
- {customerReport.topCustomers.length > 0 && ( +
+

Services

- {customerReport.topCustomers.map((c) => ( -
-
-

{c.name}

-

{c.visits} visit{c.visits === 1 ? "" : "s"}

+ {serviceReport.length === 0 ? ( +

No completed appointments in this range.

+ ) : ( + serviceReport.map((s) => ( +
+
+

{s.name}

+

{s.timesCompleted} completed

+
+ £{s.revenue}
- £{c.spend} -
- ))} + )) + )} - )} -
+
-
-

Loyalty

-
- - - - -
- {loyaltyReport.rewardsExpired > 0 && } -
- -
-

Notifications

-
- - -
- {notificationReport.byChannel.length > 0 && ( +
+

Staff

- {notificationReport.byChannel.map((c) => ( -
- {c.channel} - - {c.sent} sent{c.failed > 0 ? ` · ${c.failed} failed` : ""} - -
- ))} + {staffReport.length === 0 ? ( +

No appointments in this range.

+ ) : ( + staffReport.map((s) => ( +
+
+

{s.name}

+

+ {s.completed} completed · {s.cancelled} cancelled · {s.noShow} no-show +

+
+ £{s.revenue} +
+ )) + )}
- )} -
+
+ +
+

Customers

+
+ + +
+ {customerReport.topCustomers.length > 0 && ( + + {customerReport.topCustomers.map((c) => ( +
+
+

{c.name}

+

{c.visits} visit{c.visits === 1 ? "" : "s"}

+
+ £{c.spend} +
+ ))} +
+ )} +
+ +
+

Loyalty

+
+ + + + +
+ {loyaltyReport.rewardsExpired > 0 && } +
+ +
+

Notifications

+
+ + +
+ {notificationReport.byChannel.length > 0 && ( + + {notificationReport.byChannel.map((c) => ( +
+ {c.channel} + + {c.sent} sent{c.failed > 0 ? ` · ${c.failed} failed` : ""} + +
+ ))} +
+ )} +
+
); } diff --git a/src/app/(owner)/owner/services/page.tsx b/src/app/(owner)/owner/services/page.tsx index 148f5da..f17fc7f 100644 --- a/src/app/(owner)/owner/services/page.tsx +++ b/src/app/(owner)/owner/services/page.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import { redirect } from "next/navigation"; import { auth } from "@/auth"; +import { TopNav } from "@/components/navigation/top-nav"; import { prisma } from "@/lib/db/prisma"; import { hasPermission } from "@/lib/auth/permissions"; import { Permission } from "@/generated/prisma/enums"; @@ -24,28 +25,30 @@ export default async function OwnerServicesPage() { const categories = await listCategories(prisma, context.businessId); return ( -
-

Services

- ({ - id: c.id, - name: c.name, - isActive: c.isActive, - services: c.services.map((s) => ({ - id: s.id, - categoryId: s.categoryId, - name: s.name, - description: s.description ?? "", - imageUrl: s.imageUrl, - durationMinutes: s.durationMinutes, - price: s.price.toString(), - bufferBeforeMinutes: s.bufferBeforeMinutes, - bufferAfterMinutes: s.bufferAfterMinutes, - isActive: s.isActive, - allowOnlineBooking: s.allowOnlineBooking, - })), - }))} - /> +
+ +
+ ({ + id: c.id, + name: c.name, + isActive: c.isActive, + services: c.services.map((s) => ({ + id: s.id, + categoryId: s.categoryId, + name: s.name, + description: s.description ?? "", + imageUrl: s.imageUrl, + durationMinutes: s.durationMinutes, + price: s.price.toString(), + bufferBeforeMinutes: s.bufferBeforeMinutes, + bufferAfterMinutes: s.bufferAfterMinutes, + isActive: s.isActive, + allowOnlineBooking: s.allowOnlineBooking, + })), + }))} + /> +
); } diff --git a/src/app/(owner)/owner/team/page.tsx b/src/app/(owner)/owner/team/page.tsx index 8e221bb..0f49298 100644 --- a/src/app/(owner)/owner/team/page.tsx +++ b/src/app/(owner)/owner/team/page.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { Plus, Search, ShieldCheck, ShieldPlus } from "lucide-react"; import { redirect } from "next/navigation"; import { auth } from "@/auth"; +import { TopNav } from "@/components/navigation/top-nav"; import { prisma } from "@/lib/db/prisma"; import { hasPermission } from "@/lib/auth/permissions"; import { Permission } from "@/generated/prisma/enums"; @@ -30,80 +31,82 @@ export default async function OwnerTeamPage({ const { q = "" } = await searchParams; const staff = await listStaffForBusiness(prisma, { businessId: context.businessId, q, includeInactive: true }); + const headerAction = ( +
+ +
+ ); + return ( -
-
-

Team

-
- -
); } diff --git a/src/app/(staff)/staff/settings/calendar/page.tsx b/src/app/(staff)/staff/settings/calendar/page.tsx index ed8c58f..4eb5f63 100644 --- a/src/app/(staff)/staff/settings/calendar/page.tsx +++ b/src/app/(staff)/staff/settings/calendar/page.tsx @@ -28,8 +28,8 @@ export default async function StaffCalendarSettingsPage() {

- One-way sync: {branding.name} stays the source of truth, and your confirmed appointments are pushed to - Google Calendar. Nothing is ever imported back from Google. + {/* {branding.name} */} + NextChair is where your bookings are managed. Connect your Google Calendar to automatically add confirmed appointments to your personal calendar.