174 lines
5.7 KiB
TypeScript
174 lines
5.7 KiB
TypeScript
'use client';
|
|
|
|
import { useMemo, useState } from 'react';
|
|
import { useMutation } from '@tanstack/react-query';
|
|
import { toast } from 'sonner';
|
|
import { Icons } from '@/components/icons';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle
|
|
} from '@/components/ui/dialog';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue
|
|
} from '@/components/ui/select';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
import {
|
|
shareCustomerContactMutation,
|
|
unshareCustomerContactMutation
|
|
} from '../api/mutations';
|
|
import type { CustomerContactRecord, CustomerReferenceData } from '../api/types';
|
|
import { formatDateTime } from '@/lib/format';
|
|
|
|
export function ContactShareSheet({
|
|
customerId,
|
|
contact,
|
|
referenceData,
|
|
open,
|
|
onOpenChange,
|
|
canManage
|
|
}: {
|
|
customerId: string;
|
|
contact: CustomerContactRecord | null;
|
|
referenceData: CustomerReferenceData;
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
canManage: boolean;
|
|
}) {
|
|
const [sharedToUserId, setSharedToUserId] = useState('');
|
|
const [remark, setRemark] = useState('');
|
|
const existingSharedIds = useMemo(
|
|
() => new Set(contact?.shares.map((item) => item.sharedToUserId) ?? []),
|
|
[contact]
|
|
);
|
|
const candidates = useMemo(
|
|
() => referenceData.crmUsers.filter((user) => !existingSharedIds.has(user.id)),
|
|
[existingSharedIds, referenceData.crmUsers]
|
|
);
|
|
|
|
const shareMutation = useMutation({
|
|
...shareCustomerContactMutation,
|
|
onSuccess: () => {
|
|
toast.success('แชร์ contact เรียบร้อย');
|
|
setSharedToUserId('');
|
|
setRemark('');
|
|
},
|
|
onError: (error) =>
|
|
toast.error(error instanceof Error ? error.message : 'ไม่สามารถแชร์ contact ได้')
|
|
});
|
|
const unshareMutation = useMutation({
|
|
...unshareCustomerContactMutation,
|
|
onSuccess: () => {
|
|
toast.success('ยกเลิกการแชร์เรียบร้อย');
|
|
},
|
|
onError: (error) =>
|
|
toast.error(error instanceof Error ? error.message : 'ไม่สามารถยกเลิกการแชร์ได้')
|
|
});
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>Shared With</DialogTitle>
|
|
<DialogDescription>จัดการผู้ใช้ที่เข้าถึง contact นี้ได้</DialogDescription>
|
|
</DialogHeader>
|
|
<div className='space-y-4'>
|
|
{!contact?.shares.length ? (
|
|
<div className='text-muted-foreground text-sm'>ยังไม่มีการแชร์ contact นี้</div>
|
|
) : (
|
|
<div className='space-y-2'>
|
|
{contact.shares.map((share) => (
|
|
<div
|
|
key={share.id}
|
|
className='flex items-start justify-between gap-3 rounded-lg border p-3'
|
|
>
|
|
<div className='space-y-1 text-sm'>
|
|
<div className='font-medium'>{share.sharedToName ?? share.sharedToUserId}</div>
|
|
<div className='text-muted-foreground text-xs'>
|
|
{formatDateTime(share.sharedAt)} โดย {share.sharedByName ?? share.sharedByUserId}
|
|
</div>
|
|
{share.remark ? <div className='text-xs'>{share.remark}</div> : null}
|
|
</div>
|
|
{canManage ? (
|
|
<Button
|
|
variant='outline'
|
|
size='sm'
|
|
onClick={() =>
|
|
unshareMutation.mutate({
|
|
customerId,
|
|
contactId: contact.id,
|
|
shareId: share.id
|
|
})
|
|
}
|
|
>
|
|
<Icons.trash className='mr-2 h-4 w-4' />
|
|
Remove
|
|
</Button>
|
|
) : null}
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
{canManage ? (
|
|
<div className='space-y-3 border-t pt-4'>
|
|
<Select value={sharedToUserId} onValueChange={setSharedToUserId}>
|
|
<SelectTrigger aria-label='Shared user'>
|
|
<SelectValue placeholder='Select user' />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{candidates.map((user) => (
|
|
<SelectItem key={user.id} value={user.id}>
|
|
{user.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<Textarea
|
|
value={remark}
|
|
onChange={(event) => setRemark(event.target.value)}
|
|
placeholder='Remark'
|
|
/>
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
<DialogFooter>
|
|
<Button variant='outline' onClick={() => onOpenChange(false)}>
|
|
ปิด
|
|
</Button>
|
|
{canManage ? (
|
|
<Button
|
|
isLoading={shareMutation.isPending}
|
|
disabled={!contact || !sharedToUserId}
|
|
onClick={() => {
|
|
if (!contact) {
|
|
return;
|
|
}
|
|
|
|
shareMutation.mutate({
|
|
customerId,
|
|
contactId: contact.id,
|
|
values: {
|
|
sharedToUserId,
|
|
remark
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
<Icons.check className='mr-2 h-4 w-4' />
|
|
Share
|
|
</Button>
|
|
) : null}
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|