Compare commits
7 Commits
feat/impro
...
b48dd4f15d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b48dd4f15d | ||
|
|
fee0be7e1f | ||
|
|
721ebaa775 | ||
| 2ccff7dcaa | |||
|
|
4b1b06f00f | ||
|
|
af687fe2d8 | ||
| 9875f22d5a |
@@ -1,20 +1,6 @@
|
|||||||
import { beforeEach, expect, mock, test } from 'bun:test';
|
import { beforeEach, expect, test } from 'bun:test';
|
||||||
|
|
||||||
import { createPrismaMock } from 'bun-mock-prisma';
|
import { prismaMock, uuidV7Mock } from '../support/prisma.mock';
|
||||||
|
|
||||||
import type { PrismaClient } from '@/generated/prisma/client';
|
|
||||||
import type { PrismaClientMock } from 'bun-mock-prisma';
|
|
||||||
|
|
||||||
const prismaMock = createPrismaMock<PrismaClient>() as PrismaClientMock<PrismaClient>;
|
|
||||||
|
|
||||||
mock.module('@/lib/prisma', () => ({
|
|
||||||
__esModule: true,
|
|
||||||
db: {
|
|
||||||
sport: prismaMock.sport,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { uuidV7Mock } = await import('../support/prisma.mock');
|
|
||||||
|
|
||||||
const { createSport, getSportById, listSports, updateSport } = await import(
|
const { createSport, getSportById, listSports, updateSport } = await import(
|
||||||
'@/modules/sport/services/sport.service'
|
'@/modules/sport/services/sport.service'
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export const dbMock = {
|
|||||||
complex: prismaMock.complex,
|
complex: prismaMock.complex,
|
||||||
user: prismaMock.user,
|
user: prismaMock.user,
|
||||||
complexInvitation: prismaMock.complexInvitation,
|
complexInvitation: prismaMock.complexInvitation,
|
||||||
|
sport: prismaMock.sport,
|
||||||
$transaction: transactionMock,
|
$transaction: transactionMock,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -166,17 +166,21 @@ export function BookingCreateDialog() {
|
|||||||
onOpenChange={(open) => !open && closeCreateBooking()}
|
onOpenChange={(open) => !open && closeCreateBooking()}
|
||||||
>
|
>
|
||||||
<ResponsiveDialogContent
|
<ResponsiveDialogContent
|
||||||
className="data-[variant=dialog]:max-w-lg"
|
className="group/create-booking data-[variant=dialog]:max-w-lg data-[variant=drawer]:!h-[92svh] data-[variant=drawer]:!max-h-[92svh] data-[variant=drawer]:overflow-hidden data-[variant=drawer]:px-0 data-[variant=drawer]:pb-0"
|
||||||
onOpenAutoFocus={(event) => event.preventDefault()}
|
onOpenAutoFocus={(event) => event.preventDefault()}
|
||||||
>
|
>
|
||||||
<ResponsiveDialogHeader>
|
<ResponsiveDialogHeader className="group-data-[variant=drawer]/create-booking:shrink-0 group-data-[variant=drawer]/create-booking:px-4 group-data-[variant=drawer]/create-booking:pb-3">
|
||||||
<ResponsiveDialogTitle>Nueva reserva</ResponsiveDialogTitle>
|
<ResponsiveDialogTitle>Nueva reserva</ResponsiveDialogTitle>
|
||||||
<ResponsiveDialogDescription>
|
<ResponsiveDialogDescription>
|
||||||
Crea un turno para atención telefónica o mostrador.
|
Crea un turno para atención telefónica o mostrador.
|
||||||
</ResponsiveDialogDescription>
|
</ResponsiveDialogDescription>
|
||||||
</ResponsiveDialogHeader>
|
</ResponsiveDialogHeader>
|
||||||
|
|
||||||
<form id="booking-create-form" className="grid gap-4" onSubmit={handleSubmit(onSubmit)}>
|
<form
|
||||||
|
id="booking-create-form"
|
||||||
|
className="grid gap-4 group-data-[variant=drawer]/create-booking:min-h-0 group-data-[variant=drawer]/create-booking:flex-1 group-data-[variant=drawer]/create-booking:overflow-y-auto group-data-[variant=drawer]/create-booking:px-4 group-data-[variant=drawer]/create-booking:pb-4"
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
>
|
||||||
<div className="grid gap-3 md:grid-cols-2">
|
<div className="grid gap-3 md:grid-cols-2">
|
||||||
<Field>
|
<Field>
|
||||||
<FieldLabel>Fecha</FieldLabel>
|
<FieldLabel>Fecha</FieldLabel>
|
||||||
@@ -294,7 +298,7 @@ export function BookingCreateDialog() {
|
|||||||
{createBookingError && <p className="text-sm text-destructive">{createBookingError}</p>}
|
{createBookingError && <p className="text-sm text-destructive">{createBookingError}</p>}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ResponsiveDialogFooter>
|
<ResponsiveDialogFooter className="group-data-[variant=drawer]/create-booking:shrink-0 group-data-[variant=drawer]/create-booking:border-t group-data-[variant=drawer]/create-booking:border-border/70 group-data-[variant=drawer]/create-booking:bg-popover/95 group-data-[variant=drawer]/create-booking:px-4 group-data-[variant=drawer]/create-booking:pt-3 group-data-[variant=drawer]/create-booking:pb-[calc(12px+env(safe-area-inset-bottom))]">
|
||||||
<ResponsiveDialogClose asChild>
|
<ResponsiveDialogClose asChild>
|
||||||
<Button variant="outline">Cancelar</Button>
|
<Button variant="outline">Cancelar</Button>
|
||||||
</ResponsiveDialogClose>
|
</ResponsiveDialogClose>
|
||||||
|
|||||||
@@ -352,18 +352,33 @@ function MobilePanelHeader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function MobileFilters() {
|
function MobileFilters() {
|
||||||
const { selectedDate, setSelectedDate } = useBooking();
|
const { selectedDate, setSelectedDate, moveSelectedDate } = useBooking();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="grid grid-cols-[52px_1fr_52px] gap-3">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
className="h-12 rounded-lg"
|
||||||
|
onClick={() => moveSelectedDate(-1)}
|
||||||
|
>
|
||||||
|
<ChevronLeft className="size-5" />
|
||||||
|
</Button>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
value={fromIsoDateLocal(selectedDate)}
|
value={fromIsoDateLocal(selectedDate)}
|
||||||
onChange={(date) =>
|
onChange={(date) =>
|
||||||
setSelectedDate(date ? toIsoDateLocal(date) : toIsoDateLocal(new Date()))
|
setSelectedDate(date ? toIsoDateLocal(date) : toIsoDateLocal(new Date()))
|
||||||
}
|
}
|
||||||
className="h-12 w-full justify-center rounded-lg border-border/70 bg-card/75 px-4 text-sm font-medium"
|
className="h-12 rounded-lg border-border/70 bg-card/75 text-sm"
|
||||||
placeholder="Fecha"
|
|
||||||
/>
|
/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
className="h-12 rounded-lg"
|
||||||
|
onClick={() => moveSelectedDate(1)}
|
||||||
|
>
|
||||||
|
<ChevronRight className="size-5" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,13 +59,14 @@ export function ShareWhatsappButton({ confirmation }: ShareWhatsappButtonProps)
|
|||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="h-12 w-full rounded-xl border-slate-200 bg-white text-sm font-semibold text-slate-900 hover:bg-slate-50 sm:text-base"
|
className="h-12 w-full overflow-hidden rounded-xl border-slate-200 bg-white px-0 text-sm font-semibold text-slate-900 hover:bg-slate-50 sm:px-4 sm:text-base"
|
||||||
asChild
|
asChild
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={whatsappUrl}
|
href={whatsappUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
aria-label="Compartir por WhatsApp"
|
||||||
title="Compartir por WhatsApp"
|
title="Compartir por WhatsApp"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -76,7 +77,7 @@ export function ShareWhatsappButton({ confirmation }: ShareWhatsappButtonProps)
|
|||||||
>
|
>
|
||||||
<path d={siWhatsapp.path} fill="currentColor" />
|
<path d={siWhatsapp.path} fill="currentColor" />
|
||||||
</svg>
|
</svg>
|
||||||
<span className="sm:hidden">Compartir por WhatsApp</span>
|
<span className="hidden sm:inline">Compartir por WhatsApp</span>
|
||||||
</a>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import PlayzerIcon from '@/assets/playzer-favicon-512-transparent.png';
|
import PlayzerLogo from '@/assets/playzer-logo-transparent.svg';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import {
|
import {
|
||||||
@@ -162,9 +162,8 @@ export function PublicBookingConfirmationPage({
|
|||||||
{displayData.complexName}
|
{displayData.complexName}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-slate-600">
|
<div className="flex items-center">
|
||||||
<img src={PlayzerIcon} alt="Playzer" className="size-8" />
|
<img src={PlayzerLogo} alt="Playzer" className="h-9 w-auto sm:h-10" />
|
||||||
<span className="text-lg font-bold tracking-tight">Playzer</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -221,7 +220,7 @@ export function PublicBookingConfirmationPage({
|
|||||||
cancelación.
|
cancelación.
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-3 gap-2 sm:gap-3">
|
<div className="grid grid-cols-[48px_minmax(0,1fr)_minmax(0,1fr)] gap-2 sm:grid-cols-3 sm:gap-3">
|
||||||
<ShareWhatsappButton confirmation={confirmationQuery.data!} />
|
<ShareWhatsappButton confirmation={confirmationQuery.data!} />
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
Reference in New Issue
Block a user