Skip to content

Commit

Permalink
use js dates for time picker
Browse files Browse the repository at this point in the history
  • Loading branch information
fmtabbara committed Dec 6, 2024
1 parent 66fafd0 commit 93609e7
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 130 deletions.
2 changes: 0 additions & 2 deletions suncityla/app/booking/actions/onSubmitAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const onSubmitAction = async (prvState: FormState, data: FormData): Promise<Form
state: parsed.data.state,
postalCode: parsed.data['postal-code'],
bookingDate: parsed.data.bookingDate,
bookingTime: parsed.data.bookingTime,
},
});
} else {
Expand All @@ -51,7 +50,6 @@ const onSubmitAction = async (prvState: FormState, data: FormData): Promise<Form
state: parsed.data.state,
postalCode: parsed.data['postal-code'],
bookingDate: parsed.data.bookingDate,
bookingTime: parsed.data.bookingTime,
},
});
}
Expand Down
9 changes: 6 additions & 3 deletions suncityla/app/booking/components/BookingCard/BookingEntry.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { format } from 'date-fns';
import { add, format } from 'date-fns';
import { Booking } from '@prisma/client';
import {
Table,
Expand Down Expand Up @@ -40,8 +40,11 @@ const BookingEntry = ({ booking }: { booking: Booking }) => {
<TableRow>
<TableCell>{booking.firstname}</TableCell>
<TableCell>{booking.lastname}</TableCell>
<TableCell>{format(new Date(booking.bookingDate), 'yyyy-MM-dd')}</TableCell>
<TableCell>{booking.bookingTime}</TableCell>
<TableCell>{format(new Date(booking.bookingDate), 'EE dd/MM/yy')}</TableCell>
<TableCell>{`${format(new Date(booking.bookingDate), 'h:mm a')} - ${format(
add(new Date(booking.bookingDate), { hours: 1 }),
'h:mm a',
)}`}</TableCell>
<TableCell>{booking.streetAddress}</TableCell>
<TableCell>{booking.postalCode}</TableCell>
<TableCell>{booking.state}</TableCell>
Expand Down
44 changes: 34 additions & 10 deletions suncityla/app/booking/components/BookingForm/BookingForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useActionState, useRef, startTransition, useEffect } from 'react';
import { useActionState, useRef, startTransition, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
Expand All @@ -14,7 +14,8 @@ import onSubmitAction from '@/app/booking/actions/onSubmitAction';
import { bookingFormSchema } from '../../schemas/newBookingForm';
import { Booking } from '@prisma/client';
import TimeSelect from '../TimeSelect/TimeSelect';
import availableTimes from '../TimeSelect/times';
import createAvailableTimes from '../TimeSelect/times';
import { set } from 'date-fns';

export type BookingFormData = z.infer<typeof bookingFormSchema>;

Expand All @@ -34,16 +35,21 @@ export default function BookingForm({ booking }: { booking?: Booking | null }) {
'street-address': booking?.streetAddress ?? '',
'postal-code': booking?.postalCode ?? '',
state: 'LA',
bookingDate: booking?.bookingDate.toISOString() ?? new Date().toISOString(),
bookingTime: booking?.bookingTime || availableTimes[0].time,
bookingDate: booking?.bookingDate.toISOString() || '',
...(state.fields ?? {}),
},
});

// Time Stamp
const [time, setSelectedTime] = useState<number | undefined>(booking?.bookingDate.getTime());
const watchDate = form.watch('bookingDate');
const availableTimes = createAvailableTimes(new Date(watchDate));

const formRef = useRef<HTMLFormElement>(null);

const handleClearForm = () => {
form.reset();
setSelectedTime(undefined);
};

useEffect(() => {
Expand All @@ -52,6 +58,16 @@ export default function BookingForm({ booking }: { booking?: Booking | null }) {
}
}, [state.bookingRef, isPending, router, state.message]);

useEffect(() => {
if (time) {
const newDateWithTime = new Date(watchDate);
const hours = new Date(time).getHours();
newDateWithTime.setHours(hours);
form.setValue('bookingDate', newDateWithTime.toISOString());
return;
}
}, [watchDate, time, form]);

