This commit is contained in:
parent
d109d50120
commit
9244eaec26
@ -1,7 +1,7 @@
|
||||
import { Container } from '@/components/layout';
|
||||
import { PageHeader } from '@/components/navigation';
|
||||
import { ContactDataCard, PersonCard, ProfileOrdersList } from '@/components/profile';
|
||||
import { QuickAppointment } from '@/components/profile/quick-appointment';
|
||||
import { ProfileButtons } from '@/components/profile/profile-buttons';
|
||||
import { ReadonlyServicesList } from '@/components/profile/services';
|
||||
|
||||
// Тип параметров страницы
|
||||
@ -16,10 +16,11 @@ export default async function ProfilePage(props: Readonly<Props>) {
|
||||
<PageHeader title="Профиль контакта" />
|
||||
<Container className="px-0">
|
||||
<PersonCard telegramId={contactTelegramId} />
|
||||
<QuickAppointment telegramId={contactTelegramId} />
|
||||
<ContactDataCard telegramId={contactTelegramId} />
|
||||
<ReadonlyServicesList telegramId={contactTelegramId} />
|
||||
<ProfileOrdersList telegramId={contactTelegramId} />
|
||||
<div className="pb-24" />
|
||||
<ProfileButtons telegramId={contactTelegramId} />
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
|
||||
94
apps/web/components/profile/profile-buttons.tsx
Normal file
94
apps/web/components/profile/profile-buttons.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
'use client';
|
||||
|
||||
import FloatingActionPanel from '@/components/shared/action-panel';
|
||||
import { useCustomerQuery } from '@/hooks/api/customers';
|
||||
import { usePushWithData } from '@/hooks/url';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from '@repo/ui/components/ui/drawer';
|
||||
import { useState } from 'react';
|
||||
|
||||
type QuickAppointmentProps = {
|
||||
readonly telegramId: number;
|
||||
};
|
||||
|
||||
export function ProfileButtons({ telegramId }: Readonly<QuickAppointmentProps>) {
|
||||
const [isPanelOpen, setIsPanelOpen] = useState(false);
|
||||
const push = usePushWithData();
|
||||
|
||||
const { data: { customer: profile } = {} } = useCustomerQuery({ telegramId });
|
||||
const { data: { customer: currentUser } = {} } = useCustomerQuery();
|
||||
|
||||
const handleBookAsClient = () => {
|
||||
push('/orders/add', {
|
||||
client: currentUser,
|
||||
slot: { master: profile },
|
||||
});
|
||||
};
|
||||
|
||||
const handleBookAsMaster = () => {
|
||||
push('/orders/add', {
|
||||
client: profile,
|
||||
slot: { master: currentUser },
|
||||
});
|
||||
};
|
||||
|
||||
if (!telegramId) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<FloatingActionPanel onQuickBook={() => setIsPanelOpen(true)} />
|
||||
<Drawer onOpenChange={setIsPanelOpen} open={isPanelOpen}>
|
||||
<DrawerTrigger asChild>
|
||||
<div />
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<div className="mx-auto w-full max-w-sm">
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>Быстрая запись</DrawerTitle>
|
||||
<DrawerDescription>Выберите действие</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<div className="p-4 pt-0">
|
||||
<div className="flex flex-col gap-3">
|
||||
<DrawerClose asChild>
|
||||
<Button
|
||||
className="w-full text-sm"
|
||||
disabled={!profile || !currentUser}
|
||||
onClick={handleBookAsClient}
|
||||
size="sm"
|
||||
>
|
||||
Записаться к мастеру {profile?.name}
|
||||
</Button>
|
||||
</DrawerClose>
|
||||
<DrawerClose asChild>
|
||||
<Button
|
||||
className="w-full text-sm"
|
||||
disabled={!profile || !currentUser}
|
||||
onClick={handleBookAsMaster}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
>
|
||||
Записать клиента к себе
|
||||
</Button>
|
||||
</DrawerClose>
|
||||
</div>
|
||||
</div>
|
||||
<DrawerFooter>
|
||||
<DrawerClose asChild>
|
||||
<Button variant="outline">Отмена</Button>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import { useCustomerQuery } from '@/hooks/api/customers';
|
||||
import { usePushWithData } from '@/hooks/url';
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from '@repo/ui/components/ui/drawer';
|
||||
|
||||
type QuickAppointmentProps = {
|
||||
readonly telegramId: number;
|
||||
};
|
||||
|
||||
export function QuickAppointment({ telegramId }: Readonly<QuickAppointmentProps>) {
|
||||
const push = usePushWithData();
|
||||
|
||||
const { data: { customer: profile } = {} } = useCustomerQuery({ telegramId });
|
||||
const { data: { customer: currentUser } = {} } = useCustomerQuery();
|
||||
|
||||
const handleBookAsClient = () => {
|
||||
push('/orders/add', {
|
||||
client: currentUser,
|
||||
slot: { master: profile },
|
||||
});
|
||||
};
|
||||
|
||||
const handleBookAsMaster = () => {
|
||||
push('/orders/add', {
|
||||
client: profile,
|
||||
slot: { master: currentUser },
|
||||
});
|
||||
};
|
||||
|
||||
if (!telegramId) return null;
|
||||
|
||||
return (
|
||||
<Drawer>
|
||||
<DrawerTrigger asChild>
|
||||
<div className="mt-4 flex justify-center">
|
||||
<Button className="px-6 py-2 text-sm font-semibold" size="sm">
|
||||
Быстрая запись
|
||||
</Button>
|
||||
</div>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<div className="mx-auto w-full max-w-sm">
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>Быстрая запись</DrawerTitle>
|
||||
<DrawerDescription>Выберите действие</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<div className="p-4 pt-0">
|
||||
<div className="flex flex-col gap-3">
|
||||
<DrawerClose asChild>
|
||||
<Button
|
||||
className="w-full text-sm"
|
||||
disabled={!handleBookAsClient}
|
||||
onClick={handleBookAsClient}
|
||||
size="sm"
|
||||
>
|
||||
Записаться к мастеру {profile?.name}
|
||||
</Button>
|
||||
</DrawerClose>
|
||||
<DrawerClose asChild>
|
||||
<Button
|
||||
className="w-full text-sm"
|
||||
disabled={!handleBookAsMaster}
|
||||
onClick={handleBookAsMaster}
|
||||
size="sm"
|
||||
variant="secondary"
|
||||
>
|
||||
Записать клиента к себе
|
||||
</Button>
|
||||
</DrawerClose>
|
||||
</div>
|
||||
</div>
|
||||
<DrawerFooter>
|
||||
<DrawerClose asChild>
|
||||
<Button variant="outline">Отмена</Button>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</div>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { Button } from '@repo/ui/components/ui/button';
|
||||
import { Card } from '@repo/ui/components/ui/card';
|
||||
import { Ban, Check, Lock, RotateCcw, Save, Trash2, Undo, Unlock } from 'lucide-react';
|
||||
import { Ban, Check, Lock, Plus, RotateCcw, Save, Trash2, Undo, Unlock } from 'lucide-react';
|
||||
|
||||
type FloatingActionPanelProps = {
|
||||
readonly isLoading?: boolean;
|
||||
@ -11,6 +11,7 @@ type FloatingActionPanelProps = {
|
||||
readonly onComplete?: () => void;
|
||||
readonly onConfirm?: () => void;
|
||||
readonly onDelete?: () => void;
|
||||
readonly onQuickBook?: () => void;
|
||||
readonly onRepeat?: () => void;
|
||||
readonly onReturn?: () => void;
|
||||
readonly onSave?: () => void;
|
||||
@ -24,6 +25,7 @@ export default function FloatingActionPanel({
|
||||
onComplete,
|
||||
onConfirm,
|
||||
onDelete,
|
||||
onQuickBook,
|
||||
onRepeat,
|
||||
onReturn,
|
||||
onSave,
|
||||
@ -36,6 +38,7 @@ export default function FloatingActionPanel({
|
||||
!onDelete &&
|
||||
!onComplete &&
|
||||
!onRepeat &&
|
||||
!onQuickBook &&
|
||||
!onToggle &&
|
||||
!onReturn &&
|
||||
!onSave
|
||||
@ -45,6 +48,18 @@ export default function FloatingActionPanel({
|
||||
return (
|
||||
<Card className="fixed inset-x-4 bottom-4 z-50 rounded-3xl border-0 bg-background/95 p-4 shadow-2xl backdrop-blur-sm dark:bg-primary/5 md:bottom-6 md:left-auto md:right-6 md:p-6">
|
||||
<div className="flex flex-col items-center gap-2 sm:flex-row sm:gap-4">
|
||||
{/* Кнопка записать */}
|
||||
{onQuickBook && (
|
||||
<Button
|
||||
className="w-full rounded-2xl bg-gradient-to-r from-purple-600 to-blue-600 text-sm text-white transition-all duration-200 hover:bg-primary/90 dark:from-purple-700 dark:to-blue-700 sm:w-auto"
|
||||
disabled={isLoading}
|
||||
onClick={onQuickBook}
|
||||
size="sm"
|
||||
>
|
||||
<Plus className="mr-2 size-4" />
|
||||
<span>Быстрая запись</span>
|
||||
</Button>
|
||||
)}
|
||||
{/* Кнопка закрыть/открыть */}
|
||||
{onToggle && (
|
||||
<Button
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user