Merge pull request 'refactor-api' (#1) from refactor-api into feature/orders
This commit is contained in:
commit
298442330c
@ -3,12 +3,7 @@
|
||||
import { env as environment } from './config/env';
|
||||
import { commandsList, KEYBOARD_REMOVE, KEYBOARD_SHARE_PHONE, MESSAGE_NOT_MASTER } from './message';
|
||||
import { normalizePhoneNumber } from './utils/phone';
|
||||
import {
|
||||
createOrUpdateUser,
|
||||
getCustomer,
|
||||
updateCustomerMaster,
|
||||
updateCustomerProfile,
|
||||
} from '@repo/graphql/api';
|
||||
import { CustomersService } from '@repo/graphql/api/customers';
|
||||
import { Enum_Customer_Role } from '@repo/graphql/types';
|
||||
import { Telegraf } from 'telegraf';
|
||||
import { message } from 'telegraf/filters';
|
||||
@ -16,8 +11,10 @@ import { message } from 'telegraf/filters';
|
||||
const bot = new Telegraf(environment.BOT_TOKEN);
|
||||
|
||||
bot.start(async (context) => {
|
||||
const data = await getCustomer({ telegramId: context.from.id });
|
||||
const customer = data?.data?.customers?.at(0);
|
||||
const telegramId = context.from.id;
|
||||
|
||||
const customerService = new CustomersService({ telegramId });
|
||||
const { customer } = await customerService.getCustomer({ telegramId });
|
||||
|
||||
if (customer) {
|
||||
return context.reply(
|
||||
@ -34,8 +31,10 @@ bot.start(async (context) => {
|
||||
});
|
||||
|
||||
bot.command('addcontact', async (context) => {
|
||||
const data = await getCustomer({ telegramId: context.from.id });
|
||||
const customer = data?.data?.customers?.at(0);
|
||||
const telegramId = context.from.id;
|
||||
|
||||
const customerService = new CustomersService({ telegramId });
|
||||
const { customer } = await customerService.getCustomer({ telegramId });
|
||||
|
||||
if (!customer) {
|
||||
return context.reply(
|
||||
@ -52,8 +51,10 @@ bot.command('addcontact', async (context) => {
|
||||
});
|
||||
|
||||
bot.command('becomemaster', async (context) => {
|
||||
const data = await getCustomer({ telegramId: context.from.id });
|
||||
const customer = data?.data?.customers?.at(0);
|
||||
const telegramId = context.from.id;
|
||||
|
||||
const customerService = new CustomersService({ telegramId });
|
||||
const { customer } = await customerService.getCustomer({ telegramId });
|
||||
|
||||
if (!customer) {
|
||||
return context.reply('Сначала поделитесь своим номером телефона.', KEYBOARD_SHARE_PHONE);
|
||||
@ -63,12 +64,15 @@ bot.command('becomemaster', async (context) => {
|
||||
return context.reply('Вы уже являетесь мастером.');
|
||||
}
|
||||
|
||||
const response = await updateCustomerProfile({
|
||||
data: { role: Enum_Customer_Role.Master },
|
||||
documentId: customer.documentId,
|
||||
}).catch((error) => {
|
||||
context.reply('Произошла ошибка.\n' + error);
|
||||
});
|
||||
const response = await customerService
|
||||
.updateCustomer({
|
||||
data: {
|
||||
role: Enum_Customer_Role.Master,
|
||||
},
|
||||
})
|
||||
.catch((error) => {
|
||||
context.reply('Произошла ошибка.\n' + error);
|
||||
});
|
||||
|
||||
if (response) {
|
||||
return context.reply('Вы стали мастером');
|
||||
@ -76,8 +80,10 @@ bot.command('becomemaster', async (context) => {
|
||||
});
|
||||
|
||||
bot.on(message('contact'), async (context) => {
|
||||
const data = await getCustomer({ telegramId: context.from.id });
|
||||
const customer = data?.data?.customers?.at(0);
|
||||
const telegramId = context.from.id;
|
||||
|
||||
const customerService = new CustomersService({ telegramId });
|
||||
const { customer } = await customerService.getCustomer({ telegramId });
|
||||
|
||||
const isRegistration = !customer;
|
||||
|
||||
@ -86,13 +92,15 @@ bot.on(message('contact'), async (context) => {
|
||||
const phone = normalizePhoneNumber(contact.phone_number);
|
||||
|
||||
if (isRegistration) {
|
||||
const response = await createOrUpdateUser({
|
||||
name,
|
||||
phone,
|
||||
telegramId: context.from.id,
|
||||
}).catch((error) => {
|
||||
context.reply('Произошла ошибка.\n' + error);
|
||||
});
|
||||
const response = await customerService
|
||||
.createCustomer({
|
||||
name,
|
||||
phone,
|
||||
telegramId: context.from.id,
|
||||
})
|
||||
.catch((error) => {
|
||||
context.reply('Произошла ошибка.\n' + error);
|
||||
});
|
||||
|
||||
if (response) {
|
||||
return context.reply(
|
||||
@ -107,12 +115,19 @@ bot.on(message('contact'), async (context) => {
|
||||
}
|
||||
|
||||
try {
|
||||
await createOrUpdateUser({ name, phone });
|
||||
const createCustomerResult = await customerService.createCustomer({ name, phone });
|
||||
|
||||
await updateCustomerMaster({
|
||||
masterId: customer.documentId,
|
||||
operation: 'add',
|
||||
phone,
|
||||
const documentId = createCustomerResult?.createCustomer?.documentId;
|
||||
|
||||
if (!documentId) {
|
||||
throw new Error('Customer not created');
|
||||
}
|
||||
|
||||
const masters = [customer.documentId];
|
||||
|
||||
await customerService.addMasters({
|
||||
data: { masters },
|
||||
documentId,
|
||||
});
|
||||
|
||||
return context.reply(
|
||||
|
||||
42
apps/web/actions/api/customers.ts
Normal file
42
apps/web/actions/api/customers.ts
Normal file
@ -0,0 +1,42 @@
|
||||
'use server';
|
||||
|
||||
import { useService } from './lib/service';
|
||||
import { CustomersService } from '@repo/graphql/api/customers';
|
||||
|
||||
const getService = useService(CustomersService);
|
||||
|
||||
export async function addMasters(...variables: Parameters<CustomersService['addMasters']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.addMasters(...variables);
|
||||
}
|
||||
|
||||
export async function createCustomer(...variables: Parameters<CustomersService['createCustomer']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.createCustomer(...variables);
|
||||
}
|
||||
|
||||
export async function getClients(...variables: Parameters<CustomersService['getClients']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.getClients(...variables);
|
||||
}
|
||||
|
||||
export async function getCustomer(...variables: Parameters<CustomersService['getCustomer']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.getCustomer(...variables);
|
||||
}
|
||||
|
||||
export async function getMasters(...variables: Parameters<CustomersService['getMasters']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.getMasters(...variables);
|
||||
}
|
||||
|
||||
export async function updateCustomer(...variables: Parameters<CustomersService['updateCustomer']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.updateCustomer(...variables);
|
||||
}
|
||||
14
apps/web/actions/api/lib/service.ts
Normal file
14
apps/web/actions/api/lib/service.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { authOptions } from '@/config/auth';
|
||||
import { type BaseService } from '@repo/graphql/api/base';
|
||||
import { getServerSession } from 'next-auth';
|
||||
|
||||
export function useService<T extends typeof BaseService>(service: T) {
|
||||
return async function () {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.telegramId) throw new Error('Unauthorized');
|
||||
|
||||
const customer = { telegramId: session.user.telegramId };
|
||||
|
||||
return new service(customer) as InstanceType<T>;
|
||||
};
|
||||
}
|
||||
18
apps/web/actions/api/orders.ts
Normal file
18
apps/web/actions/api/orders.ts
Normal file
@ -0,0 +1,18 @@
|
||||
'use server';
|
||||
|
||||
import { useService } from './lib/service';
|
||||
import { OrdersService } from '@repo/graphql/api/orders';
|
||||
|
||||
const getServicesService = useService(OrdersService);
|
||||
|
||||
export async function createOrder(...variables: Parameters<OrdersService['createOrder']>) {
|
||||
const service = await getServicesService();
|
||||
|
||||
return service.createOrder(...variables);
|
||||
}
|
||||
|
||||
export async function getOrder(...variables: Parameters<OrdersService['getOrder']>) {
|
||||
const service = await getServicesService();
|
||||
|
||||
return service.getOrder(...variables);
|
||||
}
|
||||
18
apps/web/actions/api/services.ts
Normal file
18
apps/web/actions/api/services.ts
Normal file
@ -0,0 +1,18 @@
|
||||
'use server';
|
||||
|
||||
import { useService } from './lib/service';
|
||||
import { ServicesService } from '@repo/graphql/api/services';
|
||||
|
||||
const getServicesService = useService(ServicesService);
|
||||
|
||||
export async function getService(...variables: Parameters<ServicesService['getService']>) {
|
||||
const service = await getServicesService();
|
||||
|
||||
return service.getService(...variables);
|
||||
}
|
||||
|
||||
export async function getServices(...variables: Parameters<ServicesService['getServices']>) {
|
||||
const service = await getServicesService();
|
||||
|
||||
return service.getServices(...variables);
|
||||
}
|
||||
36
apps/web/actions/api/slots.ts
Normal file
36
apps/web/actions/api/slots.ts
Normal file
@ -0,0 +1,36 @@
|
||||
'use server';
|
||||
|
||||
import { useService } from './lib/service';
|
||||
import { SlotsService } from '@repo/graphql/api/slots';
|
||||
|
||||
const getService = useService(SlotsService);
|
||||
|
||||
export async function createSlot(...variables: Parameters<SlotsService['createSlot']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.createSlot(...variables);
|
||||
}
|
||||
|
||||
export async function deleteSlot(...variables: Parameters<SlotsService['deleteSlot']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.deleteSlot(...variables);
|
||||
}
|
||||
|
||||
export async function getSlot(...variables: Parameters<SlotsService['getSlot']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.getSlot(...variables);
|
||||
}
|
||||
|
||||
export async function getSlots(...variables: Parameters<SlotsService['getSlots']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.getSlots(...variables);
|
||||
}
|
||||
|
||||
export async function updateSlot(...variables: Parameters<SlotsService['updateSlot']>) {
|
||||
const service = await getService();
|
||||
|
||||
return service.updateSlot(...variables);
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
'use server';
|
||||
import { authOptions } from '@/config/auth';
|
||||
import { getCustomerClients, getCustomerMasters } from '@repo/graphql/api';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
|
||||
export async function getClients() {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) throw new Error('Missing session');
|
||||
|
||||
const { user } = session;
|
||||
|
||||
const response = await getCustomerClients({ telegramId: user?.telegramId });
|
||||
|
||||
return response.data?.customers?.at(0);
|
||||
}
|
||||
|
||||
export async function getMasters() {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) throw new Error('Missing session');
|
||||
|
||||
const { user } = session;
|
||||
|
||||
const response = await getCustomerMasters({ telegramId: user?.telegramId });
|
||||
|
||||
return response.data?.customers?.at(0);
|
||||
}
|
||||
@ -1,69 +0,0 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use server';
|
||||
// eslint-disable-next-line sonarjs/no-internal-api-use
|
||||
import type * as ApolloTypes from '../../../packages/graphql/node_modules/@apollo/client/core';
|
||||
import { getProfile } from './profile';
|
||||
import { formatDate, formatTime, sumTime } from '@/utils/date';
|
||||
import * as api from '@repo/graphql/api';
|
||||
import { Enum_Customer_Role, Enum_Slot_State } from '@repo/graphql/types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type FixTypescriptCringe = ApolloTypes.FetchResult;
|
||||
|
||||
export const getOrder = api.getOrder;
|
||||
|
||||
type OrderInput = {
|
||||
clientId: string;
|
||||
date: Date;
|
||||
serviceId: string;
|
||||
slotId: string;
|
||||
time: string;
|
||||
};
|
||||
|
||||
export async function createOrder(input: OrderInput) {
|
||||
const customer = await getProfile();
|
||||
|
||||
if (!input.slotId) {
|
||||
throw new Error('Missing slot');
|
||||
}
|
||||
|
||||
const { data } = await api.getSlot({ documentId: input.slotId });
|
||||
|
||||
if (data.slot?.state === Enum_Slot_State.Closed) {
|
||||
throw new Error('Slot is closed');
|
||||
}
|
||||
|
||||
if (customer.role === Enum_Customer_Role.Client) {
|
||||
if (customer.documentId !== input.clientId) {
|
||||
throw new Error('Invalid client');
|
||||
}
|
||||
|
||||
const masterId = data.slot?.master?.documentId;
|
||||
|
||||
const masters = await api.getCustomerMasters(customer);
|
||||
|
||||
if (!masters.data.customers.some((master) => master?.documentId === masterId)) {
|
||||
throw new Error('Invalid master');
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
customer.role === Enum_Customer_Role.Master &&
|
||||
data.slot?.master?.documentId !== customer.documentId
|
||||
) {
|
||||
throw new Error('Invalid master');
|
||||
}
|
||||
|
||||
const service = await api.getService({ documentId: input.serviceId });
|
||||
|
||||
const endTime = sumTime(input.time, service?.data?.service?.duration);
|
||||
const payload = {
|
||||
client: input.clientId,
|
||||
date: formatDate(input.date).db(),
|
||||
services: [input.serviceId],
|
||||
slot: input.slotId,
|
||||
time_end: formatTime(endTime).db(),
|
||||
time_start: formatTime(input.time).db(),
|
||||
};
|
||||
return api.createOrder(payload);
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
'use server';
|
||||
import { authOptions } from '@/config/auth';
|
||||
import { getCustomer, updateCustomerProfile } from '@repo/graphql/api';
|
||||
import { type CustomerInput, type GetCustomerQueryVariables } from '@repo/graphql/types';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
|
||||
export async function getProfile(input?: GetCustomerQueryVariables) {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) throw new Error('Missing session');
|
||||
|
||||
const { user } = session;
|
||||
const telegramId = input?.telegramId || user?.telegramId;
|
||||
|
||||
const { data } = await getCustomer({ telegramId });
|
||||
const customer = data?.customers?.at(0);
|
||||
|
||||
if (!customer) throw new Error('Customer not found');
|
||||
|
||||
return customer;
|
||||
}
|
||||
|
||||
export async function updateProfile(input: CustomerInput) {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session) throw new Error('Missing session');
|
||||
|
||||
const { user } = session;
|
||||
|
||||
const { data } = await getCustomer({ telegramId: user?.telegramId });
|
||||
const customer = data.customers.at(0);
|
||||
|
||||
if (!customer) throw new Error('Customer not found');
|
||||
|
||||
await updateCustomerProfile({
|
||||
data: input,
|
||||
documentId: customer?.documentId,
|
||||
});
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
'use server';
|
||||
import { getProfile } from './profile';
|
||||
import * as api from '@repo/graphql/api/service';
|
||||
// eslint-disable-next-line sonarjs/no-internal-api-use
|
||||
import type * as ApolloTypes from '@repo/graphql/node_modules/@apollo/client/core';
|
||||
import { type GetServicesQueryVariables } from '@repo/graphql/types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type FixTypescriptCringe = ApolloTypes.FetchResult;
|
||||
|
||||
export async function getServices(input?: GetServicesQueryVariables) {
|
||||
const customer = await getProfile();
|
||||
|
||||
const filters = input || { filters: { master: { documentId: { eq: customer.documentId } } } };
|
||||
|
||||
return api.getServices(filters);
|
||||
}
|
||||
|
||||
export const getService = api.getService;
|
||||
13
apps/web/actions/session.ts
Normal file
13
apps/web/actions/session.ts
Normal file
@ -0,0 +1,13 @@
|
||||
'use server';
|
||||
|
||||
import { authOptions } from '@/config/auth';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
|
||||
export async function getSessionUser() {
|
||||
const session = await getServerSession(authOptions);
|
||||
const user = session?.user;
|
||||
|
||||
if (!user?.telegramId) throw new Error('Missing session');
|
||||
|
||||
return user;
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
'use server';
|
||||
// eslint-disable-next-line sonarjs/no-internal-api-use
|
||||
import type * as ApolloTypes from '../../../packages/graphql/node_modules/@apollo/client/core';
|
||||
import { getProfile } from './profile';
|
||||
import { formatDate, formatTime } from '@/utils/date';
|
||||
import * as api from '@repo/graphql/api';
|
||||
import type * as GQL from '@repo/graphql/types';
|
||||
|
||||
type AddSlotInput = Omit<GQL.CreateSlotMutationVariables['input'], 'master'>;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type FixTypescriptCringe = ApolloTypes.FetchResult;
|
||||
|
||||
export async function addSlot(input: AddSlotInput) {
|
||||
const customer = await getProfile();
|
||||
|
||||
return api.createSlot({
|
||||
...input,
|
||||
date: formatDate(input.date).db(),
|
||||
master: customer?.documentId,
|
||||
time_end: formatTime(input.time_end).db(),
|
||||
time_start: formatTime(input.time_start).db(),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSlots(input: GQL.GetSlotsQueryVariables) {
|
||||
const customer = await getProfile();
|
||||
|
||||
return api.getSlots({
|
||||
filters: {
|
||||
master: {
|
||||
documentId: {
|
||||
eq: customer.documentId,
|
||||
},
|
||||
},
|
||||
...input.filters,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateSlot(input: GQL.UpdateSlotMutationVariables) {
|
||||
await getProfile();
|
||||
|
||||
return api.updateSlot({
|
||||
...input,
|
||||
data: {
|
||||
...input.data,
|
||||
date: input.data?.date ? formatDate(input.data.date).db() : undefined,
|
||||
time_end: input.data?.time_end ? formatTime(input.data.time_end).db() : undefined,
|
||||
time_start: input.data?.time_start ? formatTime(input.data.time_start).db() : undefined,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const getSlot = api.getSlot;
|
||||
export const deleteSlot = api.deleteSlot;
|
||||
@ -1,5 +1,6 @@
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
'use client';
|
||||
|
||||
import { getTelegramUser } from '@/mocks/get-telegram-user';
|
||||
import { LoadingSpinner } from '@repo/ui/components/ui/spinner';
|
||||
import { signIn, useSession } from 'next-auth/react';
|
||||
@ -21,7 +22,7 @@ export default function Auth() {
|
||||
signIn('telegram', {
|
||||
callbackUrl: '/profile',
|
||||
redirect: false,
|
||||
telegramId: String(user?.id),
|
||||
telegramId: user?.id,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { useClientOnce } from '@/hooks/telegram';
|
||||
import { isTMA } from '@telegram-apps/sdk-react';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
'use client';
|
||||
|
||||
import { initData, isMiniAppDark, useSignal } from '@telegram-apps/sdk-react';
|
||||
import { signIn, useSession } from 'next-auth/react';
|
||||
import { useTheme } from 'next-themes';
|
||||
@ -28,7 +29,7 @@ function useAuth() {
|
||||
signIn('telegram', {
|
||||
callbackUrl: '/profile',
|
||||
redirect: false,
|
||||
telegramId: String(initDataUser.id),
|
||||
telegramId: initDataUser.id,
|
||||
}).then(() => redirect('/profile'));
|
||||
}
|
||||
}, [initDataUser?.id, status]);
|
||||
|
||||
@ -7,7 +7,7 @@ type Props = { params: Promise<{ telegramId: string }> };
|
||||
|
||||
export default async function ProfilePage(props: Readonly<Props>) {
|
||||
const parameters = await props.params;
|
||||
const { telegramId } = parameters;
|
||||
const telegramId = Number.parseInt(parameters.telegramId, 10);
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
|
||||
@ -1,18 +1,21 @@
|
||||
'use client';
|
||||
import { useProfileMutation } from '@/hooks/profile';
|
||||
|
||||
import { useCustomerMutation } from '@/hooks/api/customers';
|
||||
import { initData, useSignal } from '@telegram-apps/sdk-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function UpdateProfile() {
|
||||
const initDataUser = useSignal(initData.user);
|
||||
const { mutate: updateProfile } = useProfileMutation();
|
||||
const { mutate: updateProfile } = useCustomerMutation();
|
||||
const [hasUpdated, setHasUpdated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasUpdated) {
|
||||
updateProfile({
|
||||
active: true,
|
||||
photoUrl: initDataUser?.photoUrl || undefined,
|
||||
data: {
|
||||
active: true,
|
||||
photoUrl: initDataUser?.photoUrl || undefined,
|
||||
},
|
||||
});
|
||||
setHasUpdated(true);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { LoadingSpinner } from '../common/spinner';
|
||||
import { useCustomerContacts } from '@/hooks/contacts';
|
||||
import { useCustomerContacts } from '@/hooks/api/contacts';
|
||||
import * as GQL from '@repo/graphql/types';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@repo/ui/components/ui/avatar';
|
||||
import Link from 'next/link';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { ContactsFilterContext, type FilterType } from '@/context/contacts-filter';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { NavButton } from './components/nav-button';
|
||||
import { BookOpen, Newspaper, PlusCircle, User, Users } from 'lucide-react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { BackButton } from './components/back-button';
|
||||
|
||||
type Props = { title: string | undefined };
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
import { useOrderCreate } from '@/hooks/orders';
|
||||
|
||||
import { useOrderCreate } from '@/hooks/api/orders';
|
||||
import { useOrderStore } from '@/stores/order';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { ContactsGridBase } from './components';
|
||||
import { LoadingSpinner } from '@/components/common/spinner';
|
||||
import { ContactsFilterProvider } from '@/context/contacts-filter';
|
||||
import { useCustomerContacts } from '@/hooks/contacts';
|
||||
import { useCustomerContacts } from '@/hooks/api/contacts';
|
||||
import { useOrderStore } from '@/stores/order';
|
||||
import { withContext } from '@/utils/context';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const MastersGrid = withContext(ContactsFilterProvider)(function () {
|
||||
const { contacts, isLoading, setFilter } = useCustomerContacts({ includeSelf: true });
|
||||
const { contacts, isLoading, setFilter } = useCustomerContacts();
|
||||
const masterId = useOrderStore((store) => store.masterId);
|
||||
const setMasterId = useOrderStore((store) => store.setMasterId);
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { useOrderStore } from '@/stores/order';
|
||||
import { Calendar } from '@repo/ui/components/ui/calendar';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
import { useSlots } from '@/hooks/slots';
|
||||
|
||||
import { useSlotsQuery } from '@/hooks/api/slots';
|
||||
import { useOrderStore } from '@/stores/order';
|
||||
import { Enum_Slot_State, type SlotFieldsFragment } from '@repo/graphql/types';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
@ -25,9 +26,20 @@ const generateTimeSlots = (slots: SlotFieldsFragment[]): Array<{ slotId: string;
|
||||
export function TimeSelect() {
|
||||
const masterId = useOrderStore((store) => store.masterId);
|
||||
const date = useOrderStore((store) => store.date);
|
||||
const { data } = useSlots({ date, masterId });
|
||||
const { data: { slots } = {} } = useSlotsQuery({
|
||||
filters: {
|
||||
date: {
|
||||
eq: date,
|
||||
},
|
||||
master: {
|
||||
documentId: {
|
||||
eq: masterId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const openedSlots = data?.data.slots.filter((slot) => slot?.state === Enum_Slot_State.Open);
|
||||
const openedSlots = slots?.filter((slot) => slot?.state === Enum_Slot_State.Open);
|
||||
const timeSlots = generateTimeSlots(openedSlots ? sift(openedSlots) : []);
|
||||
|
||||
const morning = timeSlots.filter((time) => time.time.hour() < 12);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { useOrderStore } from '@/stores/order';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { useOrderStore } from '@/stores/order';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import { Card, CardContent } from '@repo/ui/components/ui/card';
|
||||
|
||||
@ -1,17 +1,28 @@
|
||||
'use client';
|
||||
import { useServicesQuery } from '@/hooks/services';
|
||||
|
||||
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';
|
||||
|
||||
export function ServiceSelect() {
|
||||
const { data } = useServicesQuery();
|
||||
const masterId = useOrderStore((store) => store.masterId);
|
||||
|
||||
const { data: { services } = {} } = useServicesQuery({
|
||||
filters: {
|
||||
master: {
|
||||
documentId: {
|
||||
eq: masterId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!services?.length) return null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{data?.data.services.map(
|
||||
(service) => service && <ServiceCard key={service.documentId} {...service} />,
|
||||
)}
|
||||
{services.map((service) => service && <ServiceCard key={service.documentId} {...service} />)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
import { useOrderCreate } from '@/hooks/orders';
|
||||
|
||||
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';
|
||||
@ -14,7 +15,15 @@ export function SubmitButton() {
|
||||
const handleSubmit = () => {
|
||||
if (isDisabled) return;
|
||||
|
||||
createOrder({ clientId, date, serviceId, slotId, time });
|
||||
createOrder({
|
||||
input: {
|
||||
client: clientId,
|
||||
date,
|
||||
services: [serviceId],
|
||||
slot: slotId,
|
||||
time_start: time,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { LoadingSpinner } from '../common/spinner';
|
||||
import {
|
||||
BackButton,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
'use client';
|
||||
|
||||
import { Checkbox, type CheckboxProps } from '@repo/ui/components/ui/checkbox';
|
||||
import { useState } from 'react';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
'use client';
|
||||
|
||||
import { type CustomerInput } from '@repo/graphql/types';
|
||||
import { Input } from '@repo/ui/components/ui/input';
|
||||
import { Label } from '@repo/ui/components/ui/label';
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { CardSectionHeader } from '../ui';
|
||||
import { CheckboxWithText, DataField } from './components';
|
||||
import { type ProfileProps } from './types';
|
||||
import { useProfileMutation, useProfileQuery } from '@/hooks/profile';
|
||||
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';
|
||||
|
||||
export function ContactDataCard({ telegramId }: Readonly<ProfileProps>) {
|
||||
const { data: customer } = useProfileQuery({ telegramId });
|
||||
const { data: { customer } = {} } = useCustomerQuery({ telegramId });
|
||||
|
||||
if (!customer) return null;
|
||||
|
||||
@ -30,8 +31,8 @@ export function ContactDataCard({ telegramId }: Readonly<ProfileProps>) {
|
||||
}
|
||||
|
||||
export function ProfileDataCard() {
|
||||
const { data: customer } = useProfileQuery();
|
||||
const { mutate: updateProfile } = useProfileMutation();
|
||||
const { data: { customer } = {} } = useCustomerQuery();
|
||||
const { mutate: updateCustomer } = useCustomerMutation();
|
||||
|
||||
if (!customer) return null;
|
||||
|
||||
@ -43,14 +44,18 @@ export function ProfileDataCard() {
|
||||
fieldName="name"
|
||||
id="name"
|
||||
label="Имя"
|
||||
onChange={updateProfile}
|
||||
onChange={({ name }) => updateCustomer({ data: { name } })}
|
||||
value={customer?.name ?? ''}
|
||||
/>
|
||||
<DataField disabled id="phone" label="Телефон" readOnly value={customer?.phone ?? ''} />
|
||||
<CheckboxWithText
|
||||
checked={customer.role !== 'client'}
|
||||
description="Разрешить другим пользователям записываться к вам"
|
||||
onChange={(checked) => updateProfile({ role: checked ? Role.Master : Role.Client })}
|
||||
onChange={(checked) =>
|
||||
updateCustomer({
|
||||
data: { role: checked ? Role.Master : Role.Client },
|
||||
})
|
||||
}
|
||||
text="Быть мастером"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import { LinkButton } from './components';
|
||||
import { type ProfileProps } from './types';
|
||||
import { useProfileQuery } from '@/hooks/profile';
|
||||
import { useCustomerQuery } from '@/hooks/api/customers';
|
||||
import { Enum_Customer_Role } from '@repo/graphql/types';
|
||||
|
||||
export function LinksCard({ telegramId }: Readonly<ProfileProps>) {
|
||||
const { data: customer } = useProfileQuery({ telegramId });
|
||||
const { data: { customer } = {} } = useCustomerQuery({ telegramId });
|
||||
|
||||
const isMaster = customer?.role === Enum_Customer_Role.Master;
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
'use client';
|
||||
|
||||
import { LoadingSpinner } from '../common/spinner';
|
||||
import { type ProfileProps } from './types';
|
||||
import { useProfileQuery } from '@/hooks/profile';
|
||||
import { useCustomerQuery } from '@/hooks/api/customers';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@repo/ui/components/ui/avatar';
|
||||
import { Card } from '@repo/ui/components/ui/card';
|
||||
|
||||
export function PersonCard({ telegramId }: Readonly<ProfileProps>) {
|
||||
const { data: customer, isLoading } = useProfileQuery({ telegramId });
|
||||
const { data: { customer } = {}, isLoading } = useCustomerQuery({ telegramId });
|
||||
|
||||
if (isLoading || !customer)
|
||||
return (
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export type ProfileProps = {
|
||||
readonly telegramId?: string;
|
||||
readonly telegramId?: number;
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { ScheduleContext } from '@/context/schedule';
|
||||
import { Calendar } from '@repo/ui/components/ui/calendar';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import { type OrderClient, type OrderComponentProps } from '../types';
|
||||
import { ReadonlyTimeRange } from './time-range';
|
||||
import { useOrderQuery } from '@/hooks/orders';
|
||||
import { useOrderQuery } from '@/hooks/api/orders';
|
||||
import { Enum_Order_State } from '@repo/graphql/types';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@repo/ui/components/ui/avatar';
|
||||
import { Badge } from '@repo/ui/components/ui/badge';
|
||||
@ -10,8 +11,7 @@ import { cn } from '@repo/ui/lib/utils';
|
||||
import Link from 'next/link';
|
||||
|
||||
export function OrderCard({ documentId }: Readonly<OrderComponentProps>) {
|
||||
const { data } = useOrderQuery({ documentId });
|
||||
const order = data?.data?.order;
|
||||
const { data: { order } = {} } = useOrderQuery({ documentId });
|
||||
|
||||
if (!order) return null;
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import { ReadonlyTimeRange } from './time-range';
|
||||
import { useSlotQuery } from '@/hooks/slots';
|
||||
import { useSlotQuery } from '@/hooks/api/slots';
|
||||
import { Enum_Slot_State, type SlotFieldsFragment } from '@repo/graphql/types';
|
||||
import { Badge } from '@repo/ui/components/ui/badge';
|
||||
import { cn } from '@repo/ui/lib/utils';
|
||||
@ -18,8 +19,7 @@ export function SlotCard(props: Readonly<SlotFieldsFragment>) {
|
||||
const pathname = usePathname();
|
||||
const { documentId } = props;
|
||||
|
||||
const { data } = useSlotQuery({ documentId });
|
||||
const slot = data?.data?.slot;
|
||||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||||
|
||||
const ordersNumber = slot?.orders?.length;
|
||||
const hasOrders = Boolean(ordersNumber);
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import { type SlotComponentProps } from '../types';
|
||||
import { useSlotQuery } from '@/hooks/slots';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import { useSlotQuery } from '@/hooks/api/slots';
|
||||
import { formatDate } from '@repo/graphql/utils/datetime-format';
|
||||
|
||||
export function SlotDate({ documentId }: Readonly<SlotComponentProps>) {
|
||||
const { data } = useSlotQuery({ documentId });
|
||||
const slot = data?.data?.slot;
|
||||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||||
|
||||
if (!slot) return null;
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
'use client';
|
||||
|
||||
import { ScheduleTimeContext } from '../context';
|
||||
import { type SlotComponentProps } from '../types';
|
||||
import { EditableTimeRangeForm, ReadonlyTimeRange } from './time-range';
|
||||
import { useSlotMutation, useSlotQuery } from '@/hooks/slots';
|
||||
import { useSlotMutation, useSlotQuery } from '@/hooks/api/slots';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import { PencilLine } from 'lucide-react';
|
||||
import { use, useEffect } from 'react';
|
||||
@ -19,8 +20,7 @@ function SlotTimeEditForm({ documentId }: Readonly<SlotComponentProps>) {
|
||||
use(ScheduleTimeContext);
|
||||
const { isPending: isMutationPending, mutate: updateSlot } = useSlotMutation({ documentId });
|
||||
|
||||
const { data, isPending: isQueryPending } = useSlotQuery({ documentId });
|
||||
const slot = data?.data?.slot;
|
||||
const { data: { slot } = {}, isPending: isQueryPending } = useSlotQuery({ documentId });
|
||||
|
||||
const isPending = isMutationPending || isQueryPending;
|
||||
|
||||
@ -32,7 +32,7 @@ function SlotTimeEditForm({ documentId }: Readonly<SlotComponentProps>) {
|
||||
}, [editMode, setEndTime, setStartTime, slot]);
|
||||
|
||||
function handleSubmit() {
|
||||
updateSlot({ data: { time_end: endTime, time_start: startTime }, documentId });
|
||||
updateSlot({ data: { time_end: endTime, time_start: startTime } });
|
||||
resetTime();
|
||||
setEditMode(false);
|
||||
}
|
||||
@ -46,11 +46,10 @@ function SlotTimeEditForm({ documentId }: Readonly<SlotComponentProps>) {
|
||||
);
|
||||
}
|
||||
|
||||
function SlotTimeReadonly(props: Readonly<SlotComponentProps>) {
|
||||
function SlotTimeReadonly({ documentId }: Readonly<SlotComponentProps>) {
|
||||
const { setEditMode } = use(ScheduleTimeContext);
|
||||
|
||||
const { data } = useSlotQuery(props);
|
||||
const slot = data?.data?.slot;
|
||||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||||
|
||||
if (!slot) return null;
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ScheduleTimeContext } from '../context';
|
||||
import { formatTime } from '@/utils/date';
|
||||
import { formatTime } from '@repo/graphql/utils/datetime-format';
|
||||
import { Input } from '@repo/ui/components/ui/input';
|
||||
import { cn } from '@repo/ui/lib/utils';
|
||||
import { type FormEvent, type PropsWithChildren, use } from 'react';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import {
|
||||
createContext,
|
||||
type Dispatch,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import { EditableTimeRangeForm } from './components/time-range';
|
||||
import { ScheduleTimeContext, ScheduleTimeContextProvider } from './context';
|
||||
import { ScheduleContext } from '@/context/schedule';
|
||||
import { useSlotAdd } from '@/hooks/slots';
|
||||
import { useSlotCreate } from '@/hooks/api/slots';
|
||||
import { withContext } from '@/utils/context';
|
||||
import { Enum_Slot_State } from '@repo/graphql/types';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
@ -13,18 +13,17 @@ import { type FormEvent, use } from 'react';
|
||||
export const DaySlotAddForm = withContext(ScheduleTimeContextProvider)(function () {
|
||||
const { endTime, resetTime, startTime } = use(ScheduleTimeContext);
|
||||
|
||||
const { selectedDate } = use(ScheduleContext);
|
||||
|
||||
const { isPending, mutate: addSlot } = useSlotAdd({ date: selectedDate });
|
||||
const { isPending, mutate: addSlot } = useSlotCreate();
|
||||
|
||||
const handleSubmit = (event: FormEvent) => {
|
||||
event.preventDefault();
|
||||
if (startTime && endTime) {
|
||||
addSlot({
|
||||
date: selectedDate,
|
||||
state: Enum_Slot_State.Open,
|
||||
time_end: endTime,
|
||||
time_start: startTime,
|
||||
input: {
|
||||
state: Enum_Slot_State.Open,
|
||||
time_end: endTime,
|
||||
time_start: startTime,
|
||||
},
|
||||
});
|
||||
|
||||
resetTime();
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import { SlotCard } from './components/slot-card';
|
||||
import { DaySlotAddForm } from './day-slot-add-form';
|
||||
import { LoadingSpinner } from '@/components/common/spinner';
|
||||
import { ScheduleContext } from '@/context/schedule';
|
||||
import { useSlots } from '@/hooks/slots';
|
||||
import { useSlotsQuery } from '@/hooks/api/slots';
|
||||
import { use } from 'react';
|
||||
|
||||
export function DaySlotsList() {
|
||||
const { selectedDate } = use(ScheduleContext);
|
||||
const { data, isLoading } = useSlots({ date: selectedDate });
|
||||
const slots = data?.data.slots;
|
||||
const { data: { slots } = {}, isLoading } = useSlotsQuery({
|
||||
filters: { date: { eq: selectedDate } },
|
||||
});
|
||||
|
||||
if (isLoading) return <LoadingSpinner />;
|
||||
|
||||
|
||||
@ -1,37 +1,33 @@
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import { type SlotComponentProps } from './types';
|
||||
import { ScheduleContext } from '@/context/schedule';
|
||||
import { useSlotDelete, useSlotMutation, useSlotQuery } from '@/hooks/slots';
|
||||
import { useSlotDelete, useSlotMutation, useSlotQuery } from '@/hooks/api/slots';
|
||||
import { Enum_Slot_State } from '@repo/graphql/types';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { use } from 'react';
|
||||
|
||||
export function SlotButtons({ documentId }: Readonly<SlotComponentProps>) {
|
||||
const { data } = useSlotQuery({ documentId });
|
||||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||||
|
||||
const { mutate: updateSlot } = useSlotMutation({ documentId });
|
||||
|
||||
const { selectedDate } = use(ScheduleContext);
|
||||
const { mutate: deleteSlot } = useSlotDelete({ date: selectedDate, documentId });
|
||||
const { mutate: deleteSlot } = useSlotDelete({ documentId });
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const slot = data?.data?.slot;
|
||||
|
||||
if (!slot) return null;
|
||||
|
||||
const isOpened = slot?.state === Enum_Slot_State.Open;
|
||||
const isClosed = slot?.state === Enum_Slot_State.Closed;
|
||||
|
||||
function handleOpenSlot() {
|
||||
return updateSlot({ data: { state: Enum_Slot_State.Open }, documentId });
|
||||
return updateSlot({ data: { state: Enum_Slot_State.Open } });
|
||||
}
|
||||
|
||||
function handleCloseSlot() {
|
||||
return updateSlot({ data: { state: Enum_Slot_State.Closed }, documentId });
|
||||
return updateSlot({ data: { state: Enum_Slot_State.Closed } });
|
||||
}
|
||||
|
||||
function handleDeleteSlot() {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { SlotDate } from './components/slot-date';
|
||||
import { SlotTime } from './components/slot-time';
|
||||
import { ScheduleTimeContextProvider } from './context';
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import { OrderCard } from './components/order-card';
|
||||
import { type SlotComponentProps } from './types';
|
||||
import { useSlotQuery } from '@/hooks/slots';
|
||||
import { useSlotQuery } from '@/hooks/api/slots';
|
||||
|
||||
export function SlotOrdersList({ documentId }: Readonly<SlotComponentProps>) {
|
||||
const { data } = useSlotQuery({ documentId });
|
||||
const slot = data?.data?.slot;
|
||||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||||
|
||||
if (!slot) return null;
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ export const authOptions: AuthOptions = {
|
||||
},
|
||||
async session({ session, token }) {
|
||||
if (token?.id && session?.user) {
|
||||
session.user.telegramId = token.id as string;
|
||||
session.user.telegramId = token.id as number;
|
||||
}
|
||||
|
||||
return session;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, type PropsWithChildren, useMemo, useState } from 'react';
|
||||
|
||||
export type FilterType = 'all' | 'clients' | 'masters';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, useMemo, useState } from 'react';
|
||||
|
||||
type ContextType = {
|
||||
|
||||
23
apps/web/hooks/api/contacts/query.ts
Normal file
23
apps/web/hooks/api/contacts/query.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { getClients, getMasters } from '@/actions/api/customers';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useSession } from 'next-auth/react';
|
||||
|
||||
export const useClientsQuery = (props?: Parameters<typeof getClients>[0]) => {
|
||||
const { data: session } = useSession();
|
||||
const telegramId = props?.telegramId || session?.user?.telegramId;
|
||||
|
||||
return useQuery({
|
||||
queryFn: () => getClients({ telegramId }),
|
||||
queryKey: ['customer', 'telegramId', telegramId, 'clients'],
|
||||
});
|
||||
};
|
||||
|
||||
export const useMastersQuery = (props?: Parameters<typeof getMasters>[0]) => {
|
||||
const { data: session } = useSession();
|
||||
const telegramId = props?.telegramId || session?.user?.telegramId;
|
||||
|
||||
return useQuery({
|
||||
queryFn: () => getMasters({ telegramId }),
|
||||
queryKey: ['customer', 'telegramId', telegramId, 'masters'],
|
||||
});
|
||||
};
|
||||
@ -1,19 +1,12 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
import { useProfileQuery } from '../profile';
|
||||
|
||||
import { useClientsQuery, useMastersQuery } from './query';
|
||||
import { ContactsFilterContext } from '@/context/contacts-filter';
|
||||
import { Enum_Customer_Role } from '@repo/graphql/types';
|
||||
import { sift } from 'radash';
|
||||
import { use, useEffect, useMemo } from 'react';
|
||||
|
||||
type Parameters_ = {
|
||||
includeSelf: boolean;
|
||||
};
|
||||
|
||||
export function useCustomerContacts(parameters?: Parameters_) {
|
||||
export function useCustomerContacts() {
|
||||
const { filter, setFilter } = use(ContactsFilterContext);
|
||||
const { data: customer, isLoading: isLoadingProfile } = useProfileQuery();
|
||||
|
||||
const {
|
||||
data: clientsData,
|
||||
@ -27,14 +20,10 @@ export function useCustomerContacts(parameters?: Parameters_) {
|
||||
refetch: refetchMasters,
|
||||
} = useMastersQuery();
|
||||
|
||||
const clients = clientsData?.clients || [];
|
||||
let masters = mastersData?.masters || [];
|
||||
const clients = clientsData?.customers?.at(0)?.clients || [];
|
||||
const masters = mastersData?.customers?.at(0)?.masters || [];
|
||||
|
||||
if (parameters?.includeSelf && customer?.role === Enum_Customer_Role.Master) {
|
||||
masters = [{ ...customer, name: 'Я' }, ...masters];
|
||||
}
|
||||
|
||||
const isLoading = isLoadingClients || isLoadingMasters || isLoadingProfile;
|
||||
const isLoading = isLoadingClients || isLoadingMasters;
|
||||
|
||||
useEffect(() => {
|
||||
if (filter === 'clients') {
|
||||
35
apps/web/hooks/api/customers.ts
Normal file
35
apps/web/hooks/api/customers.ts
Normal file
@ -0,0 +1,35 @@
|
||||
'use client';
|
||||
|
||||
import { getCustomer, updateCustomer } from '@/actions/api/customers';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useSession } from 'next-auth/react';
|
||||
|
||||
export const useCustomerQuery = (variables?: Parameters<typeof getCustomer>[0]) => {
|
||||
const { data: session } = useSession();
|
||||
const telegramId = variables?.telegramId || session?.user?.telegramId;
|
||||
|
||||
return useQuery({
|
||||
enabled: Boolean(telegramId),
|
||||
queryFn: () => getCustomer({ telegramId }),
|
||||
queryKey: ['customer', telegramId],
|
||||
});
|
||||
};
|
||||
|
||||
export const useCustomerMutation = () => {
|
||||
const { data: session } = useSession();
|
||||
const telegramId = session?.user?.telegramId;
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const handleOnSuccess = () => {
|
||||
if (!telegramId) return;
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['customer', telegramId],
|
||||
});
|
||||
};
|
||||
|
||||
return useMutation({
|
||||
mutationFn: updateCustomer,
|
||||
onSuccess: handleOnSuccess,
|
||||
});
|
||||
};
|
||||
16
apps/web/hooks/api/orders.ts
Normal file
16
apps/web/hooks/api/orders.ts
Normal file
@ -0,0 +1,16 @@
|
||||
'use client';
|
||||
|
||||
import { createOrder, getOrder } from '@/actions/api/orders';
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const useOrderQuery = ({ documentId }: Parameters<typeof getOrder>[0]) =>
|
||||
useQuery({
|
||||
queryFn: () => getOrder({ documentId }),
|
||||
queryKey: ['order', documentId],
|
||||
});
|
||||
|
||||
export const useOrderCreate = () =>
|
||||
useMutation({
|
||||
mutationFn: createOrder,
|
||||
mutationKey: ['order', 'create'],
|
||||
});
|
||||
18
apps/web/hooks/api/services.ts
Normal file
18
apps/web/hooks/api/services.ts
Normal file
@ -0,0 +1,18 @@
|
||||
'use client';
|
||||
|
||||
import { getService, getServices } from '@/actions/api/services';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const useServicesQuery = (input: Parameters<typeof getServices>[0]) => {
|
||||
return useQuery({
|
||||
queryFn: () => getServices(input),
|
||||
queryKey: ['services', input],
|
||||
});
|
||||
};
|
||||
|
||||
export const useServiceQuery = (input: Parameters<typeof getService>[0]) => {
|
||||
return useQuery({
|
||||
queryFn: () => getService(input),
|
||||
queryKey: ['service', input.documentId],
|
||||
});
|
||||
};
|
||||
87
apps/web/hooks/api/slots.ts
Normal file
87
apps/web/hooks/api/slots.ts
Normal file
@ -0,0 +1,87 @@
|
||||
'use client';
|
||||
|
||||
import { useCustomerQuery } from './customers';
|
||||
import { createSlot, deleteSlot, getSlot, getSlots, updateSlot } from '@/actions/api/slots';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
export const useSlotsQuery = (variables: Parameters<typeof getSlots>[0]) => {
|
||||
const { data: { customer } = {} } = useCustomerQuery();
|
||||
|
||||
const masterId = variables.filters?.master?.documentId?.eq || customer?.documentId;
|
||||
const date = variables.filters?.date?.eq;
|
||||
|
||||
return useQuery({
|
||||
queryFn: () => getSlots(variables),
|
||||
queryKey: ['slots', { date: date?.toISOString(), masterId }],
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotQuery = (variables: Parameters<typeof getSlot>[0]) => {
|
||||
const { documentId } = variables;
|
||||
|
||||
return useQuery({
|
||||
queryFn: () => getSlot(variables),
|
||||
queryKey: ['slot', documentId],
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotMutation = ({
|
||||
documentId,
|
||||
}: Pick<Parameters<typeof updateSlot>[0], 'documentId'>) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ data }: Pick<Parameters<typeof updateSlot>[0], 'data'>) =>
|
||||
updateSlot({ data, documentId }),
|
||||
mutationKey: ['slot', 'update', documentId],
|
||||
onSuccess: () => {
|
||||
if (documentId) {
|
||||
queryClient.invalidateQueries({ queryKey: ['slot', documentId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotCreate = () => {
|
||||
const { data: { customer } = {} } = useCustomerQuery();
|
||||
const masterId = customer?.documentId;
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: createSlot,
|
||||
mutationKey: ['slot', 'create'],
|
||||
onSuccess: masterId
|
||||
? (data) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['slots', { date: data?.createSlot?.date?.toISOString(), masterId }],
|
||||
});
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotDelete = ({ documentId }: Parameters<typeof deleteSlot>[0]) => {
|
||||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: () => deleteSlot({ documentId }),
|
||||
mutationKey: ['slot', 'delete', documentId],
|
||||
onSuccess: () => {
|
||||
const date = slot?.date;
|
||||
const masterId = slot?.master;
|
||||
|
||||
if (date && masterId) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['slots', { date: date?.toISOString(), masterId }],
|
||||
});
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['slot', documentId],
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@ -1,8 +0,0 @@
|
||||
import { getClients, getMasters } from '@/actions/contacts';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const useClientsQuery = () =>
|
||||
useQuery({ enabled: false, queryFn: getClients, queryKey: ['contacts', 'clients', 'get'] });
|
||||
|
||||
export const useMastersQuery = () =>
|
||||
useQuery({ enabled: false, queryFn: getMasters, queryKey: ['contacts', 'masters', 'get'] });
|
||||
@ -1,24 +0,0 @@
|
||||
'use client';
|
||||
import { createOrder, getOrder } from '@/actions/orders';
|
||||
// eslint-disable-next-line sonarjs/no-internal-api-use
|
||||
import type * as ApolloTypes from '@repo/graphql/node_modules/@apollo/client/core';
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type FixTypescriptCringe = ApolloTypes.FetchResult;
|
||||
|
||||
type Props = {
|
||||
documentId: string;
|
||||
};
|
||||
|
||||
export const useOrderQuery = ({ documentId }: Props) =>
|
||||
useQuery({
|
||||
queryFn: () => getOrder({ documentId }),
|
||||
queryKey: ['orders', 'get', documentId],
|
||||
});
|
||||
|
||||
export const useOrderCreate = () =>
|
||||
useMutation({
|
||||
mutationFn: createOrder,
|
||||
mutationKey: ['orders', 'create'],
|
||||
});
|
||||
@ -1,23 +0,0 @@
|
||||
'use client';
|
||||
import { getProfile, updateProfile } from '@/actions/profile';
|
||||
import { type ProfileProps } from '@/components/profile/types';
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const useProfileQuery = (props?: ProfileProps) => {
|
||||
const telegramId = props?.telegramId;
|
||||
|
||||
return useQuery({
|
||||
queryFn: () => getProfile({ telegramId }),
|
||||
queryKey: telegramId ? ['profile', 'telegramId', telegramId, 'get'] : ['profile', 'get'],
|
||||
});
|
||||
};
|
||||
|
||||
export const useProfileMutation = () => {
|
||||
const { refetch } = useProfileQuery();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: updateProfile,
|
||||
mutationKey: ['profile', 'update'],
|
||||
onSuccess: () => refetch(),
|
||||
});
|
||||
};
|
||||
@ -1,15 +0,0 @@
|
||||
'use client';
|
||||
import { getServices } from '@/actions/services';
|
||||
// eslint-disable-next-line sonarjs/no-internal-api-use
|
||||
import type * as ApolloTypes from '@repo/graphql/node_modules/@apollo/client/core';
|
||||
import { type GetServicesQueryVariables } from '@repo/graphql/types';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type FixTypescriptCringe = ApolloTypes.FetchResult;
|
||||
|
||||
export const useServicesQuery = (input?: GetServicesQueryVariables) =>
|
||||
useQuery({
|
||||
queryFn: () => getServices(input),
|
||||
queryKey: ['services', 'list'],
|
||||
});
|
||||
@ -1,71 +0,0 @@
|
||||
'use client';
|
||||
import { addSlot, deleteSlot, getSlot, getSlots, updateSlot } from '@/actions/slots';
|
||||
import { formatDate } from '@/utils/date';
|
||||
// eslint-disable-next-line sonarjs/no-internal-api-use
|
||||
import type * as ApolloTypes from '@repo/graphql/node_modules/@apollo/client/core';
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type FixTypescriptCringe = ApolloTypes.FetchResult;
|
||||
|
||||
type SlotAddInput = {
|
||||
date: Date;
|
||||
};
|
||||
|
||||
type SlotMutationInput = {
|
||||
documentId: string;
|
||||
};
|
||||
|
||||
type SlotQueryInput = {
|
||||
date: Date;
|
||||
masterId?: null | string;
|
||||
};
|
||||
|
||||
export const useSlots = ({ date, masterId }: SlotQueryInput) => {
|
||||
return useQuery({
|
||||
queryFn: () =>
|
||||
getSlots({
|
||||
filters: {
|
||||
date: { eq: formatDate(date).db() },
|
||||
master: masterId ? { documentId: { eq: masterId } } : undefined,
|
||||
},
|
||||
}),
|
||||
queryKey: ['slots', 'master', masterId, 'list', date],
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotQuery = ({ documentId }: SlotMutationInput) =>
|
||||
useQuery({
|
||||
queryFn: () => getSlot({ documentId }),
|
||||
queryKey: ['slots', 'get', documentId],
|
||||
});
|
||||
|
||||
export const useSlotMutation = ({ documentId }: SlotMutationInput) => {
|
||||
const { refetch } = useSlotQuery({ documentId });
|
||||
|
||||
return useMutation({
|
||||
mutationFn: updateSlot,
|
||||
mutationKey: ['slots', 'update', documentId],
|
||||
onSuccess: () => refetch(),
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotAdd = ({ date }: SlotAddInput) => {
|
||||
const { refetch } = useSlots({ date });
|
||||
|
||||
return useMutation({
|
||||
mutationFn: addSlot,
|
||||
mutationKey: ['slots', 'add'],
|
||||
onSuccess: () => refetch(),
|
||||
});
|
||||
};
|
||||
|
||||
export const useSlotDelete = ({ date, documentId }: SlotAddInput & SlotMutationInput) => {
|
||||
const { refetch } = useSlots({ date });
|
||||
|
||||
return useMutation({
|
||||
mutationFn: () => deleteSlot({ documentId }),
|
||||
mutationKey: ['slots', 'delete', documentId],
|
||||
onSuccess: () => refetch(),
|
||||
});
|
||||
};
|
||||
@ -5,7 +5,7 @@ import { env } from '@/config/env';
|
||||
export async function getTelegramUser() {
|
||||
if (process.env.NODE_ENV !== 'production')
|
||||
return {
|
||||
id: env.__DEV_TELEGRAM_ID,
|
||||
id: Number.parseInt(env.__DEV_TELEGRAM_ID, 10),
|
||||
};
|
||||
|
||||
return null;
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
"@repo/ui": "workspace:*",
|
||||
"@tanstack/react-query": "^5.64.1",
|
||||
"@telegram-apps/sdk-react": "^2.0.19",
|
||||
"dayjs": "^1.11.13",
|
||||
"dayjs": "catalog:",
|
||||
"graphql": "catalog:",
|
||||
"lucide-react": "catalog:",
|
||||
"next": "15.3.0",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { SessionProvider } from 'next-auth/react';
|
||||
|
||||
export function AuthProvider({ children }: { readonly children: React.ReactNode }) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* eslint-disable sonarjs/function-return-type */
|
||||
'use client';
|
||||
|
||||
import { useClientOnce, useDidMount } from '@/hooks/telegram';
|
||||
import { setLocale } from '@/utils/i18n/locale';
|
||||
import { init } from '@/utils/telegram/init';
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
||||
import { type ComponentProps, useEffect, useState } from 'react';
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { createOrderStore } from './store';
|
||||
import { createContext, type PropsWithChildren, useRef } from 'react';
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import { OrderStoreContext } from './context';
|
||||
import { type OrderStore, type Steps } from './types';
|
||||
import { useProfileQuery } from '@/hooks/profile';
|
||||
import { useCustomerQuery } from '@/hooks/api/customers';
|
||||
import { Enum_Customer_Role } from '@repo/graphql/types';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { useStore } from 'zustand';
|
||||
@ -28,7 +29,7 @@ export const MASTER_STEPS: Steps[] = STEPS.filter((step) => step !== 'master-sel
|
||||
export const CLIENT_STEPS: Steps[] = STEPS.filter((step) => step !== 'client-select');
|
||||
|
||||
export function useInitOrderStore() {
|
||||
const { data } = useProfileQuery();
|
||||
const { data: { customer } = {} } = useCustomerQuery();
|
||||
|
||||
const setMasterId = useOrderStore((store) => store.setMasterId);
|
||||
const setClientId = useOrderStore((store) => store.setClientId);
|
||||
@ -36,14 +37,14 @@ export function useInitOrderStore() {
|
||||
const setStepsSequence = useOrderStore((store) => store._setStepSequence);
|
||||
|
||||
useEffect(() => {
|
||||
const role = data?.role;
|
||||
const role = customer?.role;
|
||||
|
||||
if (role === Enum_Customer_Role.Master && data) {
|
||||
setMasterId(data?.documentId);
|
||||
if (role === Enum_Customer_Role.Master && customer) {
|
||||
setMasterId(customer?.documentId);
|
||||
}
|
||||
|
||||
if (role === Enum_Customer_Role.Client && data) {
|
||||
setClientId(data?.documentId);
|
||||
if (role === Enum_Customer_Role.Client && customer) {
|
||||
setClientId(customer?.documentId);
|
||||
}
|
||||
|
||||
const steps = role === Enum_Customer_Role.Master ? MASTER_STEPS : CLIENT_STEPS;
|
||||
@ -51,5 +52,5 @@ export function useInitOrderStore() {
|
||||
|
||||
setStepsSequence(steps);
|
||||
setStep(initialStep);
|
||||
}, [data, setClientId, setMasterId, setStep, setStepsSequence]);
|
||||
}, [customer, setClientId, setMasterId, setStep, setStepsSequence]);
|
||||
}
|
||||
|
||||
4
apps/web/types/next-auth.d.ts
vendored
4
apps/web/types/next-auth.d.ts
vendored
@ -4,11 +4,11 @@ import { type DefaultSession } from 'next-auth';
|
||||
declare module 'next-auth' {
|
||||
interface Session extends DefaultSession {
|
||||
user?: {
|
||||
telegramId?: null | string;
|
||||
telegramId?: null | number;
|
||||
};
|
||||
}
|
||||
|
||||
interface User extends DefaultUser {
|
||||
telegramId?: null | string;
|
||||
telegramId?: null | number;
|
||||
}
|
||||
}
|
||||
|
||||
15
packages/graphql/api/base.ts
Normal file
15
packages/graphql/api/base.ts
Normal file
@ -0,0 +1,15 @@
|
||||
type CustomerProfile = {
|
||||
telegramId: number;
|
||||
};
|
||||
|
||||
export class BaseService {
|
||||
protected customer: CustomerProfile;
|
||||
|
||||
constructor(customer: CustomerProfile) {
|
||||
if (!customer?.telegramId) {
|
||||
throw new Error('Invalid customer profile: telegramId required');
|
||||
}
|
||||
|
||||
this.customer = customer;
|
||||
}
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
'use server';
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
|
||||
export async function createOrUpdateUser(input: GQL.CreateCustomerMutationVariables) {
|
||||
if (!input.phone && !input.telegramId) throw new Error('Missing phone and telegramId');
|
||||
|
||||
const { query, mutate } = await getClientWithToken();
|
||||
|
||||
const response = await query({
|
||||
query: GQL.GetCustomerDocument,
|
||||
variables: input,
|
||||
});
|
||||
|
||||
const customer = response?.data?.customers?.at(0);
|
||||
|
||||
if (customer && customer.phone === input.phone) {
|
||||
return mutate({
|
||||
mutation: GQL.UpdateCustomerProfileDocument,
|
||||
variables: {
|
||||
documentId: customer.documentId,
|
||||
data: { ...input },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return mutate({
|
||||
mutation: GQL.CreateCustomerDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCustomer(input: GQL.GetCustomerQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetCustomerDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCustomerMasters(input: GQL.GetCustomerMastersQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetCustomerMastersDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCustomerClients(input: GQL.GetCustomerClientsQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetCustomerClientsDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
type AddCustomerMasterInput = Pick<GQL.CreateCustomerMutationVariables, 'phone' | 'telegramId'> & {
|
||||
masterId: GQL.Scalars['ID']['input'];
|
||||
operation: 'add' | 'remove';
|
||||
};
|
||||
|
||||
export async function updateCustomerMaster(input: AddCustomerMasterInput) {
|
||||
if (!input.phone && !input.telegramId) throw new Error('Missing phone and telegramId');
|
||||
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const response = await query({
|
||||
query: GQL.GetCustomerMastersDocument,
|
||||
variables: input,
|
||||
});
|
||||
|
||||
const customer = response?.data?.customers?.at(0);
|
||||
|
||||
if (customer) {
|
||||
let newMastersIds = customer.masters.map((x) => x?.documentId);
|
||||
|
||||
switch (input.operation) {
|
||||
case 'add':
|
||||
if (newMastersIds.includes(input.masterId)) return;
|
||||
newMastersIds = [...newMastersIds, input.masterId];
|
||||
break;
|
||||
case 'remove':
|
||||
newMastersIds = newMastersIds.filter((x) => x !== input.masterId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return updateCustomerProfile({
|
||||
documentId: customer.documentId,
|
||||
data: {
|
||||
masters: newMastersIds,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateCustomerProfile(input: GQL.UpdateCustomerProfileMutationVariables) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
return mutate({
|
||||
mutation: GQL.UpdateCustomerProfileDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
116
packages/graphql/api/customers.ts
Normal file
116
packages/graphql/api/customers.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
import { BaseService } from './base';
|
||||
import { type VariablesOf } from '@graphql-typed-document-node/core';
|
||||
|
||||
export class CustomersService extends BaseService {
|
||||
async addMasters(variables: VariablesOf<typeof GQL.UpdateCustomerDocument>) {
|
||||
const newMasterIds = variables.data.masters;
|
||||
|
||||
const { mutate, query } = await getClientWithToken();
|
||||
const getMastersResult = await query({
|
||||
query: GQL.GetMastersDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
const existingMasterIds = getMastersResult?.data?.customers
|
||||
?.at(0)
|
||||
?.masters.map((x) => x?.documentId);
|
||||
|
||||
const newMastersIds = [...new Set([...(existingMasterIds || []), ...(newMasterIds || [])])];
|
||||
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.UpdateCustomerDocument,
|
||||
variables: {
|
||||
data: { masters: newMastersIds },
|
||||
documentId: variables.documentId,
|
||||
},
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
|
||||
async createCustomer(variables: VariablesOf<typeof GQL.CreateCustomerDocument>) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.CreateCustomerDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
|
||||
async getCustomer(variables: VariablesOf<typeof GQL.GetCustomerDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetCustomerDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
const customer = result.data.customers.at(0);
|
||||
|
||||
return { customer };
|
||||
}
|
||||
|
||||
async getClients(variables?: VariablesOf<typeof GQL.GetClientsDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetClientsDocument,
|
||||
variables: {
|
||||
telegramId: variables?.telegramId || this.customer.telegramId,
|
||||
},
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async getMasters(variables?: VariablesOf<typeof GQL.GetMastersDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetMastersDocument,
|
||||
variables: {
|
||||
telegramId: variables?.telegramId || this.customer.telegramId,
|
||||
},
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async updateCustomer(
|
||||
variables: Omit<VariablesOf<typeof GQL.UpdateCustomerDocument>, 'documentId'>,
|
||||
) {
|
||||
const { customer } = await this.getCustomer(this.customer);
|
||||
|
||||
if (!customer) throw new Error('Customer not found');
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.UpdateCustomerDocument,
|
||||
variables: {
|
||||
data: variables.data,
|
||||
documentId: customer.documentId,
|
||||
},
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
export * from './auth';
|
||||
export * from './customer';
|
||||
export * from './slot';
|
||||
export * from './order';
|
||||
export * from './service';
|
||||
@ -1,21 +0,0 @@
|
||||
'use server';
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
|
||||
export async function getOrder(variables: GQL.GetOrderQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetOrderDocument,
|
||||
variables,
|
||||
});
|
||||
}
|
||||
|
||||
export async function createOrder(input: GQL.CreateOrderMutationVariables['input']) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
return mutate({
|
||||
mutation: GQL.CreateOrderDocument,
|
||||
variables: { input },
|
||||
});
|
||||
}
|
||||
100
packages/graphql/api/orders.ts
Normal file
100
packages/graphql/api/orders.ts
Normal file
@ -0,0 +1,100 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
import { Enum_Customer_Role, Enum_Slot_State } from '../types';
|
||||
import { formatDate, formatTime, sumTime } from '../utils/datetime-format';
|
||||
import { BaseService } from './base';
|
||||
import { CustomersService } from './customers';
|
||||
import { ServicesService } from './services';
|
||||
import { SlotsService } from './slots';
|
||||
import { type VariablesOf } from '@graphql-typed-document-node/core';
|
||||
|
||||
const ERRORS = {
|
||||
INVALID_CLIENT: 'Invalid client',
|
||||
INVALID_MASTER: 'Invalid master',
|
||||
MISSING_CLIENT: 'Missing client id',
|
||||
MISSING_SERVICE_ID: 'Missing service id',
|
||||
MISSING_SERVICES: 'Missing services',
|
||||
MISSING_SLOT: 'Missing slot id',
|
||||
MISSING_START_TIME: 'Missing time start',
|
||||
SLOT_CLOSED: 'Slot is closed',
|
||||
};
|
||||
|
||||
export class OrdersService extends BaseService {
|
||||
async createOrder(variables: {
|
||||
input: Omit<VariablesOf<typeof GQL.CreateOrderDocument>['input'], 'time_end'>;
|
||||
}) {
|
||||
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);
|
||||
|
||||
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);
|
||||
const { slot } = await slotsService.getSlot({ documentId: variables.input.slot });
|
||||
|
||||
if (slot?.state === Enum_Slot_State.Closed) {
|
||||
throw new Error(ERRORS.SLOT_CLOSED);
|
||||
}
|
||||
|
||||
if (customer?.role === Enum_Customer_Role.Client) {
|
||||
if (customer.documentId !== variables.input.client) {
|
||||
throw new Error(ERRORS.INVALID_CLIENT);
|
||||
}
|
||||
|
||||
const masters = await customersService.getMasters(this.customer);
|
||||
const masterId = slot?.master?.documentId;
|
||||
if (!masters.customers.some((master) => master?.documentId === masterId)) {
|
||||
throw new Error(ERRORS.INVALID_MASTER);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
customer?.role === Enum_Customer_Role.Master &&
|
||||
slot?.master?.documentId !== customer.documentId
|
||||
) {
|
||||
throw new Error(ERRORS.INVALID_MASTER);
|
||||
}
|
||||
|
||||
const { service } = await servicesService.getService({
|
||||
documentId: variables.input.services[0],
|
||||
});
|
||||
const endTime = sumTime(variables.input.time_start, service?.duration);
|
||||
const { mutate } = await getClientWithToken();
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.CreateOrderDocument,
|
||||
variables: {
|
||||
input: {
|
||||
client: variables.input.client,
|
||||
date: formatDate(variables.input.date).db(),
|
||||
services: variables.input.services,
|
||||
slot: variables.input.slot,
|
||||
time_end: formatTime(endTime).db(),
|
||||
time_start: formatTime(variables.input.time_start).db(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
|
||||
async getOrder(variables: VariablesOf<typeof GQL.GetOrderDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetOrderDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
'use server';
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
|
||||
export async function getServices(input: GQL.GetServicesQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetServicesDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getService(input: GQL.GetServiceQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetServiceDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
32
packages/graphql/api/services.ts
Normal file
32
packages/graphql/api/services.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
import { BaseService } from './base';
|
||||
import { type VariablesOf } from '@graphql-typed-document-node/core';
|
||||
|
||||
export class ServicesService extends BaseService {
|
||||
async getService(variables: VariablesOf<typeof GQL.GetServiceDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetServiceDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async getServices(variables: VariablesOf<typeof GQL.GetServicesDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetServicesDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
'use server';
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
|
||||
export async function createSlot(input: GQL.CreateSlotMutationVariables['input']) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
return mutate({
|
||||
mutation: GQL.CreateSlotDocument,
|
||||
variables: { input },
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSlots(input: GQL.GetSlotsQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetSlotsDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getSlot(input: GQL.GetSlotQueryVariables) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
return query({
|
||||
query: GQL.GetSlotDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateSlot(input: GQL.UpdateSlotMutationVariables) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
return mutate({
|
||||
mutation: GQL.UpdateSlotDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteSlot(input: GQL.DeleteSlotMutationVariables) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
return mutate({
|
||||
mutation: GQL.DeleteSlotDocument,
|
||||
variables: input,
|
||||
});
|
||||
}
|
||||
98
packages/graphql/api/slots.ts
Normal file
98
packages/graphql/api/slots.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { getClientWithToken } from '../apollo/client';
|
||||
import * as GQL from '../types';
|
||||
import { formatDate, formatTime } from '../utils/datetime-format';
|
||||
import { BaseService } from './base';
|
||||
import { CustomersService } from './customers';
|
||||
import { type VariablesOf } from '@graphql-typed-document-node/core';
|
||||
|
||||
export class SlotsService extends BaseService {
|
||||
async createSlot(variables: VariablesOf<typeof GQL.CreateSlotDocument>) {
|
||||
const customerService = new CustomersService(this.customer);
|
||||
|
||||
const { customer } = await customerService.getCustomer(this.customer);
|
||||
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.CreateSlotDocument,
|
||||
variables: {
|
||||
...variables,
|
||||
date: formatDate(variables.input.date).db(),
|
||||
master: customer?.documentId,
|
||||
time_end: formatTime(variables.input.time_end).db(),
|
||||
time_start: formatTime(variables.input.time_start).db(),
|
||||
},
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
|
||||
async deleteSlot(variables: VariablesOf<typeof GQL.DeleteSlotDocument>) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.DeleteSlotDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
|
||||
async getSlot(variables: VariablesOf<typeof GQL.GetSlotDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetSlotDocument,
|
||||
variables,
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async getSlots(variables: VariablesOf<typeof GQL.GetSlotsDocument>) {
|
||||
const { query } = await getClientWithToken();
|
||||
|
||||
const result = await query({
|
||||
query: GQL.GetSlotsDocument,
|
||||
variables: {
|
||||
filters: {
|
||||
...variables.filters,
|
||||
date: { eq: formatDate(variables?.filters?.date?.eq).db() },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (result.error) throw new Error(result.error.message);
|
||||
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async updateSlot(variables: VariablesOf<typeof GQL.UpdateSlotDocument>) {
|
||||
const { mutate } = await getClientWithToken();
|
||||
|
||||
const mutationResult = await mutate({
|
||||
mutation: GQL.UpdateSlotDocument,
|
||||
variables: {
|
||||
...variables,
|
||||
date: variables.data?.date ? formatDate(variables.data.date).db() : undefined,
|
||||
time_end: variables.data?.time_end ? formatTime(variables.data.time_end).db() : undefined,
|
||||
time_start: variables.data?.time_start
|
||||
? formatTime(variables.data.time_start).db()
|
||||
: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const error = mutationResult.errors?.at(0);
|
||||
if (error) throw new Error(error.message);
|
||||
|
||||
return mutationResult.data;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { login } from '../api';
|
||||
import { login } from '../api/auth';
|
||||
import { isTokenExpired } from '../utils/jwt';
|
||||
|
||||
export const token: null | string = null;
|
||||
|
||||
@ -4,6 +4,6 @@ import { typescript } from '@repo/eslint-config/typescript';
|
||||
export default [
|
||||
...typescript,
|
||||
{
|
||||
ignores: ['**/graphql/types.ts', '**/schema.graphql'],
|
||||
ignores: ['**/types/**'],
|
||||
},
|
||||
];
|
||||
|
||||
@ -5,9 +5,12 @@ module.exports = {
|
||||
'./types/operations.generated.ts': {
|
||||
config: {
|
||||
avoidOptionals: false,
|
||||
maybeValue: 'T | null | undefined',
|
||||
onlyOperationTypes: true,
|
||||
scalars: {
|
||||
Long: 'number',
|
||||
},
|
||||
useTypeImports: true,
|
||||
maybeValue: 'T | null | undefined'
|
||||
},
|
||||
plugins: ['typescript', 'typescript-operations', 'typed-document-node'],
|
||||
},
|
||||
|
||||
@ -20,11 +20,15 @@ query GetCustomer($phone: String, $telegramId: Long) {
|
||||
}
|
||||
}
|
||||
|
||||
query GetCustomerMasters($phone: String, $telegramId: Long) {
|
||||
query GetMasters($phone: String, $telegramId: Long, $documentId: ID) {
|
||||
customers(
|
||||
filters: {
|
||||
or: [{ phone: { eq: $phone } }, { telegramId: { eq: $telegramId } }]
|
||||
and: [{ active: { eq: true } }]
|
||||
or: [
|
||||
{ phone: { eq: $phone } }
|
||||
{ telegramId: { eq: $telegramId } }
|
||||
{ documentId: { eq: $documentId } }
|
||||
]
|
||||
# and: [{ active: { eq: true } }]
|
||||
}
|
||||
) {
|
||||
documentId
|
||||
@ -34,11 +38,11 @@ query GetCustomerMasters($phone: String, $telegramId: Long) {
|
||||
}
|
||||
}
|
||||
|
||||
query GetCustomerClients($phone: String, $telegramId: Long) {
|
||||
query GetClients($phone: String, $telegramId: Long) {
|
||||
customers(
|
||||
filters: {
|
||||
or: [{ phone: { eq: $phone } }, { telegramId: { eq: $telegramId } }]
|
||||
and: [{ active: { eq: true } }]
|
||||
# and: [{ active: { eq: true } }]
|
||||
}
|
||||
) {
|
||||
documentId
|
||||
@ -48,7 +52,7 @@ query GetCustomerClients($phone: String, $telegramId: Long) {
|
||||
}
|
||||
}
|
||||
|
||||
mutation UpdateCustomerProfile($documentId: ID!, $data: CustomerInput!) {
|
||||
mutation UpdateCustomer($documentId: ID!, $data: CustomerInput!) {
|
||||
updateCustomer(documentId: $documentId, data: $data) {
|
||||
...CustomerFields
|
||||
}
|
||||
|
||||
@ -9,19 +9,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "catalog:",
|
||||
"dayjs": "catalog:",
|
||||
"jsonwebtoken": "catalog:",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"graphql": "catalog:",
|
||||
"@repo/eslint-config": "workspace:*",
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
"@types/jsonwebtoken": "^9.0.7",
|
||||
"@graphql-codegen/cli": "^5.0.3",
|
||||
"@graphql-codegen/typed-document-node": "^5.0.12",
|
||||
"@graphql-codegen/typescript": "^4.1.2",
|
||||
"@graphql-codegen/typescript-operations": "^4.4.0",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@repo/eslint-config": "workspace:*",
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
"@types/jsonwebtoken": "^9.0.7",
|
||||
"graphql": "catalog:",
|
||||
"vite-tsconfig-paths": "catalog:",
|
||||
"vitest": "catalog:"
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ export type Scalars = {
|
||||
Date: { input: any; output: any; }
|
||||
DateTime: { input: any; output: any; }
|
||||
JSON: { input: any; output: any; }
|
||||
Long: { input: any; output: any; }
|
||||
Long: { input: number; output: number; }
|
||||
Time: { input: any; output: any; }
|
||||
};
|
||||
|
||||
@ -651,7 +651,7 @@ export type LoginMutationVariables = Exact<{
|
||||
|
||||
export type LoginMutation = { __typename?: 'Mutation', login: { __typename?: 'UsersPermissionsLoginPayload', jwt?: string | null | undefined } };
|
||||
|
||||
export type CustomerFieldsFragment = { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: any | null | undefined };
|
||||
export type CustomerFieldsFragment = { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: number | null | undefined };
|
||||
|
||||
export type CreateCustomerMutationVariables = Exact<{
|
||||
name: Scalars['String']['input'];
|
||||
@ -668,31 +668,32 @@ export type GetCustomerQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetCustomerQuery = { __typename?: 'Query', customers: Array<{ __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: any | null | undefined } | null | undefined> };
|
||||
export type GetCustomerQuery = { __typename?: 'Query', customers: Array<{ __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 GetCustomerMastersQueryVariables = Exact<{
|
||||
export type GetMastersQueryVariables = Exact<{
|
||||
phone?: InputMaybe<Scalars['String']['input']>;
|
||||
telegramId?: InputMaybe<Scalars['Long']['input']>;
|
||||
documentId?: InputMaybe<Scalars['ID']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetMastersQuery = { __typename?: 'Query', customers: Array<{ __typename?: 'Customer', documentId: string, masters: Array<{ __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 GetClientsQueryVariables = Exact<{
|
||||
phone?: InputMaybe<Scalars['String']['input']>;
|
||||
telegramId?: InputMaybe<Scalars['Long']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetCustomerMastersQuery = { __typename?: 'Query', customers: Array<{ __typename?: 'Customer', documentId: string, masters: Array<{ __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: any | null | undefined } | null | undefined> } | null | undefined> };
|
||||
export type GetClientsQuery = { __typename?: 'Query', customers: Array<{ __typename?: 'Customer', documentId: string, clients: Array<{ __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 GetCustomerClientsQueryVariables = Exact<{
|
||||
phone?: InputMaybe<Scalars['String']['input']>;
|
||||
telegramId?: InputMaybe<Scalars['Long']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetCustomerClientsQuery = { __typename?: 'Query', customers: Array<{ __typename?: 'Customer', documentId: string, clients: Array<{ __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: any | null | undefined } | null | undefined> } | null | undefined> };
|
||||
|
||||
export type UpdateCustomerProfileMutationVariables = Exact<{
|
||||
export type UpdateCustomerMutationVariables = Exact<{
|
||||
documentId: Scalars['ID']['input'];
|
||||
data: CustomerInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateCustomerProfileMutation = { __typename?: 'Mutation', updateCustomer?: { __typename?: 'Customer', active?: boolean | null | undefined, documentId: string, name: string, phone: string, photoUrl?: string | null | undefined, role: Enum_Customer_Role, telegramId?: any | null | undefined } | null | undefined };
|
||||
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?: any | null | undefined, time_end?: any | 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', name: string, documentId: string, photoUrl?: string | null | undefined } | null | undefined };
|
||||
|
||||
@ -772,9 +773,9 @@ export const RegisterDocument = {"kind":"Document","definitions":[{"kind":"Opera
|
||||
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<LoginMutation, LoginMutationVariables>;
|
||||
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<CreateCustomerMutation, CreateCustomerMutationVariables>;
|
||||
export const GetCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetCustomer"},"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":"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<GetCustomerQuery, GetCustomerQueryVariables>;
|
||||
export const GetCustomerMastersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetCustomerMasters"},"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"}}}]}}]}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"and"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"active"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"BooleanValue","value":true}}]}}]}]}}]}}],"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<GetCustomerMastersQuery, GetCustomerMastersQueryVariables>;
|
||||
export const GetCustomerClientsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetCustomerClients"},"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"}}}]}}]}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"and"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"active"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"BooleanValue","value":true}}]}}]}]}}]}}],"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<GetCustomerClientsQuery, GetCustomerClientsQueryVariables>;
|
||||
export const UpdateCustomerProfileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateCustomerProfile"},"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<UpdateCustomerProfileMutation, UpdateCustomerProfileMutationVariables>;
|
||||
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<GetMastersQuery, GetMastersQueryVariables>;
|
||||
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<GetClientsQuery, GetClientsQueryVariables>;
|
||||
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<UpdateCustomerMutation, UpdateCustomerMutationVariables>;
|
||||
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":"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":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}}]}}]}}]} as unknown as DocumentNode<GetOrderQuery, GetOrderQueryVariables>;
|
||||
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":"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":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}}]}}]}}]} as unknown as DocumentNode<CreateOrderMutation, CreateOrderMutationVariables>;
|
||||
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<GetServicesQuery, GetServicesQueryVariables>;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
"esModuleInterop": true,
|
||||
"incremental": false,
|
||||
"isolatedModules": true,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
||||
import { cn } from '@repo/ui/lib/utils';
|
||||
import * as React from 'react';
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-shadow */
|
||||
/* eslint-disable react/no-unstable-nested-components */
|
||||
'use client';
|
||||
|
||||
import { buttonVariants } from '@repo/ui/components/ui/button';
|
||||
import { cn } from '@repo/ui/lib/utils';
|
||||
import { ru } from 'date-fns/locale';
|
||||
|
||||
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@ -24,6 +24,9 @@ catalogs:
|
||||
autoprefixer:
|
||||
specifier: ^10.4.20
|
||||
version: 10.4.20
|
||||
dayjs:
|
||||
specifier: ^1.11.3
|
||||
version: 1.11.13
|
||||
dotenv-cli:
|
||||
specifier: ^7.4.4
|
||||
version: 7.4.4
|
||||
@ -148,7 +151,7 @@ importers:
|
||||
specifier: ^2.0.19
|
||||
version: 2.0.19(@types/react@19.1.2)(react@19.1.0)
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
specifier: 'catalog:'
|
||||
version: 1.11.13
|
||||
graphql:
|
||||
specifier: 'catalog:'
|
||||
@ -268,6 +271,9 @@ importers:
|
||||
'@apollo/client':
|
||||
specifier: 'catalog:'
|
||||
version: 3.12.4(@types/react@19.1.2)(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
dayjs:
|
||||
specifier: 'catalog:'
|
||||
version: 1.11.13
|
||||
jsonwebtoken:
|
||||
specifier: 'catalog:'
|
||||
version: 9.0.2
|
||||
@ -290,6 +296,9 @@ importers:
|
||||
'@graphql-typed-document-node/core':
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(graphql@16.9.0)
|
||||
'@repo/eslint-config':
|
||||
specifier: workspace:*
|
||||
version: link:../eslint-config
|
||||
'@repo/typescript-config':
|
||||
specifier: workspace:*
|
||||
version: link:../typescript-config
|
||||
|
||||
@ -8,6 +8,7 @@ catalog:
|
||||
"@types/react-dom": ^19.1.2
|
||||
"@vchikalkin/eslint-config-awesome": ^2.2.2
|
||||
autoprefixer: ^10.4.20
|
||||
dayjs: ^1.11.3
|
||||
dotenv-cli: ^7.4.4
|
||||
eslint: ^9.17.0
|
||||
graphql: ^16.9.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user