This commit is contained in:
vchikalkin 2025-10-07 11:24:00 +03:00
parent d109d50120
commit 9244eaec26
4 changed files with 113 additions and 95 deletions

View File

@ -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>
</>
);

View 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>
</>
);
}

View File

@ -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>
);
}

View File

@ -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