From 6e91315647553f99ea2a5322d4efa97231f54975 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Fri, 18 Jul 2025 16:17:12 +0300 Subject: [PATCH] refactor(profile): streamline profile and slot pages by integrating session user retrieval and updating booking logic with BookButton component --- .../app/(main)/profile/[telegramId]/page.tsx | 52 +++++++++++------ .../schedule/slots/[documentId]/page.tsx | 13 +++++ apps/web/components/profile/orders-list.tsx | 56 ------------------- apps/web/components/shared/book-button.tsx | 46 +++++++++++++++ 4 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 apps/web/components/shared/book-button.tsx diff --git a/apps/web/app/(main)/profile/[telegramId]/page.tsx b/apps/web/app/(main)/profile/[telegramId]/page.tsx index 1a242b0..8f440d5 100644 --- a/apps/web/app/(main)/profile/[telegramId]/page.tsx +++ b/apps/web/app/(main)/profile/[telegramId]/page.tsx @@ -1,35 +1,55 @@ import { getCustomer } from '@/actions/api/customers'; +import { getSessionUser } from '@/actions/session'; import { Container } from '@/components/layout'; import { PageHeader } from '@/components/navigation'; -import { - BookContactButton, - ContactDataCard, - PersonCard, - ProfileOrdersList, -} from '@/components/profile'; +import { ContactDataCard, PersonCard, ProfileOrdersList } from '@/components/profile'; +import { BookButton } from '@/components/shared/book-button'; +import { isCustomerMaster } from '@repo/utils/customer'; import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'; +// Тип параметров страницы type Props = { params: Promise<{ telegramId: string }> }; export default async function ProfilePage(props: Readonly) { - const parameters = await props.params; - const telegramId = Number.parseInt(parameters.telegramId, 10); - + const { telegramId } = await props.params; + const contactTelegramId = Number(telegramId); const queryClient = new QueryClient(); - await queryClient.prefetchQuery({ - queryFn: () => getCustomer({ telegramId }), - queryKey: ['customer', telegramId], + // Получаем профиль контакта + const { customer: profile } = await queryClient.fetchQuery({ + queryFn: () => getCustomer({ telegramId: contactTelegramId }), + queryKey: ['customer', contactTelegramId], }); + // Получаем текущего пользователя + const sessionUser = await getSessionUser(); + const { customer: currentUser } = await queryClient.fetchQuery({ + queryFn: () => getCustomer({ telegramId: sessionUser.telegramId }), + queryKey: ['customer', sessionUser.telegramId], + }); + + // Проверка наличия данных + if (!profile || !currentUser) return null; + + // Определяем роли и id + const isMaster = isCustomerMaster(currentUser); + const masterId = isMaster ? currentUser.documentId : profile.documentId; + const clientId = isMaster ? profile.documentId : currentUser.documentId; + return ( - - - - + + + + {masterId && clientId && ( + + )} ); diff --git a/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx b/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx index 96ddb94..e31e5a0 100644 --- a/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx +++ b/apps/web/app/(main)/profile/schedule/slots/[documentId]/page.tsx @@ -1,8 +1,11 @@ +import { getCustomer } from '@/actions/api/customers'; import { getSlot } from '@/actions/api/slots'; +import { getSessionUser } from '@/actions/session'; import { Container } from '@/components/layout'; import { PageHeader } from '@/components/navigation'; import { SlotButtons, SlotDateTime, SlotOrdersList } from '@/components/schedule'; import { type SlotPageParameters } from '@/components/schedule/types'; +import { BookButton } from '@/components/shared/book-button'; import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query'; type Props = { params: Promise }; @@ -18,12 +21,22 @@ export default async function SlotPage(props: Readonly) { queryKey: ['slot', documentId], }); + // Получаем текущего пользователя + const sessionUser = await getSessionUser(); + const { customer: currentUser } = await queryClient.fetchQuery({ + queryFn: () => getCustomer({ telegramId: sessionUser.telegramId }), + queryKey: ['customer', sessionUser.telegramId], + }); + + const masterId = currentUser?.documentId; + return ( + {masterId && }
diff --git a/apps/web/components/profile/orders-list.tsx b/apps/web/components/profile/orders-list.tsx index 916d938..75b1ea7 100644 --- a/apps/web/components/profile/orders-list.tsx +++ b/apps/web/components/profile/orders-list.tsx @@ -4,62 +4,6 @@ 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) { - 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 ( -
- -
- ); -} export function ProfileOrdersList({ telegramId }: Readonly) { const { data: { customer } = {} } = useCustomerQuery(); diff --git a/apps/web/components/shared/book-button.tsx b/apps/web/components/shared/book-button.tsx new file mode 100644 index 0000000..c1fb750 --- /dev/null +++ b/apps/web/components/shared/book-button.tsx @@ -0,0 +1,46 @@ +'use client'; + +import { usePushWithData } from '@/hooks/url'; +import { CalendarPlus } from 'lucide-react'; + +type BookButtonProps = { + clientId?: string; + disabled?: boolean; + label: string; + masterId: string; + onBooked?: () => void; +}; + +export function BookButton({ + clientId, + disabled, + label, + masterId, + onBooked, +}: Readonly) { + const push = usePushWithData(); + + const handleBook = () => { + push('/orders/add', { + ...(clientId && { client: { documentId: clientId } }), + slot: { master: { documentId: masterId } }, + }); + onBooked?.(); + }; + + if (!masterId && !clientId) return null; + + return ( +
+ +
+ ); +}