add basic slot page

This commit is contained in:
vchikalkin 2025-02-11 14:34:28 +03:00
parent 209114a394
commit 1d1a90b6d3
9 changed files with 79 additions and 18 deletions

View File

@ -16,10 +16,10 @@ export async function addSlot(input: AddSlotInput) {
return api.createSlot({
...input,
date: formatDate(input.date),
date: formatDate(input.date).db(),
master: customer?.documentId,
time_end: formatTime(input.time_end),
time_start: formatTime(input.time_start),
time_end: formatTime(input.time_end).db(),
time_start: formatTime(input.time_start).db(),
});
}

View File

@ -0,0 +1,25 @@
import { getSlot } from '@/actions/slots';
import { PageHeader } from '@/components/navigation';
import { TimeCard } from '@/components/schedule';
import { dehydrate, HydrationBoundary, QueryClient } from '@tanstack/react-query';
type Props = { params: Promise<{ documentId: string }> };
export default async function ProfilePage(props: Readonly<Props>) {
const parameters = await props.params;
const { documentId } = parameters;
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
queryFn: () => getSlot({ documentId }),
queryKey: ['schedule', 'slots', 'get', documentId],
});
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<PageHeader title={undefined} />
<TimeCard {...parameters} />
</HydrationBoundary>
);
}

View File

@ -1,2 +1,3 @@
export * from './calendar';
export * from './time-card';
export * from './time-slots';

View File

@ -0,0 +1,22 @@
'use client';
import { type SlotProps } from './types';
import { useSlotQuery } from '@/hooks/slots';
import { formatDate, formatTime } from '@/utils/date';
export function TimeCard({ documentId }: Readonly<SlotProps>) {
const { data } = useSlotQuery({ documentId });
if (!data?.slot) return null;
return (
<div className="flex flex-col p-4">
<span className="mb-2 tracking-wide">{formatDate(data?.slot?.date).user()}</span>
<span className="mt-2 text-3xl font-bold tracking-wide">
{formatTime(data?.slot?.time_start).user()}
</span>
<span className="mt-2 text-3xl font-bold tracking-wide">
{formatTime(data?.slot?.time_end).user()}
</span>
</div>
);
}

View File

@ -1,6 +1,6 @@
'use client';
import { type SlotProps } from '../../types';
import { ContextProvider } from '../context';
import { type SlotProps } from '../types';
import { ReadonlyTimeRange } from './time-pair';
import { useSlotQuery } from '@/hooks/slots';
import { withContext } from '@/utils/context';

View File

@ -1,9 +1,10 @@
'use client';
import { type Slot } from '../../types';
import { Context, type ContextType } from '../context';
import { type Slot } from '../types';
import { useSlotAdd } from '@/hooks/slots';
import { parseTime } from '@/utils/date';
import { formatTime } from '@/utils/date';
import { Input } from '@repo/ui/components/ui/input';
import { cn } from '@repo/ui/lib/utils';
import { use } from 'react';
type TimePairProps = Pick<ContextType, 'endTime' | 'setEndTime' | 'setStartTime' | 'startTime'> & {
@ -25,12 +26,16 @@ export function AddTimePair() {
);
}
export function ReadonlyTimeRange({ time_end, time_start }: Readonly<Slot>) {
export function ReadonlyTimeRange({
className,
time_end,
time_start,
}: Readonly<Slot> & { readonly className?: string }) {
return (
<div className="flex flex-row items-center gap-2 text-lg font-bold">
<span>{parseTime(time_start)}</span>
<div className={cn('flex flex-row items-center gap-2 text-lg font-bold', className)}>
<span className="tracking-wider">{formatTime(time_start).user()}</span>
{' - '}
<span>{parseTime(time_end)}</span>
<span className="tracking-wider">{formatTime(time_end).user()}</span>
</div>
);
}

View File

@ -18,7 +18,7 @@ export const useSlots = () => {
getSlots({
filters: {
date: {
eq: formatDate(selectedDate),
eq: formatDate(selectedDate).db(),
},
},
}),

View File

@ -1,4 +1,6 @@
/* eslint-disable import/no-unassigned-import */
import dayjs from 'dayjs';
import 'dayjs/locale/ru';
export function combineDateTime(date: Date, time: string) {
const [hours = '00', minutes = '00'] = time.split(':');
@ -12,16 +14,22 @@ export function combineDateTime(date: Date, time: string) {
);
}
export function formatDate(date: Date) {
return dayjs(date).format('YYYY-MM-DD');
export function formatDate(date: Date | string) {
return {
db: () => dayjs(date).format('YYYY-MM-DD'),
user: () => {
const lang = document.documentElement.lang || 'ru';
dayjs.locale(lang);
return dayjs(date).format('D MMMM YYYY');
},
};
}
export function formatTime(time: string) {
return `${time}:00`;
}
export function parseTime(time: string) {
const [hours = '00', minutes = '00'] = time.split(':');
return `${hours}:${minutes}`;
return {
db: () => `${hours}:${minutes}:00`,
user: () => `${hours}:${minutes}`,
};
}