Staff / Owner
Merged staff and owner settings
This commit is contained in:
23 files changed
+693
-236
No files matched your search
@@ -10,7 +10,7 @@ import { EmptyState } from "@/components/feedback/empty-state";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { TopNav } from "@/components/navigation/top-nav";
|
||||
import { prisma } from "@/lib/db/prisma";
|
||||
import { getActingStaff } from "@/lib/staff/get-acting-staff";
|
||||
import { getActingBusinessContext } from "@/lib/business/get-acting-business-context";
|
||||
import { getLoyaltyHistory, getLoyaltySummary } from "@/services/loyalty/loyalty.service";
|
||||
import { resolveRewardThreshold } from "@/services/loyalty/reward-threshold";
|
||||
import { listAppointments } from "@/services/scheduling/appointment.service";
|
||||
@@ -38,8 +38,8 @@ export default async function StaffCustomerDetailsPage({
|
||||
}: {
|
||||
params: Promise<{ id: string }>;
|
||||
}) {
|
||||
const staff = await getActingStaff();
|
||||
if (!staff) redirect("/home");
|
||||
const context = await getActingBusinessContext();
|
||||
if (!context) redirect("/home");
|
||||
|
||||
const { id } = await params;
|
||||
const customer = await prisma.customerProfile.findUnique({
|
||||
@@ -54,7 +54,7 @@ export default async function StaffCustomerDetailsPage({
|
||||
// "Belongs to this business" is via the appointment relation — see
|
||||
// docs/phase-5-summary.md, same reasoning as the clients list query.
|
||||
const belongsToBusiness = await prisma.appointment.findFirst({
|
||||
where: { customerId: id, businessId: staff.businessId },
|
||||
where: { customerId: id, businessId: context.businessId },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!belongsToBusiness) notFound();
|
||||
@@ -62,17 +62,17 @@ export default async function StaffCustomerDetailsPage({
|
||||
const [upcoming, past, cancelled, notesRaw, loyalty] = await Promise.all([
|
||||
listAppointments(prisma, {
|
||||
customerId: id,
|
||||
businessId: staff.businessId,
|
||||
businessId: context.businessId,
|
||||
statuses: ["PENDING", "CONFIRMED", "CHECKED_IN", "IN_PROGRESS"],
|
||||
}),
|
||||
listAppointments(prisma, {
|
||||
customerId: id,
|
||||
businessId: staff.businessId,
|
||||
businessId: context.businessId,
|
||||
statuses: ["COMPLETED"],
|
||||
}),
|
||||
listAppointments(prisma, {
|
||||
customerId: id,
|
||||
businessId: staff.businessId,
|
||||
businessId: context.businessId,
|
||||
statuses: ["CANCELLED", "NO_SHOW"],
|
||||
}),
|
||||
prisma.customerNote.findMany({
|
||||
@@ -80,7 +80,7 @@ export default async function StaffCustomerDetailsPage({
|
||||
orderBy: { createdAt: "desc" },
|
||||
include: { author: { include: { user: { select: { name: true } } } } },
|
||||
}),
|
||||
getLoyaltySummary(prisma, { customerId: id, businessId: staff.businessId }),
|
||||
getLoyaltySummary(prisma, { customerId: id, businessId: context.businessId }),
|
||||
]);
|
||||
|
||||
const loyaltyTransactions = loyalty?.accountId
|
||||
@@ -96,7 +96,7 @@ export default async function StaffCustomerDetailsPage({
|
||||
authorName: n.author.user.name ?? "Staff",
|
||||
}));
|
||||
|
||||
const tz = staff.business.timezone;
|
||||
const tz = context.businessTimezone;
|
||||
|
||||
const renderList = (appointments: typeof upcoming, emptyLabel: string) => {
|
||||
if (appointments.length === 0) {
|
||||
@@ -263,7 +263,13 @@ export default async function StaffCustomerDetailsPage({
|
||||
|
||||
<Card className="p-6">
|
||||
<h2 className="text-muted mb-4 text-sm font-bold tracking-widest uppercase">Notes</h2>
|
||||
<CustomerNotes customerId={customer.id} notes={notes} actingStaffId={staff.id} />
|
||||
{/* A Super Administrator has no StaffProfile/staffId — passing "" is a
|
||||
deliberate never-matches sentinel (see CustomerNotes' isOwn check),
|
||||
so they can view every note but own none. Adding a note as a
|
||||
Super Administrator fails gracefully server-side (see
|
||||
addCustomerNoteAction: "You must be signed in as staff.") rather
|
||||
than fabricating a staff identity for them. */}
|
||||
<CustomerNotes customerId={customer.id} notes={notes} actingStaffId={context.staffId ?? ""} />
|
||||
</Card>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in new issue
Block a user