feat(profile): add BookContactButton component to enhance booking functionality

This commit is contained in:
vchikalkin 2025-07-03 16:15:22 +03:00
parent 6eb421bfd4
commit 76de850bf5
3 changed files with 74 additions and 13 deletions

View File

@ -1,7 +1,12 @@
import { getCustomer } from '@/actions/api/customers';
import { Container } from '@/components/layout';
import { PageHeader } from '@/components/navigation';
import { ContactDataCard, PersonCard, ProfileOrdersList } from '@/components/profile';
import {
BookContactButton,
ContactDataCard,
PersonCard,
ProfileOrdersList,
} from '@/components/profile';
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query';
type Props = { params: Promise<{ telegramId: string }> };
@ -24,6 +29,7 @@ export default async function ProfilePage(props: Readonly<Props>) {
<PersonCard telegramId={telegramId} />
<ContactDataCard telegramId={telegramId} />
<ProfileOrdersList telegramId={telegramId} />
<BookContactButton telegramId={telegramId} />
</Container>
</HydrationBoundary>
);

View File

@ -4,6 +4,62 @@ 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();

View File

@ -4,7 +4,7 @@ import { useOrderStore } from './context';
import { type Steps } from './types';
import { useCustomerQuery, useIsMaster } from '@/hooks/api/customers';
import { type OrderFieldsFragment } from '@repo/graphql/types';
import { useCallback, useEffect, useRef } from 'react';
import { useEffect, useRef } from 'react';
const STEPS: Steps[] = [
'master-select',
@ -18,7 +18,6 @@ export const CLIENT_STEPS: Steps[] = STEPS.filter((step) => step !== 'client-sel
export function useInitOrderStore(initData: null | OrderFieldsFragment) {
const initialized = useRef(false);
const { data: { customer } = {} } = useCustomerQuery();
const isMaster = useIsMaster();
@ -29,19 +28,17 @@ export function useInitOrderStore(initData: null | OrderFieldsFragment) {
const setStepsSequence = useOrderStore((store) => store._setStepSequence);
const step = useOrderStore((store) => store.step);
const setFirstStep = useCallback(() => {
const steps = isMaster ? MASTER_STEPS : CLIENT_STEPS;
setStepsSequence(steps);
setStep(steps[0] as Steps);
}, [isMaster, setStep, setStepsSequence]);
useEffect(() => {
if (initialized.current || !customer || step !== 'loading') return;
const steps = isMaster ? MASTER_STEPS : CLIENT_STEPS;
setStepsSequence(steps);
// Инициализация из initData (например, для повторного заказа)
if (initData) {
const masterId = initData.slot?.master?.documentId;
const clientId = initData.client?.documentId;
const serviceId = initData.services[0]?.documentId;
const serviceId = initData.services?.[0]?.documentId;
if (masterId) setMasterId(masterId);
if (clientId) setClientId(clientId);
@ -49,17 +46,20 @@ export function useInitOrderStore(initData: null | OrderFieldsFragment) {
if (masterId && clientId && serviceId) {
setStep('datetime-select');
} else if (masterId && clientId) {
setStep('service-select');
} else {
setFirstStep();
setStep(steps[0] ?? 'loading');
}
} else {
// Обычная инициализация (новый заказ)
if (isMaster) {
setMasterId(customer.documentId);
} else {
setClientId(customer.documentId);
}
setFirstStep();
setStep(steps[0] ?? 'loading');
}
initialized.current = true;
@ -68,7 +68,6 @@ export function useInitOrderStore(initData: null | OrderFieldsFragment) {
initData,
isMaster,
setClientId,
setFirstStep,
setMasterId,
setServiceId,
setStep,