Skip to content

Instantly share code, notes, and snippets.

@alanfoandrade
Created June 5, 2023 22:54
Show Gist options
  • Save alanfoandrade/13743725b4f6e3057e045ef61181223a to your computer and use it in GitHub Desktop.
Save alanfoandrade/13743725b4f6e3057e045ef61181223a to your computer and use it in GitHub Desktop.
'use client';
import { Calendar } from '@/components/Calendar';
import { Card } from '@/components/Card';
import { useParams } from 'next/navigation';
import { useState } from 'react';
import { twMerge } from 'tailwind-merge';
import { TimePicker } from './components/TimePicker';
export function CalendarStep() {
const { username } = useParams();
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
const isDateSelected = !!selectedDate;
let timePickerOpenVariant = '';
switch (isDateSelected) {
case true:
timePickerOpenVariant = 'grid-cols-[1fr_280px] max-md:grid-cols-1';
break;
case false:
timePickerOpenVariant = 'w-[540px] grid-cols-1';
break;
}
return (
<Card
className={twMerge(
'relative mx-auto mb-0 mt-6 grid p-0 ',
timePickerOpenVariant,
)}
>
<Calendar onDateSelected={setSelectedDate} selectedDate={selectedDate} />
{!!isDateSelected && (
<TimePicker selectedDate={selectedDate} username={username} />
)}
</Card>
);
}
'use client';
import { Text } from '@/components/Text';
import dayjs from 'dayjs';
import { useParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import { TimePickerItem } from './components/TimePickerItem';
interface LoadAvailabilityProps {
date: string; // YYYY-MM-DD
username: string;
}
interface Availability {
availableTimes: number[];
possibleTimes: number[];
}
interface TimePickerProps {
selectedDate: Date;
username: string;
}
export function TimePicker({ selectedDate, username }: TimePickerProps) {
const [availability, setAvailability] = useState<Availability | null>(null);
const weekDay = selectedDate ? dayjs(selectedDate).format('dddd') : null;
const monthDay = selectedDate
? dayjs(selectedDate).format(`DD[ de ]MMMM`)
: null;
useEffect(() => {
async function loadAvailability({ date, username }: LoadAvailabilityProps) {
try {
const response = await fetch(
`/api/users/${username}/availability?date=${date}`,
);
const availabilityData: Availability = await response.json();
setAvailability(availabilityData);
} catch (err) {
// eslint-disable-next-line no-console
console.log(err);
}
}
loadAvailability({
date: dayjs(selectedDate).format('YYYY-MM-DD'),
username,
});
}, [selectedDate, username]);
return (
<div className="absolute bottom-0 right-0 top-0 w-[280px] overflow-y-scroll border-l border-l-gray-600 px-6 pt-6">
<Text className="font-medium">
{weekDay}{' '}
<Text as="span" className="text-gray-200">
{monthDay}
</Text>
</Text>
<div className="mt-3 grid grid-cols-1 gap-2 max-md:grid-cols-2">
{availability?.possibleTimes.map((hour) => (
<TimePickerItem
key={hour}
disabled={!availability.availableTimes.includes(hour)}
>
{String(hour).padStart(2, '0')}:00h
</TimePickerItem>
))}
</div>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment