From ccfc65ca9bd5b9d5e7bdeae5d4617e01259b5a01 Mon Sep 17 00:00:00 2001 From: Vlad Chikalkin Date: Fri, 18 Jul 2025 17:11:43 +0300 Subject: [PATCH] Fix/bugs features pt 2 (#58) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(profile): comment out change role feature * refactor(orders): update OrderServices and ServiceSelect components to utilize ServiceCard, and enhance service fields with duration in GraphQL types * refactor(schedule): implement forbidden order states to disable editing slots with active orders * fix(deploy): update SSH configuration to use dynamic port from secrets for improved flexibility * refactor(api/orders): simplify order creation logic by removing unnecessary validations and improving error handling * refactor(contact-row): replace role display logic with useIsMaster hook for improved clarity * refactor(profile/orders-list): update header text from "Общие записи" to "Недавние записи" for better clarity gql: GetOrders add sort slot.date:desc * refactor(profile/orders-list): enhance OrderCard component by adding avatarSource prop based on user role * feat(order-form): implement date selection with event highlighting and monthly view for available time slots * refactor(i18n/config): update timeZone from 'Europe/Amsterdam' to 'Europe/Moscow' * refactor(order-form/datetime-select): enhance date selection logic to include slot availability check * refactor(datetime-format): integrate dayjs timezone support with default Moscow timezone for date and time formatting * fix(contact-row): replace useIsMaster hook with isCustomerMaster utility for role display logic * refactor(service-card): replace formatTime with getMinutes for duration display * refactor(order-datetime): update date and time handling to use datetime_start and datetime_end for improved consistency * refactor(profile): streamline profile and slot pages by integrating session user retrieval and updating booking logic with BookButton component * fix(navigation): append query parameter to bottom-nav links and enhance back navigation logic in success page --- .github/workflows/deploy.yml | 10 +- .../app/(main)/profile/[telegramId]/page.tsx | 52 ++++++--- .../schedule/slots/[documentId]/page.tsx | 13 +++ .../navigation/bottom-nav/nav-button.tsx | 2 +- apps/web/components/orders/order-datetime.tsx | 6 +- .../orders/order-form/datetime-select.tsx | 51 +++++++-- .../components/orders/order-form/result.tsx | 24 ++-- .../orders/order-form/service-select.tsx | 29 ++--- .../orders/order-form/submit-button.tsx | 3 +- apps/web/components/orders/order-services.tsx | 13 +-- .../orders/orders-list/date-select.tsx | 23 +++- .../components/orders/orders-list/index.tsx | 14 ++- .../components/profile/data-card/index.tsx | 6 +- apps/web/components/profile/orders-list.tsx | 70 ++---------- apps/web/components/schedule/calendar.tsx | 11 +- .../day-slots-list/day-slot-add-form.tsx | 10 +- .../schedule/day-slots-list/index.tsx | 9 +- .../schedule/day-slots-list/slot-card.tsx | 5 +- .../schedule/slot-datetime/slot-date.tsx | 2 +- .../schedule/slot-datetime/slot-time.tsx | 47 +++++--- apps/web/components/shared/book-button.tsx | 46 ++++++++ apps/web/components/shared/contact-row.tsx | 5 +- apps/web/components/shared/order-card.tsx | 11 +- apps/web/components/shared/service-card.tsx | 32 ++++++ .../components/shared/time-range/readonly.tsx | 18 ++- apps/web/hooks/api/slots.ts | 8 +- apps/web/utils/i18n/config.ts | 4 +- packages/graphql/api/notify.ts | 26 +++-- packages/graphql/api/orders.ts | 71 +++--------- packages/graphql/api/slots.ts | 35 +++--- packages/graphql/graphql.config.cjs | 2 + packages/graphql/operations/orders.graphql | 22 ++-- packages/graphql/operations/slots.graphql | 27 ++--- .../graphql/types/operations.generated.ts | 92 ++++++---------- packages/utils/src/datetime-format.ts | 103 +++++++++++------- 35 files changed, 488 insertions(+), 414 deletions(-) create mode 100644 apps/web/components/shared/book-button.tsx create mode 100644 apps/web/components/shared/service-card.tsx diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index dce5ccc..6c4d101 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -56,11 +56,11 @@ jobs: mkdir -p ~/.ssh echo "${{ secrets.VPS_SSH_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts + ssh-keyscan -p ${{ secrets.VPS_PORT }} -H ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts - name: Ensure zapishis directory exists on VPS run: | - ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} "mkdir -p /home/${{ secrets.VPS_USER }}/zapishis" + ssh -i ~/.ssh/id_rsa -p ${{ secrets.VPS_PORT }} -o StrictHostKeyChecking=no ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} "mkdir -p /home/${{ secrets.VPS_USER }}/zapishis" - name: Create real .env file for production run: | @@ -78,7 +78,7 @@ jobs: host: ${{ secrets.VPS_HOST }} username: ${{ secrets.VPS_USER }} key: ${{ secrets.VPS_SSH_KEY }} - port: 22 + port: ${{ secrets.VPS_PORT }} source: '.env' target: '/home/${{ secrets.VPS_USER }}/zapishis/' @@ -88,13 +88,13 @@ jobs: host: ${{ secrets.VPS_HOST }} username: ${{ secrets.VPS_USER }} key: ${{ secrets.VPS_SSH_KEY }} - port: 22 + port: ${{ secrets.VPS_PORT }} source: 'docker-compose.yml' target: '/home/${{ secrets.VPS_USER }}/zapishis/' - name: Login and deploy on VPS run: | - ssh ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} " + ssh -i ~/.ssh/id_rsa -p ${{ secrets.VPS_PORT }} -o StrictHostKeyChecking=no ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }} " cd /home/${{ secrets.VPS_USER }}/zapishis && \ docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} && \ docker compose pull && \ 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/navigation/bottom-nav/nav-button.tsx b/apps/web/components/navigation/bottom-nav/nav-button.tsx index 73ed3d8..e8dbd99 100644 --- a/apps/web/components/navigation/bottom-nav/nav-button.tsx +++ b/apps/web/components/navigation/bottom-nav/nav-button.tsx @@ -27,7 +27,7 @@ export function NavButton({ disabled, href, icon, label }: NavButtonProps) { {label}
) : ( - + {icon} {label} diff --git a/apps/web/components/orders/order-datetime.tsx b/apps/web/components/orders/order-datetime.tsx index 3abfed0..0538219 100644 --- a/apps/web/components/orders/order-datetime.tsx +++ b/apps/web/components/orders/order-datetime.tsx @@ -13,12 +13,12 @@ export function OrderDateTime({ documentId }: Readonly) { return (
- {formatDate(order.slot?.date).user()} + {order.slot?.datetime_start ? formatDate(order.slot.datetime_start).user() : ''}
); diff --git a/apps/web/components/orders/order-form/datetime-select.tsx b/apps/web/components/orders/order-form/datetime-select.tsx index 7411206..0690e59 100644 --- a/apps/web/components/orders/order-form/datetime-select.tsx +++ b/apps/web/components/orders/order-form/datetime-select.tsx @@ -4,22 +4,54 @@ import { useAvailableTimeSlotsQuery } from '@/hooks/api/slots'; import { useOrderStore } from '@/stores/order'; import { Button } from '@repo/ui/components/ui/button'; import { Calendar } from '@repo/ui/components/ui/calendar'; -import { formatDate } from '@repo/utils/datetime-format'; +import { formatTime } from '@repo/utils/datetime-format'; import dayjs from 'dayjs'; +import { useState } from 'react'; export function DateSelect() { const selectedDate = useOrderStore((store) => store.date); const setDate = useOrderStore((store) => store.setDate); const setTime = useOrderStore((store) => store.setTime); const setSlot = useOrderStore((store) => store.setSlotId); + const masterId = useOrderStore((store) => store.masterId); + const serviceId = useOrderStore((store) => store.serviceId); + + const [selectedMonthDate, setSelectedMonthDate] = useState(new Date()); + + const { data: { slots } = {} } = useAvailableTimeSlotsQuery( + { + filters: { + datetime_start: { + gte: dayjs(selectedMonthDate).startOf('month').startOf('day').toISOString(), + lte: dayjs(selectedMonthDate).endOf('month').endOf('day').toISOString(), + }, + master: { + documentId: { + eq: masterId, + }, + }, + }, + }, + { + service: { + documentId: { + eq: serviceId, + }, + }, + }, + ); return ( { - return dayjs().isAfter(dayjs(date), 'day'); + return ( + dayjs().isAfter(dayjs(date), 'day') || + !slots?.some((slot) => dayjs(slot?.datetime_start).isSame(date, 'day')) + ); }} mode="single" + onMonthChange={(date) => setSelectedMonthDate(date)} onSelect={(date) => { if (date) setDate(date); setTime(null); @@ -47,8 +79,9 @@ export function TimeSelect() { const { data: { times } = {}, isLoading } = useAvailableTimeSlotsQuery( { filters: { - date: { - eq: formatDate(date).db(), + datetime_start: { + gte: dayjs(date).startOf('day').toISOString(), + lte: dayjs(date).endOf('day').toISOString(), }, master: { documentId: { @@ -68,6 +101,7 @@ export function TimeSelect() { if (isLoading || !times) return null; + const getHour = (isoString: string) => dayjs(isoString).hour(); const morning = times.filter(({ time }) => getHour(time) < 12); const afternoon = times?.filter(({ time }) => { const hour = getHour(time); @@ -84,13 +118,6 @@ export function TimeSelect() { ); } -function getHour(time: string) { - const hour = time.split(':')[0]; - if (hour) return Number.parseInt(hour, 10); - - return -1; -} - function TimeSlotsButtons({ times, title, @@ -114,7 +141,7 @@ function TimeSlotsButtons({ }} variant="outline" > - {time} + {formatTime(time).user()} ))} diff --git a/apps/web/components/orders/order-form/result.tsx b/apps/web/components/orders/order-form/result.tsx index 9f09837..feb5051 100644 --- a/apps/web/components/orders/order-form/result.tsx +++ b/apps/web/components/orders/order-form/result.tsx @@ -3,8 +3,8 @@ import { useOrderStore } from '@/stores/order'; import { Button } from '@repo/ui/components/ui/button'; import { Card, CardContent } from '@repo/ui/components/ui/card'; -import { AlertCircle, CheckCircle2, Home, RefreshCw } from 'lucide-react'; -import Link from 'next/link'; +import { AlertCircle, CheckCircle2, RefreshCw } from 'lucide-react'; +import { useRouter, useSearchParams } from 'next/navigation'; export function ErrorPage() { const setStep = useOrderStore((store) => store.setStep); @@ -35,6 +35,19 @@ export function ErrorPage() { } export function SuccessPage() { + const router = useRouter(); + const from = useSearchParams().get('from'); + + const handleBack = () => { + if (from === 'bottom-nav') { + router.push('/'); + } else if (window.history.length > 1) { + router.back(); + } else { + router.push('/'); + } + }; + return (
@@ -46,11 +59,8 @@ export function SuccessPage() {

Готово!

Запись успешно создана

- diff --git a/apps/web/components/orders/order-form/service-select.tsx b/apps/web/components/orders/order-form/service-select.tsx index 5c4ecd9..6e5b384 100644 --- a/apps/web/components/orders/order-form/service-select.tsx +++ b/apps/web/components/orders/order-form/service-select.tsx @@ -1,11 +1,11 @@ 'use client'; import { DataNotFound } from '@/components/shared/alert'; +import { ServiceCard } from '@/components/shared/service-card'; import { useServicesQuery } from '@/hooks/api/services'; import { useOrderStore } from '@/stores/order'; import { type ServiceFieldsFragment } from '@repo/graphql/types'; import { cn } from '@repo/ui/lib/utils'; -import { formatTime } from '@repo/utils/datetime-format'; export function ServiceSelect() { const { data: { services } = {} } = useServicesQuery({}); @@ -14,12 +14,14 @@ export function ServiceSelect() { return (
- {services.map((service) => service && )} + {services.map( + (service) => service && , + )}
); } -function ServiceCard({ documentId, duration, name }: Readonly) { +function ServiceCardRadio({ documentId, ...props }: Readonly) { const serviceId = useOrderStore((store) => store.serviceId); const setServiceId = useOrderStore((store) => store.setServiceId); @@ -32,7 +34,7 @@ function ServiceCard({ documentId, duration, name }: Readonly @@ -44,24 +46,7 @@ function ServiceCard({ documentId, duration, name }: Readonly -
- {name} - - - - - {formatTime(duration).user()} - -
+ ); } diff --git a/apps/web/components/orders/order-form/submit-button.tsx b/apps/web/components/orders/order-form/submit-button.tsx index dbfb398..164a265 100644 --- a/apps/web/components/orders/order-form/submit-button.tsx +++ b/apps/web/components/orders/order-form/submit-button.tsx @@ -4,7 +4,6 @@ import { useOrderCreate } from '@/hooks/api/orders'; import { useOrderStore } from '@/stores/order'; import { Button } from '@repo/ui/components/ui/button'; import { LoadingSpinner } from '@repo/ui/components/ui/spinner'; -import { formatTime } from '@repo/utils/datetime-format'; import { useEffect } from 'react'; export function SubmitButton() { @@ -19,9 +18,9 @@ export function SubmitButton() { createOrder({ input: { client: clientId, + datetime_start: time, services: [serviceId], slot: slotId, - time_start: formatTime(time).db(), }, }); }; diff --git a/apps/web/components/orders/order-services.tsx b/apps/web/components/orders/order-services.tsx index ed3eefd..35ac9d1 100644 --- a/apps/web/components/orders/order-services.tsx +++ b/apps/web/components/orders/order-services.tsx @@ -1,9 +1,8 @@ 'use client'; + +import { ServiceCard } from '../shared/service-card'; import { type OrderComponentProps } from './types'; import { useOrderQuery } from '@/hooks/api/orders'; -import { type ServiceFieldsFragment } from '@repo/graphql/types'; - -type ServiceCardProps = Pick; export function OrderServices({ documentId }: Readonly) { const { data: { order } = {} } = useOrderQuery({ documentId }); @@ -19,11 +18,3 @@ export function OrderServices({ documentId }: Readonly) { ); } - -function ServiceCard({ name }: Readonly) { - return ( -
- {name} -
- ); -} diff --git a/apps/web/components/orders/orders-list/date-select.tsx b/apps/web/components/orders/orders-list/date-select.tsx index 8fed90e..39abf0a 100644 --- a/apps/web/components/orders/orders-list/date-select.tsx +++ b/apps/web/components/orders/orders-list/date-select.tsx @@ -5,7 +5,8 @@ import { useOrdersQuery } from '@/hooks/api/orders'; import { useDateTimeStore } from '@/stores/datetime'; import { HorizontalCalendar } from '@repo/ui/components/ui/horizontal-calendar'; import dayjs from 'dayjs'; -import { useState } from 'react'; +import { sift } from 'radashi'; +import { useMemo, useState } from 'react'; export function DateSelect() { const { data: { customer } = {} } = useCustomerQuery(); @@ -14,7 +15,7 @@ export function DateSelect() { const [currentMonthDate, setCurrentMonthDate] = useState(new Date()); - const { data: { orders } = {} } = useOrdersQuery({ + const { data: { orders } = { orders: [] } } = useOrdersQuery({ filters: { client: { documentId: { @@ -22,9 +23,9 @@ export function DateSelect() { }, }, slot: { - date: { - gte: dayjs(currentMonthDate).startOf('month').format('YYYY-MM-DD'), - lte: dayjs(currentMonthDate).endOf('month').format('YYYY-MM-DD'), + datetime_start: { + gte: dayjs(currentMonthDate).startOf('month').toISOString(), + lte: dayjs(currentMonthDate).endOf('month').toISOString(), }, master: { documentId: { @@ -35,12 +36,22 @@ export function DateSelect() { }, }); + const daysWithOrders = useMemo(() => { + return sift( + orders.map((order) => { + const dateString = order?.slot?.datetime_start; + + return dateString ? new Date(dateString) : undefined; + }), + ); + }, [orders]); + const setSelectedDate = useDateTimeStore((store) => store.setDate); const selectedDate = useDateTimeStore((store) => store.date); return ( new Date(order?.slot?.date))} + daysWithOrders={daysWithOrders} onDateChange={setSelectedDate} onMonthChange={(date) => setCurrentMonthDate(date)} selectedDate={selectedDate} diff --git a/apps/web/components/orders/orders-list/index.tsx b/apps/web/components/orders/orders-list/index.tsx index 1285f6f..3838966 100644 --- a/apps/web/components/orders/orders-list/index.tsx +++ b/apps/web/components/orders/orders-list/index.tsx @@ -4,7 +4,7 @@ import { OrderCard } from '@/components/shared/order-card'; import { useCustomerQuery, useIsMaster } from '@/hooks/api/customers'; import { useOrdersQuery } from '@/hooks/api/orders'; import { useDateTimeStore } from '@/stores/datetime'; -import { formatDate } from '@repo/utils/datetime-format'; +import { getDateUTCRange } from '@repo/utils/datetime-format'; export function ClientsOrdersList() { const { data: { customer } = {} } = useCustomerQuery(); @@ -12,13 +12,15 @@ export function ClientsOrdersList() { const isMaster = useIsMaster(); const selectedDate = useDateTimeStore((store) => store.date); + const { endOfDay, startOfDay } = getDateUTCRange(selectedDate).day(); const { data: { orders } = {}, isLoading } = useOrdersQuery( { filters: { slot: { - date: { - eq: formatDate(selectedDate).db(), + datetime_start: { + gte: startOfDay, + lt: endOfDay, }, master: { documentId: { @@ -45,6 +47,7 @@ export function OrdersList() { const { data: { customer } = {} } = useCustomerQuery(); const selectedDate = useDateTimeStore((store) => store.date); + const { endOfDay, startOfDay } = getDateUTCRange(selectedDate).day(); const { data: { orders } = {}, isLoading } = useOrdersQuery( { @@ -55,8 +58,9 @@ export function OrdersList() { }, }, slot: { - date: { - eq: formatDate(selectedDate).db(), + datetime_start: { + gte: startOfDay, + lt: endOfDay, }, }, }, diff --git a/apps/web/components/profile/data-card/index.tsx b/apps/web/components/profile/data-card/index.tsx index 1aae939..18d74d0 100644 --- a/apps/web/components/profile/data-card/index.tsx +++ b/apps/web/components/profile/data-card/index.tsx @@ -1,11 +1,9 @@ 'use client'; import { type ProfileProps } from '../types'; -import { CheckboxWithText } from './checkbox-field'; import { DataField } from './text-field'; import { CardSectionHeader } from '@/components/ui'; import { useCustomerMutation, useCustomerQuery } from '@/hooks/api/customers'; -import { Enum_Customer_Role as Role } from '@repo/graphql/types'; import { Button } from '@repo/ui/components/ui/button'; import { Card } from '@repo/ui/components/ui/card'; import Link from 'next/link'; @@ -49,7 +47,7 @@ export function ProfileDataCard() { value={customer?.name ?? ''} /> - @@ -58,7 +56,7 @@ export function ProfileDataCard() { }) } text="Быть мастером" - /> + /> */} ); diff --git a/apps/web/components/profile/orders-list.tsx b/apps/web/components/profile/orders-list.tsx index fce90ff..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(); @@ -94,8 +38,18 @@ export function ProfileOrdersList({ telegramId }: Readonly) { return (
-

Общие записи

- {orders?.map((order) => order && )} +

Недавние записи

+ {orders?.map( + (order) => + order && ( + + ), + )}
); } diff --git a/apps/web/components/schedule/calendar.tsx b/apps/web/components/schedule/calendar.tsx index 33506be..76945f3 100644 --- a/apps/web/components/schedule/calendar.tsx +++ b/apps/web/components/schedule/calendar.tsx @@ -4,6 +4,7 @@ import { useCustomerQuery } from '@/hooks/api/customers'; import { useSlotsQuery } from '@/hooks/api/slots'; import { useDateTimeStore } from '@/stores/datetime'; import { Calendar } from '@repo/ui/components/ui/calendar'; +import { getDateUTCRange } from '@repo/utils/datetime-format'; import dayjs from 'dayjs'; import { useState } from 'react'; @@ -15,11 +16,13 @@ export function ScheduleCalendar() { const [currentMonthDate, setCurrentMonthDate] = useState(new Date()); + const { endOfMonth, startOfMonth } = getDateUTCRange(currentMonthDate).month(); + const { data: { slots } = {} } = useSlotsQuery({ filters: { - date: { - gte: dayjs(currentMonthDate).startOf('month').format('YYYY-MM-DD'), - lte: dayjs(currentMonthDate).endOf('month').format('YYYY-MM-DD'), + datetime_start: { + gte: startOfMonth, + lte: endOfMonth, }, master: { documentId: { @@ -38,7 +41,7 @@ export function ScheduleCalendar() { mode="single" modifiers={{ hasEvent: (date) => { - return slots?.some((slot) => dayjs(slot?.date).isSame(date, 'day')) || false; + return slots?.some((slot) => dayjs(slot?.datetime_start).isSame(date, 'day')) || false; }, }} modifiersClassNames={{ diff --git a/apps/web/components/schedule/day-slots-list/day-slot-add-form.tsx b/apps/web/components/schedule/day-slots-list/day-slot-add-form.tsx index 62c0161..d9c9a3e 100644 --- a/apps/web/components/schedule/day-slots-list/day-slot-add-form.tsx +++ b/apps/web/components/schedule/day-slots-list/day-slot-add-form.tsx @@ -8,7 +8,7 @@ import { ScheduleStoreProvider, useScheduleStore } from '@/stores/schedule'; import { withContext } from '@/utils/context'; import { Enum_Slot_State } from '@repo/graphql/types'; import { Button } from '@repo/ui/components/ui/button'; -import { formatDate, formatTime } from '@repo/utils/datetime-format'; +import { combineDateAndTimeToUTC } from '@repo/utils/datetime-format'; import { PlusSquare } from 'lucide-react'; import { type FormEvent } from 'react'; @@ -23,15 +23,15 @@ export const DaySlotAddForm = withContext(ScheduleStoreProvider)(function () { const handleSubmit = (event: FormEvent) => { event.preventDefault(); if (startTime && endTime) { + const datetimeStart = combineDateAndTimeToUTC(selectedDate, startTime); + const datetimeEnd = combineDateAndTimeToUTC(selectedDate, endTime); addSlot({ input: { - date: formatDate(selectedDate).db(), + datetime_end: datetimeEnd, + datetime_start: datetimeStart, state: Enum_Slot_State.Open, - time_end: formatTime(endTime).db(), - time_start: formatTime(startTime).db(), }, }); - resetTime(); } }; diff --git a/apps/web/components/schedule/day-slots-list/index.tsx b/apps/web/components/schedule/day-slots-list/index.tsx index 7cddfde..3f9b472 100644 --- a/apps/web/components/schedule/day-slots-list/index.tsx +++ b/apps/web/components/schedule/day-slots-list/index.tsx @@ -6,22 +6,21 @@ import { useCustomerQuery } from '@/hooks/api/customers'; import { useMasterSlotsQuery } from '@/hooks/api/slots'; import { useDateTimeStore } from '@/stores/datetime'; import { LoadingSpinner } from '@repo/ui/components/ui/spinner'; -import { formatDate } from '@repo/utils/datetime-format'; +import { getDateUTCRange } from '@repo/utils/datetime-format'; export function DaySlotsList() { const { data: { customer } = {} } = useCustomerQuery(); - const selectedDate = useDateTimeStore((store) => store.date); + const { endOfDay, startOfDay } = getDateUTCRange(selectedDate).day(); + const { data: { slots } = {}, isLoading } = useMasterSlotsQuery({ filters: { - date: { eq: formatDate(selectedDate).db() }, + datetime_start: { gte: startOfDay, lt: endOfDay }, master: { documentId: { eq: customer?.documentId } }, }, }); - if (isLoading) return ; - return (

Слоты

diff --git a/apps/web/components/schedule/day-slots-list/slot-card.tsx b/apps/web/components/schedule/day-slots-list/slot-card.tsx index 147aaef..5dcc9cf 100644 --- a/apps/web/components/schedule/day-slots-list/slot-card.tsx +++ b/apps/web/components/schedule/day-slots-list/slot-card.tsx @@ -23,7 +23,10 @@ export function SlotCard(props: Readonly) {
- + ) { return ( - {formatDate(slot?.date).user()} + {formatDate(slot?.datetime_start).user()} ); } diff --git a/apps/web/components/schedule/slot-datetime/slot-time.tsx b/apps/web/components/schedule/slot-datetime/slot-time.tsx index fb585c4..8aab074 100644 --- a/apps/web/components/schedule/slot-datetime/slot-time.tsx +++ b/apps/web/components/schedule/slot-datetime/slot-time.tsx @@ -1,3 +1,4 @@ +/* eslint-disable canonical/id-match */ /* eslint-disable react/jsx-no-bind */ 'use client'; @@ -5,14 +6,15 @@ import { type SlotComponentProps } from '../types'; import { EditableTimeRangeForm, ReadonlyTimeRange } from '@/components/shared/time-range'; import { useSlotMutation, useSlotQuery } from '@/hooks/api/slots'; import { useScheduleStore } from '@/stores/schedule'; +import { Enum_Order_State } from '@repo/graphql/types'; import { Button } from '@repo/ui/components/ui/button'; -import { formatTime } from '@repo/utils/datetime-format'; +import { combineDateAndTimeToUTC, formatTime } from '@repo/utils/datetime-format'; +import dayjs from 'dayjs'; import { PencilLine } from 'lucide-react'; import { useEffect } from 'react'; export function SlotTime(props: Readonly) { const editMode = useScheduleStore((state) => state.editMode); - return editMode ? : ; } @@ -20,21 +22,25 @@ function SlotTimeEditForm({ documentId }: Readonly) { const { editMode, endTime, resetTime, setEditMode, setEndTime, setStartTime, startTime } = useScheduleStore((state) => state); const { isPending: isMutationPending, mutate: updateSlot } = useSlotMutation({ documentId }); - const { data: { slot } = {}, isPending: isQueryPending } = useSlotQuery({ documentId }); - const isPending = isMutationPending || isQueryPending; useEffect(() => { - if (editMode) { - if (slot?.time_start) setStartTime(slot.time_start); - if (slot?.time_end) setEndTime(slot.time_end); + if (editMode && slot?.datetime_start && slot?.datetime_end) { + setStartTime(formatTime(slot.datetime_start).user()); + setEndTime(formatTime(slot.datetime_end).user()); } }, [editMode, setEndTime, setStartTime, slot]); function handleSubmit() { + if (!slot?.datetime_start) return; + const date = slot.datetime_start; // ISO-строка, год-месяц-день и время + const dateOnly = dayjs(date).format('YYYY-MM-DD'); // Получаем только дату + + const newDatetimeStart = combineDateAndTimeToUTC(dateOnly, startTime); + const newDatetimeEnd = combineDateAndTimeToUTC(dateOnly, endTime); updateSlot({ - data: { time_end: formatTime(endTime).db(), time_start: formatTime(startTime).db() }, + data: { datetime_end: newDatetimeEnd, datetime_start: newDatetimeStart }, }); resetTime(); setEditMode(false); @@ -42,28 +48,37 @@ function SlotTimeEditForm({ documentId }: Readonly) { return ( - ); } +const FORBIDDEN_ORDER_STATES: Enum_Order_State[] = [ + Enum_Order_State.Scheduled, + Enum_Order_State.Approved, + Enum_Order_State.Completed, + Enum_Order_State.Cancelling, +]; + function SlotTimeReadonly({ documentId }: Readonly) { const setEditMode = useScheduleStore((state) => state.setEditMode); - const { data: { slot } = {} } = useSlotQuery({ documentId }); - if (!slot) return null; - - const hasOrders = Boolean(slot?.orders.length); - + const disabledEdit = slot?.orders.some( + (order) => order?.state && FORBIDDEN_ORDER_STATES.includes(order?.state), + ); return (
- + +
+ ); +} diff --git a/apps/web/components/shared/contact-row.tsx b/apps/web/components/shared/contact-row.tsx index d2a462a..cd81e63 100644 --- a/apps/web/components/shared/contact-row.tsx +++ b/apps/web/components/shared/contact-row.tsx @@ -1,7 +1,8 @@ -import * as GQL from '@repo/graphql/types'; +import type * as GQL from '@repo/graphql/types'; import { Avatar, AvatarFallback, AvatarImage } from '@repo/ui/components/ui/avatar'; import { Badge } from '@repo/ui/components/ui/badge'; import { cn } from '@repo/ui/lib/utils'; +import { isCustomerMaster } from '@repo/utils/customer'; import Link from 'next/link'; import { memo } from 'react'; @@ -31,7 +32,7 @@ export const ContactRow = memo(function ({ className, ...contact }: ContactRowPr

{contact.name}

- {contact.role === GQL.Enum_Customer_Role.Client ? 'Клиент' : 'Мастер'} + {isCustomerMaster(contact) ? 'Мастер' : 'Клиент'}

diff --git a/apps/web/components/shared/order-card.tsx b/apps/web/components/shared/order-card.tsx index 7439acd..72987e2 100644 --- a/apps/web/components/shared/order-card.tsx +++ b/apps/web/components/shared/order-card.tsx @@ -21,8 +21,6 @@ export function OrderCard({ ...order }: Readonly) { const services = order?.services.map((service) => service?.name).join(', '); - const date = order?.slot?.date; - const customer = avatarSource === 'master' ? order?.slot?.master : order?.client; return ( @@ -37,9 +35,14 @@ export function OrderCard({
{customer && }
- + - {showDate ? `${formatDate(date).user('DD.MM.YYYY')} • ` : ''} + {showDate && order?.slot?.datetime_start + ? `${formatDate(order?.slot?.datetime_start).user('DD.MM.YYYY')} • ` + : ''} {services}
diff --git a/apps/web/components/shared/service-card.tsx b/apps/web/components/shared/service-card.tsx new file mode 100644 index 0000000..dee7280 --- /dev/null +++ b/apps/web/components/shared/service-card.tsx @@ -0,0 +1,32 @@ +'use client'; + +import { type ServiceFieldsFragment } from '@repo/graphql/types'; +import { cn } from '@repo/ui/lib/utils'; +import { getMinutes } from '@repo/utils/datetime-format'; + +type ServiceCardProps = Pick; + +export function ServiceCard({ duration, name }: Readonly) { + return ( +
+
+ {name} + + + + + {getMinutes(duration) + ' мин'} + +
+
+ ); +} diff --git a/apps/web/components/shared/time-range/readonly.tsx b/apps/web/components/shared/time-range/readonly.tsx index 4aecf6f..f645ca5 100644 --- a/apps/web/components/shared/time-range/readonly.tsx +++ b/apps/web/components/shared/time-range/readonly.tsx @@ -3,16 +3,24 @@ import { formatTime } from '@repo/utils/datetime-format'; type TimeRangeProps = { readonly className?: string; - readonly timeEnd: null | string | undefined; - readonly timeStart: null | string | undefined; + readonly datetimeEnd: null | string | undefined; + readonly datetimeStart: null | string | undefined; }; -export function ReadonlyTimeRange({ className, timeEnd, timeStart }: Readonly) { +export function ReadonlyTimeRange({ + className, + datetimeEnd, + datetimeStart, +}: Readonly) { return (
- {timeStart ? formatTime(timeStart).user() : 'xx:xx'} + + {datetimeStart ? formatTime(datetimeStart).user() : 'xx:xx'} + {' - '} - {timeEnd ? formatTime(timeEnd).user() : 'xx:xx'} + + {datetimeEnd ? formatTime(datetimeEnd).user() : 'xx:xx'} +
); } diff --git a/apps/web/hooks/api/slots.ts b/apps/web/hooks/api/slots.ts index 5a53042..b8df070 100644 --- a/apps/web/hooks/api/slots.ts +++ b/apps/web/hooks/api/slots.ts @@ -1,5 +1,4 @@ 'use client'; - import { useCustomerQuery } from './customers'; import { createSlot, @@ -10,21 +9,20 @@ import { updateSlot, } from '@/actions/api/slots'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import dayjs from 'dayjs'; type UseMasterSlotsVariables = { filters: Required< - Pick[0]['filters']>, 'date' | 'master'> + Pick[0]['filters']>, 'datetime_start' | 'master'> >; }; export const useMasterSlotsQuery = (variables: UseMasterSlotsVariables) => { const masterId = variables.filters?.master?.documentId?.eq; - const date = variables.filters?.date?.eq; + const datetimeStart = variables.filters?.datetime_start; return useQuery({ queryFn: () => getSlots(variables), - queryKey: ['slots', masterId, dayjs(date).format('YYYY-MM-DD')], + queryKey: ['slots', masterId, datetimeStart], }); }; diff --git a/apps/web/utils/i18n/config.ts b/apps/web/utils/i18n/config.ts index e8c56be..130a2d9 100644 --- a/apps/web/utils/i18n/config.ts +++ b/apps/web/utils/i18n/config.ts @@ -1,8 +1,8 @@ export const defaultLocale = 'ru'; -export const timeZone = 'Europe/Amsterdam'; +export const timeZone = 'Europe/Moscow'; -export const locales = [defaultLocale, 'en'] as const; +export const locales = [defaultLocale, 'ru'] as const; export const localesMap = [ { key: 'en', title: 'English' }, diff --git a/packages/graphql/api/notify.ts b/packages/graphql/api/notify.ts index 2550604..e23ed93 100644 --- a/packages/graphql/api/notify.ts +++ b/packages/graphql/api/notify.ts @@ -1,3 +1,4 @@ +/* eslint-disable complexity */ import * as GQL from '../types'; import { notifyByTelegramId } from '../utils/notify'; import { BaseService } from './base'; @@ -6,7 +7,7 @@ import { OrdersService } from './orders'; import { ServicesService } from './services'; import { SlotsService } from './slots'; import { type VariablesOf } from '@graphql-typed-document-node/core'; -import { formatDate, formatTime, sumTime } from '@repo/utils/datetime-format'; +import { formatDate, formatTime, getMinutes, sumTime } from '@repo/utils/datetime-format'; const STATE_MAP = { approved: 'Одобрено', @@ -19,9 +20,7 @@ const STATE_MAP = { }; export class NotifyService extends BaseService { async orderCreated( - variables: { - input: Omit['input'], 'time_end'>; - }, + variables: VariablesOf, createdByMaster: boolean, ) { const customersService = new CustomersService(this.customer); @@ -30,9 +29,10 @@ export class NotifyService extends BaseService { const slotId = String(variables.input.slot ?? ''); const serviceId = String(variables.input.services?.[0] ?? ''); - const timeStart = String(variables.input.time_start ?? ''); const clientId = String(variables.input.client ?? ''); + if (!serviceId || !clientId || !slotId) return; + let emoji = '🆕'; let confirmText = ''; if (createdByMaster) { @@ -47,10 +47,12 @@ export class NotifyService extends BaseService { }); const { customer: client } = await customersService.getCustomer({ documentId: clientId }); - const slotDate = formatDate(slot?.date).user(); - const timeStartString = formatTime(timeStart).user(); + if (!slot?.datetime_start || !variables.input.datetime_start || !service?.duration) return; + + const slotDate = formatDate(slot?.datetime_start).user(); + const timeStartString = formatTime(variables.input.datetime_start).user(); const timeEndString = formatTime( - service?.duration ? sumTime(timeStart, service.duration) : timeStart, + sumTime(variables.input.datetime_start, getMinutes(service?.duration)), ).user(); // Мастеру @@ -73,14 +75,16 @@ export class NotifyService extends BaseService { if (!order) return; const slot = order.slot; + if (!slot) return; + const service = order.services[0]; const master = slot?.master; const client = order.client; const orderStateString = STATE_MAP[order.state || 'unknown']; - const slotDate = formatDate(slot?.date).user(); - const timeStartString = formatTime(order.time_start ?? '').user(); - const timeEndString = formatTime(order.time_end ?? '').user(); + const slotDate = formatDate(slot?.datetime_start).user(); + const timeStartString = formatTime(order.datetime_start ?? '').user(); + const timeEndString = formatTime(order.datetime_end ?? '').user(); let emoji = '✏️'; if (order.state === GQL.Enum_Order_State.Cancelled) { diff --git a/packages/graphql/api/orders.ts b/packages/graphql/api/orders.ts index 1702a6a..696f8e5 100644 --- a/packages/graphql/api/orders.ts +++ b/packages/graphql/api/orders.ts @@ -1,22 +1,17 @@ -/* eslint-disable sonarjs/cognitive-complexity */ -/* eslint-disable canonical/id-match */ import { getClientWithToken } from '../apollo/client'; import * as GQL from '../types'; -import { Enum_Slot_State } from '../types'; import { BaseService } from './base'; import { CustomersService } from './customers'; import { NotifyService } from './notify'; import { ServicesService } from './services'; -import { SlotsService } from './slots'; import { type VariablesOf } from '@graphql-typed-document-node/core'; import { isCustomerMaster } from '@repo/utils/customer'; -import { formatTime, sumTime } from '@repo/utils/datetime-format'; +import { getMinutes } from '@repo/utils/datetime-format'; +import dayjs from 'dayjs'; const ERRORS = { - INVALID_CLIENT: 'Invalid client', - INVALID_MASTER: 'Invalid master', INVALID_SERVICE_DURATION: 'Invalid service duration', - MISSING_CLIENT: 'Missing client id', + MISSING_CLIENT: 'Missing client', MISSING_ORDER: 'Order not found', MISSING_SERVICE_ID: 'Missing service id', MISSING_SERVICES: 'Missing services', @@ -24,69 +19,31 @@ const ERRORS = { MISSING_START_TIME: 'Missing time start', MISSING_USER: 'User not found', NO_PERMISSION: 'No permission', - SLOT_CLOSED: 'Slot is closed', }; export class OrdersService extends BaseService { - async createOrder(variables: { - input: Omit['input'], 'time_end'>; - }) { + async createOrder(variables: VariablesOf) { + // Проверки на существование обязательных полей для предотвращения ошибок типов if (!variables.input.slot) throw new Error(ERRORS.MISSING_SLOT); - if (!variables.input.client) throw new Error(ERRORS.MISSING_CLIENT); if (!variables.input.services?.length) throw new Error(ERRORS.MISSING_SERVICES); if (!variables.input.services[0]) throw new Error(ERRORS.MISSING_SERVICE_ID); - if (!variables.input.time_start) throw new Error(ERRORS.MISSING_START_TIME); + if (!variables.input.datetime_start) throw new Error(ERRORS.MISSING_START_TIME); + if (!variables.input.client) throw new Error(ERRORS.MISSING_CLIENT); const customersService = new CustomersService(this.customer); - const slotsService = new SlotsService(this.customer); const servicesService = new ServicesService(this.customer); const { customer } = await customersService.getCustomer(this.customer); - if (!customer) throw new Error(ERRORS.MISSING_USER); - const { slot } = await slotsService.getSlot({ documentId: variables.input.slot }); - - if (slot?.state === Enum_Slot_State.Closed) { - throw new Error(ERRORS.SLOT_CLOSED); - } - - const isMaster = isCustomerMaster(customer); - - if (!isMaster) { - if (customer.documentId !== variables.input.client) { - throw new Error(ERRORS.INVALID_CLIENT); - } - - const { customers } = await customersService.getMasters(this.customer); - const masters = customers.at(0)?.masters; - - const masterId = slot?.master?.documentId; - if (!masters?.some((master) => master?.documentId === masterId)) { - throw new Error(ERRORS.INVALID_MASTER); - } - } - - if (isMaster) { - const { customers: myMasters } = await customersService.getMasters(this.customer); - - const clientId = variables.input.client; - const isTryingToRecordMaster = myMasters.some((master) => master?.documentId === clientId); - - if (isTryingToRecordMaster) throw new Error(ERRORS.INVALID_CLIENT); - } - - if (isMaster && slot?.master?.documentId !== customer.documentId) { - throw new Error(ERRORS.INVALID_MASTER); - } - const { service } = await servicesService.getService({ documentId: variables.input.services[0], }); - if (!service?.duration) throw new Error(ERRORS.INVALID_SERVICE_DURATION); - const endTime = sumTime(variables.input.time_start, service?.duration); + const datetimeEnd = dayjs(variables.input.datetime_start) + .add(getMinutes(service.duration), 'minute') + .toISOString(); const { mutate } = await getClientWithToken(); @@ -96,8 +53,10 @@ export class OrdersService extends BaseService { ...variables, input: { ...variables.input, - state: isMaster ? GQL.Enum_Order_State.Approved : GQL.Enum_Order_State.Created, - time_end: formatTime(endTime).db(), + datetime_end: datetimeEnd, + state: isCustomerMaster(customer) + ? GQL.Enum_Order_State.Approved + : GQL.Enum_Order_State.Created, }, }, }); @@ -107,7 +66,7 @@ export class OrdersService extends BaseService { // Уведомление об создании заказа const notifyService = new NotifyService(this.customer); - notifyService.orderCreated(variables, isMaster); + notifyService.orderCreated(variables, isCustomerMaster(customer)); return mutationResult.data; } diff --git a/packages/graphql/api/slots.ts b/packages/graphql/api/slots.ts index c1a50d5..e5473b7 100644 --- a/packages/graphql/api/slots.ts +++ b/packages/graphql/api/slots.ts @@ -50,6 +50,9 @@ export class SlotsService extends BaseService { variables: VariablesOf, context: { service: GQL.ServiceFiltersInput }, ) { + if (!variables.filters?.datetime_start) throw new Error('Missing date'); + if (!context?.service?.documentId?.eq) throw new Error('Missing service id'); + const { query } = await getClientWithToken(); const getSlotsResult = await query({ @@ -66,8 +69,6 @@ export class SlotsService extends BaseService { const servicesService = new ServicesService(this.customer); - if (!context?.service?.documentId?.eq) throw new Error('Missing service id'); - const { service } = await servicesService.getService({ documentId: context.service.documentId.eq, }); @@ -76,38 +77,36 @@ export class SlotsService extends BaseService { const serviceDuration = getMinutes(service.duration); - const openedSlots = getSlotsResult.data.slots; + const slots = getSlotsResult.data.slots; const times: Array<{ slotId: string; time: string }> = []; - for (const slot of openedSlots) { - if (!slot?.time_start || !slot?.time_end) continue; + for (const slot of slots) { + if (!slot?.datetime_start || !slot?.datetime_end) continue; - let startTime = dayjs(`${slot.date} ${slot.time_start}`); - const endTime = dayjs(`${slot.date} ${slot.time_end}`).subtract(serviceDuration, 'minutes'); + let datetimeStart = dayjs(slot.datetime_start); + const datetimeEnd = dayjs(slot.datetime_end).subtract(serviceDuration, 'minutes'); - while (startTime.valueOf() <= endTime.valueOf()) { - const slotStartTime = startTime; - const potentialEndTime = startTime.add(serviceDuration, 'minutes'); + while (datetimeStart.valueOf() <= datetimeEnd.valueOf()) { + const slotStartTime = datetimeStart; + const potentialDatetimeEnd = datetimeStart.add(serviceDuration, 'minutes'); const hasConflict = slot.orders.some( (order) => order?.state && - ![GQL.Enum_Order_State.Cancelled, GQL.Enum_Order_State.Completed].includes( - order.state, - ) && - slotStartTime.isBefore(dayjs(`${slot.date} ${order.time_end}`)) && - potentialEndTime.isAfter(dayjs(`${slot.date} ${order.time_start}`)), + ![GQL.Enum_Order_State.Cancelled].includes(order.state) && + slotStartTime.isBefore(dayjs(order.datetime_end)) && + potentialDatetimeEnd.isAfter(dayjs(order.datetime_start)), ); if (!hasConflict) { - times.push({ slotId: slot.documentId, time: startTime.format('HH:mm') }); + times.push({ slotId: slot.documentId, time: datetimeStart.toISOString() }); } - startTime = startTime.add(15, 'minutes'); + datetimeStart = datetimeStart.add(15, 'minutes'); } } - return { times }; + return { slots, times }; } async getSlot(variables: VariablesOf) { diff --git a/packages/graphql/graphql.config.cjs b/packages/graphql/graphql.config.cjs index 1c82209..18d2971 100644 --- a/packages/graphql/graphql.config.cjs +++ b/packages/graphql/graphql.config.cjs @@ -8,6 +8,8 @@ module.exports = { maybeValue: 'T | null | undefined', onlyOperationTypes: true, scalars: { + Date: 'string', + DateTime: 'string', Long: 'number', Time: 'string', }, diff --git a/packages/graphql/operations/orders.graphql b/packages/graphql/operations/orders.graphql index dcdd0fe..0267d1c 100644 --- a/packages/graphql/operations/orders.graphql +++ b/packages/graphql/operations/orders.graphql @@ -1,30 +1,26 @@ fragment OrderFields on Order { documentId - time_start - time_end + datetime_start + datetime_end state order_number services { - documentId - name + ...ServiceFields } client { ...CustomerFields } slot { - date - master { - ...CustomerFields - } - } - services { - documentId - name + ...SlotFields } } query GetOrders($filters: OrderFiltersInput, $pagination: PaginationArg) { - orders(filters: $filters, sort: "time_start:asc", pagination: $pagination) { + orders( + filters: $filters + sort: ["slot.datetime_start:desc", "datetime_start:asc"] + pagination: $pagination + ) { ...OrderFields } } diff --git a/packages/graphql/operations/slots.graphql b/packages/graphql/operations/slots.graphql index 1c1ebb7..485ec17 100644 --- a/packages/graphql/operations/slots.graphql +++ b/packages/graphql/operations/slots.graphql @@ -1,9 +1,11 @@ fragment SlotFields on Slot { documentId - date - time_start - time_end + datetime_start + datetime_end state + master { + ...CustomerFields + } } mutation CreateSlot($input: SlotInput!) { @@ -13,32 +15,27 @@ mutation CreateSlot($input: SlotInput!) { } query GetSlots($filters: SlotFiltersInput) { - slots(filters: $filters, sort: "time_start:asc") { + slots(filters: $filters, sort: "datetime_start:asc") { ...SlotFields } } query GetSlotsOrders($filters: SlotFiltersInput) { - slots(filters: $filters, sort: "time_start:asc") { + slots(filters: $filters, sort: "datetime_start:asc") { ...SlotFields - orders(sort: "time_start:asc") { - documentId - state - time_start - time_end + orders(sort: "datetime_start:asc") { + ...OrderFields } } } query GetSlot($documentId: ID!) { slot(documentId: $documentId) { - orders(sort: "time_start:asc") { - documentId - time_start - time_end + orders(sort: "datetime_start:asc") { + ...OrderFields } master { - documentId + ...CustomerFields } ...SlotFields } diff --git a/packages/graphql/types/operations.generated.ts b/packages/graphql/types/operations.generated.ts index b763eb2..dece7ba 100644 --- a/packages/graphql/types/operations.generated.ts +++ b/packages/graphql/types/operations.generated.ts @@ -13,8 +13,7 @@ export type Scalars = { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } - Date: { input: any; output: any; } - DateTime: { input: any; output: any; } + DateTime: { input: string; output: string; } JSON: { input: any; output: any; } Long: { input: number; output: number; } Time: { input: string; output: string; } @@ -113,31 +112,6 @@ export type CustomerInput = { telegramId?: InputMaybe; }; -export type DateFilterInput = { - and?: InputMaybe>>; - between?: InputMaybe>>; - contains?: InputMaybe; - containsi?: InputMaybe; - endsWith?: InputMaybe; - eq?: InputMaybe; - eqi?: InputMaybe; - gt?: InputMaybe; - gte?: InputMaybe; - in?: InputMaybe>>; - lt?: InputMaybe; - lte?: InputMaybe; - ne?: InputMaybe; - nei?: InputMaybe; - not?: InputMaybe; - notContains?: InputMaybe; - notContainsi?: InputMaybe; - notIn?: InputMaybe>>; - notNull?: InputMaybe; - null?: InputMaybe; - or?: InputMaybe>>; - startsWith?: InputMaybe; -}; - export type DateTimeFilterInput = { and?: InputMaybe>>; between?: InputMaybe>>; @@ -337,6 +311,8 @@ export type OrderFiltersInput = { block?: InputMaybe; client?: InputMaybe; createdAt?: InputMaybe; + datetime_end?: InputMaybe; + datetime_start?: InputMaybe; documentId?: InputMaybe; not?: InputMaybe; or?: InputMaybe>>; @@ -347,14 +323,14 @@ export type OrderFiltersInput = { services?: InputMaybe; slot?: InputMaybe; state?: InputMaybe; - time_end?: InputMaybe; - time_start?: InputMaybe; updatedAt?: InputMaybe; }; export type OrderInput = { block?: InputMaybe; client?: InputMaybe; + datetime_end?: InputMaybe; + datetime_start?: InputMaybe; order_number?: InputMaybe; price?: InputMaybe; publishedAt?: InputMaybe; @@ -362,8 +338,6 @@ export type OrderInput = { services?: InputMaybe>>; slot?: InputMaybe; state?: InputMaybe; - time_end?: InputMaybe; - time_start?: InputMaybe; }; export type PaginationArg = { @@ -461,7 +435,8 @@ export type SettingInput = { export type SlotFiltersInput = { and?: InputMaybe>>; createdAt?: InputMaybe; - date?: InputMaybe; + datetime_end?: InputMaybe; + datetime_start?: InputMaybe; documentId?: InputMaybe; master?: InputMaybe; not?: InputMaybe; @@ -469,19 +444,16 @@ export type SlotFiltersInput = { orders?: InputMaybe; publishedAt?: InputMaybe; state?: InputMaybe; - time_end?: InputMaybe; - time_start?: InputMaybe; updatedAt?: InputMaybe; }; export type SlotInput = { - date?: InputMaybe; + datetime_end?: InputMaybe; + datetime_start?: InputMaybe; master?: InputMaybe; orders?: InputMaybe>>; publishedAt?: InputMaybe; state?: InputMaybe; - time_end?: InputMaybe; - time_start?: InputMaybe; }; export type StringFilterInput = { @@ -695,7 +667,7 @@ export type UpdateCustomerMutationVariables = Exact<{ export type UpdateCustomerMutation = { __typename?: 'Mutation', updateCustomer?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined }; -export type OrderFieldsFragment = { __typename?: 'Order', documentId: string, time_start?: string | null | undefined, time_end?: string | null | undefined, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', date?: any | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined }; +export type OrderFieldsFragment = { __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined }; export type GetOrdersQueryVariables = Exact<{ filters?: InputMaybe; @@ -703,21 +675,21 @@ export type GetOrdersQueryVariables = Exact<{ }>; -export type GetOrdersQuery = { __typename?: 'Query', orders: Array<{ __typename?: 'Order', documentId: string, time_start?: string | null | undefined, time_end?: string | null | undefined, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', date?: any | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined> }; +export type GetOrdersQuery = { __typename?: 'Query', orders: Array<{ __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined> }; export type GetOrderQueryVariables = Exact<{ documentId: Scalars['ID']['input']; }>; -export type GetOrderQuery = { __typename?: 'Query', order?: { __typename?: 'Order', documentId: string, time_start?: string | null | undefined, time_end?: string | null | undefined, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', date?: any | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined }; +export type GetOrderQuery = { __typename?: 'Query', order?: { __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined }; export type CreateOrderMutationVariables = Exact<{ input: OrderInput; }>; -export type CreateOrderMutation = { __typename?: 'Mutation', createOrder?: { __typename?: 'Order', documentId: string, time_start?: string | null | undefined, time_end?: string | null | undefined, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', date?: any | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined }; +export type CreateOrderMutation = { __typename?: 'Mutation', createOrder?: { __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined }; export type UpdateOrderMutationVariables = Exact<{ documentId: Scalars['ID']['input']; @@ -725,7 +697,7 @@ export type UpdateOrderMutationVariables = Exact<{ }>; -export type UpdateOrderMutation = { __typename?: 'Mutation', updateOrder?: { __typename?: 'Order', documentId: string, time_start?: string | null | undefined, time_end?: string | null | undefined, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', date?: any | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined }; +export type UpdateOrderMutation = { __typename?: 'Mutation', updateOrder?: { __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined }; export type ServiceFieldsFragment = { __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string }; @@ -743,35 +715,35 @@ export type GetServiceQueryVariables = Exact<{ export type GetServiceQuery = { __typename?: 'Query', service?: { __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined }; -export type SlotFieldsFragment = { __typename?: 'Slot', documentId: string, date?: any | null | undefined, time_start: string, time_end: string, state?: Enum_Slot_State | null | undefined }; +export type SlotFieldsFragment = { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined }; export type CreateSlotMutationVariables = Exact<{ input: SlotInput; }>; -export type CreateSlotMutation = { __typename?: 'Mutation', createSlot?: { __typename?: 'Slot', documentId: string, date?: any | null | undefined, time_start: string, time_end: string, state?: Enum_Slot_State | null | undefined } | null | undefined }; +export type CreateSlotMutation = { __typename?: 'Mutation', createSlot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined }; export type GetSlotsQueryVariables = Exact<{ filters?: InputMaybe; }>; -export type GetSlotsQuery = { __typename?: 'Query', slots: Array<{ __typename?: 'Slot', documentId: string, date?: any | null | undefined, time_start: string, time_end: string, state?: Enum_Slot_State | null | undefined } | null | undefined> }; +export type GetSlotsQuery = { __typename?: 'Query', slots: Array<{ __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined> }; export type GetSlotsOrdersQueryVariables = Exact<{ filters?: InputMaybe; }>; -export type GetSlotsOrdersQuery = { __typename?: 'Query', slots: Array<{ __typename?: 'Slot', documentId: string, date?: any | null | undefined, time_start: string, time_end: string, state?: Enum_Slot_State | null | undefined, orders: Array<{ __typename?: 'Order', documentId: string, state?: Enum_Order_State | null | undefined, time_start?: string | null | undefined, time_end?: string | null | undefined } | null | undefined> } | null | undefined> }; +export type GetSlotsOrdersQuery = { __typename?: 'Query', slots: Array<{ __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, orders: Array<{ __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined>, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined> }; export type GetSlotQueryVariables = Exact<{ documentId: Scalars['ID']['input']; }>; -export type GetSlotQuery = { __typename?: 'Query', slot?: { __typename?: 'Slot', documentId: string, date?: any | null | undefined, time_start: string, time_end: string, state?: Enum_Slot_State | null | undefined, orders: Array<{ __typename?: 'Order', documentId: string, time_start?: string | null | undefined, time_end?: string | null | undefined } | null | undefined>, master?: { __typename?: 'Customer', documentId: string } | null | undefined } | null | undefined }; +export type GetSlotQuery = { __typename?: 'Query', slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, orders: Array<{ __typename?: 'Order', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Order_State | null | undefined, order_number?: number | null | undefined, services: Array<{ __typename?: 'Service', documentId: string, name?: string | null | undefined, duration: string } | null | undefined>, client?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined, slot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined } | null | undefined>, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined }; export type UpdateSlotMutationVariables = Exact<{ documentId: Scalars['ID']['input']; @@ -779,7 +751,7 @@ export type UpdateSlotMutationVariables = Exact<{ }>; -export type UpdateSlotMutation = { __typename?: 'Mutation', updateSlot?: { __typename?: 'Slot', documentId: string, date?: any | null | undefined, time_start: string, time_end: string, state?: Enum_Slot_State | null | undefined } | null | undefined }; +export type UpdateSlotMutation = { __typename?: 'Mutation', updateSlot?: { __typename?: 'Slot', documentId: string, datetime_start: string, datetime_end: string, state?: Enum_Slot_State | null | undefined, master?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined } | null | undefined } | null | undefined }; export type DeleteSlotMutationVariables = Exact<{ documentId: Scalars['ID']['input']; @@ -788,10 +760,10 @@ export type DeleteSlotMutationVariables = Exact<{ export type DeleteSlotMutation = { __typename?: 'Mutation', deleteSlot?: { __typename?: 'DeleteMutationResponse', documentId: string } | null | undefined }; -export const CustomerFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; -export const OrderFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; export const ServiceFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]} as unknown as DocumentNode; -export const SlotFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}}]}}]} as unknown as DocumentNode; +export const CustomerFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; +export const SlotFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; +export const OrderFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]} as unknown as DocumentNode; export const RegisterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"Register"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"register"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"username"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"jwt"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"username"}}]}}]}}]}}]} as unknown as DocumentNode; export const LoginDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"Login"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"login"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"identifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"jwt"}}]}}]}}]} as unknown as DocumentNode; export const CreateCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateCustomer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createCustomer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"role"},"value":{"kind":"EnumValue","value":"client"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}}]}}]}}]} as unknown as DocumentNode; @@ -799,15 +771,15 @@ export const GetCustomerDocument = {"kind":"Document","definitions":[{"kind":"Op export const GetMastersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMasters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"customers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"or"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"documentId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"masters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; export const GetClientsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetClients"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"customers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"or"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"clients"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; export const UpdateCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateCustomer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CustomerInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCustomer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode; -export const GetOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderFiltersInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"PaginationArg"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"time_start:asc","block":false}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; -export const GetOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; -export const CreateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; +export const GetOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderFiltersInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"PaginationArg"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"ListValue","values":[{"kind":"StringValue","value":"slot.datetime_start:desc","block":false},{"kind":"StringValue","value":"datetime_start:asc","block":false}]}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}}]} as unknown as DocumentNode; +export const GetOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"order"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}}]} as unknown as DocumentNode; +export const CreateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}}]} as unknown as DocumentNode; +export const UpdateOrderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateOrder"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OrderInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateOrder"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}}]} as unknown as DocumentNode; export const GetServicesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetServices"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ServiceFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"services"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]} as unknown as DocumentNode; export const GetServiceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetService"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"service"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]} as unknown as DocumentNode; -export const CreateSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSlot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}}]}}]} as unknown as DocumentNode; -export const GetSlotsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSlots"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slots"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"time_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}}]}}]} as unknown as DocumentNode; -export const GetSlotsOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSlotsOrders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slots"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"time_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}},{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"time_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}}]}}]} as unknown as DocumentNode; -export const GetSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"time_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}}]}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}}]}}]} as unknown as DocumentNode; -export const UpdateSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateSlot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"time_start"}},{"kind":"Field","name":{"kind":"Name","value":"time_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}}]}}]} as unknown as DocumentNode; +export const CreateSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createSlot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]} as unknown as DocumentNode; +export const GetSlotsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSlots"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slots"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"datetime_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]} as unknown as DocumentNode; +export const GetSlotsOrdersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSlotsOrders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filters"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotFiltersInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slots"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filters"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"datetime_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}},{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"datetime_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}}]} as unknown as DocumentNode; +export const GetSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"slot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"orders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"StringValue","value":"datetime_start:asc","block":false}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"OrderFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServiceFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Service"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"OrderFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Order"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"order_number"}},{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServiceFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"client"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}},{"kind":"Field","name":{"kind":"Name","value":"slot"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}}]} as unknown as DocumentNode; +export const UpdateSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SlotInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateSlot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SlotFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SlotFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Slot"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_start"}},{"kind":"Field","name":{"kind":"Name","value":"datetime_end"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"master"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]} as unknown as DocumentNode; export const DeleteSlotDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteSlot"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteSlot"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/packages/utils/src/datetime-format.ts b/packages/utils/src/datetime-format.ts index 8967dd6..629c236 100644 --- a/packages/utils/src/datetime-format.ts +++ b/packages/utils/src/datetime-format.ts @@ -1,62 +1,87 @@ /* eslint-disable import/no-unassigned-import */ -import { isBrowser } from './environment'; +import dayjs, { type ConfigType } from 'dayjs'; +import timezone from 'dayjs/plugin/timezone'; +import utc from 'dayjs/plugin/utc'; import 'dayjs/locale/ru'; -import dayjs from 'dayjs'; -import { noop } from 'radashi'; -export function combineDateTime(date: Date, time: string) { - const [hours = '00', minutes = '00'] = time.split(':'); +type DateTime = Exclude; - return new Date( - date.getFullYear(), - date.getMonth(), - date.getDate(), - Number.parseInt(hours, 10), - Number.parseInt(minutes, 10), - ); +if (!dayjs.prototype.tz) { + dayjs.extend(utc); + dayjs.extend(timezone); } -export function formatDate(date: Date | string) { - if (!date) return { db: noop, user: noop }; +dayjs.locale('ru'); +const DEFAULT_TZ = 'Europe/Moscow'; + +/** + * Склеивает дату (Date/string) и время (string, HH:mm) в datetime в нужной таймзоне, возвращает ISO строку в UTC + */ +export function combineDateAndTimeToUTC( + date: DateTime, + time: string, + tz: string = DEFAULT_TZ, +): string { + if (!date || !time) return ''; + const dateString = dayjs(date).format('YYYY-MM-DD'); + + return dayjs.tz(`${dateString}T${time}`, tz).utc().toISOString(); +} + +export function formatDate(datetime: DateTime) { return { - db: () => dayjs(date).format('YYYY-MM-DD'), - user: (template?: string, fallbackLang: string = 'ru') => { - const lang = isBrowser() ? document.documentElement.lang || fallbackLang : fallbackLang; - - dayjs.locale(lang); - - return dayjs(date).format(template || 'D MMMM YYYY'); + db: () => dayjs(datetime).utc().toISOString(), + user: (template?: string, tz: string = DEFAULT_TZ) => { + return dayjs + .utc(datetime) + .tz(tz) + .format(template || 'D MMMM YYYY'); }, }; } -export function formatTime(time: string) { - const [hours = '00', minutes = '00'] = time.split(':'); - +export function formatTime(datetime: ConfigType) { return { - db: () => `${hours}:${minutes}:00`, - user: () => `${hours}:${minutes}`, + db: () => dayjs(datetime).utc().toISOString(), + user: (tz: string = DEFAULT_TZ) => { + return dayjs.utc(datetime).tz(tz).format('HH:mm'); + }, + }; +} + +export function getDateUTCRange(date?: DateTime, tz: string = DEFAULT_TZ) { + return { + day: () => { + const startOfDay = dayjs(date).tz(tz).startOf('day').utc().toISOString(); + const endOfDay = dayjs(date).tz(tz).endOf('day').utc().toISOString(); + + return { endOfDay, startOfDay }; + }, + month: () => { + const startOfMonth = dayjs(date).tz(tz).startOf('month').utc().toISOString(); + const endOfMonth = dayjs(date).tz(tz).endOf('month').utc().toISOString(); + + return { endOfMonth, startOfMonth }; + }, }; } export function getMinutes(time: string) { const [hours = '00', minutes = '00'] = time.split(':'); + return Number.parseInt(hours, 10) * 60 + Number.parseInt(minutes, 10); } -export function sumTime(time1: string, time2: string) { - const [hours1 = '00', minutes1 = '00'] = time1.split(':'); - const [hours2 = '00', minutes2 = '00'] = time2.split(':'); +export function getTimeZoneLabel(tz: string = DEFAULT_TZ): string { + if (tz === DEFAULT_TZ) return 'МСК'; + const offset = dayjs().tz(tz).format('Z'); - let totalMinutes = Number.parseInt(minutes1, 10) + Number.parseInt(minutes2, 10); - let totalHours = Number.parseInt(hours1, 10) + Number.parseInt(hours2, 10); - - totalHours += Math.floor(totalMinutes / 60); - totalMinutes %= 60; - - const paddedHours = totalHours.toString().padStart(2, '0'); - const paddedMinutes = totalMinutes.toString().padStart(2, '0'); - - return `${paddedHours}:${paddedMinutes}`; + return `GMT${offset}`; +} + +export function sumTime(datetime: DateTime, durationMinutes: number) { + if (!datetime) return ''; + + return dayjs(datetime).add(durationMinutes, 'minute').toISOString(); }