return (
<div className="w-96 border p-4 bg-slate-100 rounded-md">
<LoadingModal show={isPending} />
Expand All @@ -78,13 +94,21 @@ export default function BookingForm({ booking }: { booking?: Booking | null }) {
<BookingFormField placeholder="Address" name="street-address" />
<BookingFormField placeholder="Postcode" name="postal-code" />
<BookingFormField placeholder="State" name="state" disabled />
<DateTimePickerForm />
<TimeSelect />
<DateTimePickerForm onChange={() => setSelectedTime(undefined)} />
{watchDate && (
<TimeSelect
selectedTime={time}
availableTimes={availableTimes}
onTimeSelect={setSelectedTime}
/>
)}
<div className="flex gap-1 justify-end mt-4">
<Button onClick={handleClearForm} variant="outline">
Clear
</Button>
<Button type="submit" disabled={form.formState.isSubmitting}>
{!booking?.id && (
<Button onClick={handleClearForm} variant="outline">
Clear
</Button>
)}
<Button type="submit" disabled={form.formState.isSubmitting || !time}>
Submit
</Button>
</div>
Expand Down
43 changes: 15 additions & 28 deletions suncityla/app/booking/components/TimeDatePicker/TimeDatePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
"use client";
'use client';

import { useState } from "react";
import { format } from "date-fns";
import { Calendar as CalendarIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { useState } from 'react';
import { format } from 'date-fns';
import { Calendar as CalendarIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormMessage,
} from "@/components/ui/form";
} from '@/components/ui/form';

export function DateTimePickerForm() {
export function DateTimePickerForm({ onChange }: { onChange: () => void }) {
const [open, setOpen] = useState(false);

return (
Expand All @@ -34,16 +30,12 @@ export function DateTimePickerForm() {
onClick={() => setOpen(true)}
variant="outline"
className={cn(
"w-full justify-start font-normal",
!field.value && "text-muted-foreground"
'w-full justify-start font-normal',
!field.value && 'text-muted-foreground',
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{field.value ? (
format(field.value, "PPP")
) : (
<span>Pick a date</span>
)}
{field.value ? format(field.value, 'PPP') : <span>Pick a date</span>}
</Button>
</PopoverTrigger>
</FormControl>
Expand All @@ -54,17 +46,12 @@ export function DateTimePickerForm() {
onSelect={(date) => {
field.onChange(date?.toISOString());
setOpen(false);
onChange();
}}
initialFocus
/>
</PopoverContent>
</Popover>
<input
type="hidden"
{...field}
name={field.name}
value={field.value}
/>
<input type="hidden" {...field} name={field.name} value={field.value} />
<FormDescription />
<FormMessage />
</FormItem>
Expand Down
63 changes: 39 additions & 24 deletions suncityla/app/booking/components/TimeSelect/TimeSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import * as React from 'react';

import {
Expand All @@ -9,34 +11,47 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import availableTimes from './times';
import { FormField, FormItem } from '@/components/ui/form';
import { format } from 'date-fns';

export function TimeSelect() {
export function TimeSelect({
availableTimes,
selectedTime,
onTimeSelect,
}: {
availableTimes: { from: number; to: number }[];
selectedTime?: number;
onTimeSelect: (time: number) => void;
}) {
return (
<FormField
name="bookingTime"
render={({ field }) => (
<FormItem>
<Select {...field} onValueChange={field.onChange}>
<SelectTrigger className="w-[180px] bg-white">
<SelectValue placeholder="Select a time" />
</SelectTrigger>
<div className="bg-white">
<SelectContent>
<SelectGroup>
<SelectLabel>Times</SelectLabel>
{availableTimes.map(({ time }) => (
<SelectItem key={time} value={time}>
{time}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</div>
</Select>
</FormItem>
)}
name=""
render={() => {
return (
<FormItem>
<Select
onValueChange={(time) => onTimeSelect(Number(time))}
value={selectedTime?.toString()}
>
<SelectTrigger className="w-[180px] bg-white">
<SelectValue placeholder="Select a time" />
</SelectTrigger>
<div className="bg-white">
<SelectContent>
<SelectGroup>
<SelectLabel>Times</SelectLabel>
{availableTimes.map(({ from, to }, i) => (
<SelectItem className="cursor-pointer" key={i} value={from.toString()}>
{format(from, 'h:mm a')} - {format(to, 'h:mm a')}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</div>
</Select>
</FormItem>
);
}}
/>
);
}
Expand Down
28 changes: 11 additions & 17 deletions suncityla/app/booking/components/TimeSelect/times.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
const availableTimes = [
{ time: '8:00 - 9:00 AM' },
{ time: '9:00 - 10:00 AM' },
{ time: '10:00 - 11:00 AM' },
{ time: '11:00 - 12:00 PM' },
{ time: '12:00 - 1:00 PM' },
{ time: '1:00 - 2:00 PM' },
{ time: '2:00 - 3:00 PM' },
{ time: '3:00 - 4:00 PM' },
{ time: '4:00 - 5:00 PM' },
{ time: '5:00 - 6:00 PM' },
{ time: '6:00 - 7:00 PM' },
{ time: '7:00 - 8:00 PM' },
{ time: '8:00 - 9:00 PM' },
{ time: '9:00 - 10:00 PM' },
];
const createAvailableTimes = (date: Date) => {
const availableTimes = [];
for (let i = 8; i < 20; i++) {
availableTimes.push({
from: date.setHours(i, 0, 0, 0),
to: date.setHours(i + 1, 0, 0, 0),
});
}
return availableTimes;
};

export default availableTimes;
export default createAvailableTimes;
1 change: 0 additions & 1 deletion suncityla/app/booking/schemas/newBookingForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,5 @@ export const bookingFormSchema = z.object({
message: 'Booking date must be in the future.',
},
),
bookingTime: z.string(),
bookingId: z.string().optional(),
});
Loading

0 comments on commit 93609e7

Please sign in to comment.