- Renamed InvitedByGrid to MastersGrid and InvitedGrid to ClientsGrid for clarity. - Enhanced customer role checks by using documentId for identifying the current user. - Updated the contacts passed to grid components to reflect the new naming and role structure. - Adjusted titles in grid components for better user experience.
139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
/* eslint-disable canonical/id-match */
|
|
'use client';
|
|
|
|
import { CardSectionHeader } from '@/components/ui';
|
|
import { ContactsContextProvider } from '@/context/contacts';
|
|
import { useCustomerContacts } from '@/hooks/api/contacts';
|
|
import { useCustomerQuery } from '@/hooks/api/customers';
|
|
// eslint-disable-next-line import/extensions
|
|
import AvatarPlaceholder from '@/public/avatar/avatar_placeholder.png';
|
|
import { useOrderStore } from '@/stores/order';
|
|
import { withContext } from '@/utils/context';
|
|
import { type CustomerFieldsFragment, Enum_Customer_Role } from '@repo/graphql/types';
|
|
import { Card } from '@repo/ui/components/ui/card';
|
|
import { Label } from '@repo/ui/components/ui/label';
|
|
import { LoadingSpinner } from '@repo/ui/components/ui/spinner';
|
|
import { cn } from '@repo/ui/lib/utils';
|
|
import Image from 'next/image';
|
|
import { useEffect } from 'react';
|
|
|
|
type ContactsGridProps = {
|
|
readonly contacts: CustomerFieldsFragment[];
|
|
readonly onSelect: (contactId: null | string) => void;
|
|
readonly selected?: null | string;
|
|
readonly title: string;
|
|
};
|
|
|
|
export function ContactsGridBase({ contacts, onSelect, selected, title }: ContactsGridProps) {
|
|
const { data: { customer } = {} } = useCustomerQuery();
|
|
|
|
return (
|
|
<Card className="p-4">
|
|
<div className="flex flex-col gap-4">
|
|
<CardSectionHeader title={title} />
|
|
<div className="grid max-h-screen grid-cols-4 gap-2 overflow-y-auto">
|
|
{contacts.map((contact) => {
|
|
if (!contact) return null;
|
|
|
|
const isCurrentUser = contact?.documentId === customer?.documentId;
|
|
|
|
return (
|
|
<Label
|
|
className="flex cursor-pointer flex-col items-center"
|
|
key={contact?.documentId}
|
|
>
|
|
<input
|
|
checked={selected === contact?.documentId}
|
|
className="hidden"
|
|
name="user"
|
|
onChange={() => onSelect(contact?.documentId)}
|
|
type="radio"
|
|
value={contact?.documentId}
|
|
/>
|
|
<div
|
|
className={cn(
|
|
'w-20 h-20 rounded-full border-2 transition-all duration-75',
|
|
selected === contact?.documentId ? 'border-primary' : 'border-transparent',
|
|
)}
|
|
>
|
|
<div
|
|
className={cn(
|
|
'size-full rounded-full p-1',
|
|
isCurrentUser
|
|
? 'bg-gradient-to-r from-purple-500 to-pink-500'
|
|
: 'bg-transparent',
|
|
)}
|
|
>
|
|
<Image
|
|
alt={contact?.name}
|
|
className="size-full rounded-full object-cover"
|
|
height={80}
|
|
src={contact?.photoUrl || AvatarPlaceholder}
|
|
width={80}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<span
|
|
className={cn(
|
|
'mt-2 max-w-20 break-words text-center text-sm font-medium',
|
|
isCurrentUser && 'font-bold',
|
|
)}
|
|
>
|
|
{contact?.name}
|
|
</span>
|
|
</Label>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
export const MastersGrid = withContext(ContactsContextProvider)(function () {
|
|
const { data: { customer } = {}, isLoading: isLoadingCustomer } = useCustomerQuery();
|
|
const { contacts, isLoading: isLoadingContacts, setFilter } = useCustomerContacts();
|
|
const masterId = useOrderStore((store) => store.masterId);
|
|
const setMasterId = useOrderStore((store) => store.setMasterId);
|
|
|
|
const isLoading = isLoadingContacts || isLoadingCustomer;
|
|
|
|
useEffect(() => {
|
|
setFilter('invitedBy');
|
|
}, [setFilter]);
|
|
|
|
if (isLoading) return <LoadingSpinner />;
|
|
|
|
return (
|
|
<ContactsGridBase
|
|
contacts={(customer ? [{ ...customer, name: 'Я' }] : []).concat(
|
|
contacts.filter((contact) => contact.role === Enum_Customer_Role.Master),
|
|
)}
|
|
onSelect={(contactId) => setMasterId(contactId)}
|
|
selected={masterId}
|
|
title="Выбор мастера"
|
|
/>
|
|
);
|
|
});
|
|
|
|
export const ClientsGrid = withContext(ContactsContextProvider)(function () {
|
|
const { contacts, isLoading, setFilter } = useCustomerContacts();
|
|
const clientId = useOrderStore((store) => store.clientId);
|
|
const setClientId = useOrderStore((store) => store.setClientId);
|
|
|
|
useEffect(() => {
|
|
setFilter('invited');
|
|
}, [setFilter]);
|
|
|
|
if (isLoading) return <LoadingSpinner />;
|
|
|
|
return (
|
|
<ContactsGridBase
|
|
contacts={contacts}
|
|
onSelect={(contactId) => setClientId(contactId)}
|
|
selected={clientId}
|
|
title="Выбор клиента"
|
|
/>
|
|
);
|
|
});
|