Phase 8
This commit is contained in:
82 files changed
+4903
-287
No files matched your search
@@ -7,6 +7,7 @@ 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";
|
||||
import { getBranding } from "@/lib/business/branding";
|
||||
import { InstallAppButton } from "@/features/pwa/components/install-app-button";
|
||||
|
||||
export const metadata: Metadata = { title: "Owner Settings" };
|
||||
@@ -26,6 +27,7 @@ export default async function OwnerSettingsPage() {
|
||||
|
||||
const canManage = await hasPermission(session.user.id, Permission.MANAGE_STAFF);
|
||||
if (!canManage) redirect("/staff");
|
||||
const branding = await getBranding();
|
||||
|
||||
return (
|
||||
<div className="space-y-6 px-6 pt-12 pb-12">
|
||||
@@ -53,7 +55,7 @@ export default async function OwnerSettingsPage() {
|
||||
|
||||
<div className="rounded-jumbo border-line border bg-white p-5">
|
||||
<p className="mb-3 text-sm font-bold">Get the app</p>
|
||||
<InstallAppButton />
|
||||
<InstallAppButton businessName={branding.name} />
|
||||
</div>
|
||||
|
||||
<SignOutButton />
|
||||
|
||||
@@ -26,10 +26,15 @@ export default async function OwnerStaffDetailPage({ params }: { params: Promise
|
||||
if (!owner) redirect("/staff");
|
||||
|
||||
const { id } = await params;
|
||||
const [target, roles, allServices] = await Promise.all([
|
||||
const [target, roles, allServices, calendarConnection] = await Promise.all([
|
||||
getStaffDetailById(prisma, { staffId: id, businessId: owner.businessId }),
|
||||
listRolesForBusiness(prisma, owner.businessId),
|
||||
prisma.service.findMany({ where: { businessId: owner.businessId, isActive: true }, orderBy: { displayOrder: "asc" } }),
|
||||
// Status only — never tokens (see the brief's "Owners must not see
|
||||
// OAuth tokens, refresh tokens, or unrelated private calendar
|
||||
// events"). Owners can see whether a barber has connected, not
|
||||
// connect on their behalf.
|
||||
prisma.staffCalendarConnection.findUnique({ where: { staffId: id }, select: { revokedAt: true, lastSyncError: true } }),
|
||||
]);
|
||||
if (!target) notFound();
|
||||
|
||||
@@ -72,6 +77,20 @@ export default async function OwnerStaffDetailPage({ params }: { params: Promise
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Card className="p-4">
|
||||
<p className="text-muted mb-1 text-[10px] font-bold tracking-widest uppercase">Google Calendar</p>
|
||||
<p className="text-sm font-bold">
|
||||
{!calendarConnection || calendarConnection.revokedAt
|
||||
? "Not connected"
|
||||
: calendarConnection.lastSyncError
|
||||
? "Sync error"
|
||||
: "Connected"}
|
||||
</p>
|
||||
{calendarConnection?.lastSyncError && !calendarConnection.revokedAt && (
|
||||
<p className="text-danger mt-1 text-xs">{calendarConnection.lastSyncError}</p>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<StaffDetailPanel
|
||||
|
||||
Reference in new issue
Block a user