* web/packages: upgrade next * fix(api/orders): update master validation logic to handle optional masters * fix(api/notify, api/orders): enhance notification messages and update order state handling for masters * fix react typings * refactor(order-buttons, action-panel): streamline button handlers and add return functionality * fix(contacts, orders): replace empty state messages with DataNotFound component for better user feedback * feat(bot): add share bot command and update environment configuration for BOT_URL * fix: pnpm-lock.yaml * feat(bot): implement add contact wizard scene and enhance contact handling logic * feat(profile): add BookContactButton component to enhance booking functionality * fix(order-buttons): update cancel and confirm button logic based on order state * feat(service-select): share services list for all enhance service card display with duration formatting and improve layout
102 lines
2.8 KiB
TypeScript
102 lines
2.8 KiB
TypeScript
'use client';
|
||
|
||
import { OrderCard } from '../shared/order-card';
|
||
import { type ProfileProps } from './types';
|
||
import { useCustomerQuery, useIsMaster } from '@/hooks/api/customers';
|
||
import { useOrdersQuery } from '@/hooks/api/orders';
|
||
import { usePushWithData } from '@/hooks/url';
|
||
import { CalendarPlus } from 'lucide-react';
|
||
|
||
export function BookContactButton({ telegramId }: Readonly<ProfileProps>) {
|
||
const { data: { customer } = {}, isLoading: isCustomerLoading } = useCustomerQuery();
|
||
const isMaster = useIsMaster();
|
||
|
||
const { data: { customer: profile } = {}, isLoading: isProfileLoading } = useCustomerQuery({
|
||
telegramId,
|
||
});
|
||
|
||
const push = usePushWithData();
|
||
|
||
const handleBook = () => {
|
||
if (!profile || !customer) return;
|
||
|
||
if (isMaster) {
|
||
push('/orders/add', {
|
||
client: {
|
||
documentId: profile.documentId,
|
||
},
|
||
slot: {
|
||
master: {
|
||
documentId: customer.documentId,
|
||
},
|
||
},
|
||
});
|
||
} else {
|
||
push('/orders/add', {
|
||
client: {
|
||
documentId: customer.documentId,
|
||
},
|
||
slot: {
|
||
master: {
|
||
documentId: profile.documentId,
|
||
},
|
||
},
|
||
});
|
||
}
|
||
};
|
||
|
||
if (isCustomerLoading || isProfileLoading || !profile || !customer) return null;
|
||
|
||
return (
|
||
<div className="flex flex-col items-center justify-center">
|
||
<button
|
||
className="flex items-center justify-center gap-2 self-center rounded-xl bg-primary/5 px-6 py-2 font-semibold text-primary shadow-sm transition-colors hover:bg-primary/10"
|
||
onClick={handleBook}
|
||
type="button"
|
||
>
|
||
<CalendarPlus className="size-5 text-primary" />
|
||
<span>{isMaster ? 'Записать' : 'Записаться'}</span>
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export function ProfileOrdersList({ telegramId }: Readonly<ProfileProps>) {
|
||
const { data: { customer } = {} } = useCustomerQuery();
|
||
const isMaster = useIsMaster();
|
||
|
||
const { data: { customer: profile } = {} } = useCustomerQuery({ telegramId });
|
||
|
||
const { data: { orders } = {}, isLoading } = useOrdersQuery(
|
||
{
|
||
filters: {
|
||
client: {
|
||
documentId: {
|
||
eq: isMaster ? profile?.documentId : customer?.documentId,
|
||
},
|
||
},
|
||
slot: {
|
||
master: {
|
||
documentId: {
|
||
eq: isMaster ? customer?.documentId : profile?.documentId,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
pagination: {
|
||
limit: 5,
|
||
},
|
||
},
|
||
Boolean(profile?.documentId) && Boolean(customer?.documentId),
|
||
);
|
||
|
||
if (!orders?.length || isLoading) return null;
|
||
|
||
return (
|
||
<div className="flex flex-col space-y-2 px-4">
|
||
<h1 className="font-bold">Общие записи</h1>
|
||
{orders?.map((order) => order && <OrderCard key={order.documentId} showDate {...order} />)}
|
||
</div>
|
||
);
|
||
}
|