Skip to content

Commit

Permalink
fix: event color | update and delete event
Browse files Browse the repository at this point in the history
  • Loading branch information
vishalkondle-dev committed Jul 7, 2024
1 parent 91d2e7d commit 39dd2ee
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 90 deletions.
147 changes: 122 additions & 25 deletions app/(private)/calendar/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,31 @@ import {
Modal,
Paper,
rem,
Select,
SelectProps,
Stack,
Text,
TextInput,
ThemeIcon,
} from '@mantine/core';
import { DatePicker, DatePickerInput, DateTimePicker, MonthPickerInput } from '@mantine/dates';
import { useForm } from '@mantine/form';
import { useDisclosure, useMediaQuery, useViewportSize } from '@mantine/hooks';
import { IconCalendar, IconChevronLeft, IconChevronRight } from '@tabler/icons-react';
import {
IconCalendar,
IconCheck,
IconChevronLeft,
IconChevronRight,
IconTagFilled,
IconTrash,
} from '@tabler/icons-react';
import dayjs from 'dayjs';
import { useState } from 'react';
import { apiCall, failure, success } from '@/lib/client_functions';
import { apiCall, failure, openModal, success } from '@/lib/client_functions';
import useFetchData from '@/hooks/useFetchData';
import { SelectedDay } from '@/components/Calendar';
import { COLORS } from '@/lib/constants';
import { EventDocument } from '@/models/Event';

const CalendarPage = () => {
const [date, setDate] = useState<Date>(dayjs().startOf('day').toDate());
Expand All @@ -42,10 +54,12 @@ const CalendarPage = () => {

const form = useForm({
initialValues: {
_id: '',
title: '',
from: dayjs(date).set('hour', 9).toDate(),
to: dayjs(date).set('hour', 10).toDate(),
isAllDay: false,
color: 'blue',
},
validate: {
title: (value) => (!value ? 'Title is required' : null),
Expand All @@ -54,7 +68,7 @@ const CalendarPage = () => {
},
});

const handleNewEvent = async (values: typeof form.values) => {
const handleEvent = async (values: typeof form.values) => {
if (form.values.isAllDay) {
values.from = dayjs(values.from).startOf('day').toDate();
values.to = dayjs(values.to).endOf('day').toDate();
Expand All @@ -64,8 +78,13 @@ const CalendarPage = () => {
return;
}
try {
await apiCall('/api/events', values, 'POST');
modalHandlers.close();
if (form.values._id) {
await apiCall('/api/events', values, 'PUT');
} else {
const { _id, ...rest } = values;
await apiCall('/api/events', rest, 'POST');
}
modalHandlers.toggle();
form.reset();
success('Event created successfully');
refetch();
Expand All @@ -74,11 +93,45 @@ const CalendarPage = () => {
}
};

const newEvent = () => {
modalHandlers.open();
form.setFieldValue('from', dayjs(date).set('hour', 9).toDate());
form.setFieldValue('to', dayjs(date).set('hour', 10).toDate());
form.setFieldValue('isAllDay', false);
const newEvent = (time?: number) => {
form.reset();
if (time !== undefined) {
form.setFieldValue('from', dayjs(date).set('hour', time).toDate());
form.setFieldValue(
'to',
dayjs(date)
.set('hour', time + 1)
.toDate()
);
} else {
form.setFieldValue('from', dayjs(date).set('hour', 9).toDate());
form.setFieldValue('to', dayjs(date).set('hour', 10).toDate());
}
modalHandlers.toggle();
};

const handleOpenEvent = (event: EventDocument) => {
form.reset();
form.setFieldValue('from', dayjs(event.from).set('hour', 9).toDate());
form.setFieldValue('to', dayjs(event.to).set('hour', 10).toDate());
form.setFieldValue('isAllDay', event.isAllDay);
form.setFieldValue('title', event.title);
form.setFieldValue('color', event.color);
form.setFieldValue('_id', String(event?._id));
modalHandlers.toggle();
};

const handleDeleteEvent = () => {
openModal('Do you want to delete this event?', async () => {
try {
await apiCall(`/api/events?_id=${form.values._id}`, null, 'DELETE');
success('Event deleted successfully');
refetch();
modalHandlers.toggle();
} catch (error) {
failure(String(error) || 'Something went wrong');
}
});
};

const renderDay = (day: Date) => (
Expand All @@ -92,8 +145,8 @@ const CalendarPage = () => {
.slice(0, 2)
.map((event) => (
<Badge
variant={dayjs(date).isSame(day, 'day') ? 'filled' : 'outline'}
color="blue"
variant="filled"
color={event?.color}
radius={0}
fullWidth
key={String(event._id)}
Expand Down Expand Up @@ -121,17 +174,28 @@ const CalendarPage = () => {
return (
<Indicator
size={18}
color="blue"
color="dark"
offset={-2}
disabled={!noOfEvents}
label={noOfEvents}
processing
zIndex={0}
>
<div>{day.getDate()}</div>
<Text fw={dayjs().isSame(day, 'day') ? 900 : 400}>{day.getDate()}</Text>
</Indicator>
);
};

const renderSelectOption: SelectProps['renderOption'] = ({ option, checked }) => (
<Group flex="1" gap="xs">
<ThemeIcon variant="transparent" color={option.value} size="xs">
<IconTagFilled />
</ThemeIcon>
{option.label}
{checked && <IconCheck style={{ marginInlineStart: 'auto' }} />}
</Group>
);

if (loading) return <></>;
return (
<AppShell
Expand Down Expand Up @@ -198,28 +262,51 @@ const CalendarPage = () => {
styles={{
month: { width: '100%' },
monthRow: { width: '100%' },
day: { width: '100%', height: rem((height * 0.54) / 5), padding: 0 },
day: { width: '100%', height: rem((height * 0.65) / 5), padding: 0 },
levelsGroup: { minWidth: '100%' },
calendarHeader: { visibility: 'hidden', display: 'none' },
}}
/>
</Paper>
<Modal opened={isModalOpened} onClose={modalHandlers.close} title="New Event">
<form onSubmit={form.onSubmit((values) => handleNewEvent(values))}>
<Modal
opened={isModalOpened}
onClose={() => {
modalHandlers.toggle();
form.reset();
}}
title={form.values?._id ? 'Edit Event' : 'New Event'}
>
<form onSubmit={form.onSubmit((values) => handleEvent(values))}>
<Stack gap="xs">
<Group wrap="nowrap" align="center">
<TextInput
type="text"
placeholder="Title"
w="100%"
{...form.getInputProps('title')}
/>
<TextInput
type="text"
placeholder="Title"
w="100%"
{...form.getInputProps('title')}
/>
<Group justify="space-between" wrap="nowrap" align="center">
<Checkbox
{...form.getInputProps('isAllDay', { type: 'checkbox' })}
style={{ whiteSpace: 'nowrap' }}
size="md"
label="All day"
/>
<Group wrap="nowrap" gap="xs">
<ThemeIcon variant="transparent" color={form.values.color} size="sm">
<IconTagFilled />
</ThemeIcon>
<Select
placeholder="Select color"
data={COLORS}
renderOption={renderSelectOption}
styles={{
input: { textTransform: 'capitalize' },
option: { textTransform: 'capitalize' },
}}
{...form.getInputProps('color')}
allowDeselect={false}
/>
</Group>
</Group>
{form.values.isAllDay ? (
<Group wrap="nowrap">
Expand Down Expand Up @@ -256,7 +343,16 @@ const CalendarPage = () => {
/>
</Group>
)}
<Button type="submit">Submit</Button>
<Group wrap="nowrap">
<Button fullWidth type="submit">
Submit
</Button>
{form.values?._id && (
<ActionIcon size="lg" color="red">
<IconTrash onClick={handleDeleteEvent} />
</ActionIcon>
)}
</Group>
</Stack>
</form>
</Modal>
Expand All @@ -268,6 +364,7 @@ const CalendarPage = () => {
setDate={setDate}
newEvent={newEvent}
events={events}
handleOpenEvent={handleOpenEvent}
/>
</AppShell.Aside>
</AppShell>
Expand Down
54 changes: 30 additions & 24 deletions components/Calendar/Event.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Button } from '@mantine/core';
import { IconClock } from '@tabler/icons-react';
import { Button, Tooltip } from '@mantine/core';
import React from 'react';
import { EventDocument } from '@/models/Event';

Expand All @@ -8,28 +7,35 @@ interface Props {
height: number;
maxHeight: number;
title: string;
handleOpenEvent: (event: EventDocument) => void;
}

export const Event = ({ event, height, maxHeight, title }: Props) => (
<Button
key={String(event._id)}
variant="light"
radius={0}
style={{
// display: 'flex',
position: 'relative',
cursor: 'pointer',
zIndex: 1,
whiteSpace: 'pre-wrap',
}}
fullWidth
onClick={() => {}}
title={title}
leftSection={<IconClock />}
mih={15}
h={height}
mah={maxHeight}
>
{event?.title}
</Button>
export const Event = ({ event, height, maxHeight, title, handleOpenEvent }: Props) => (
<Tooltip key={String(event._id)} label={title}>
<Button
variant="filled"
bd="0.2px solid white"
radius={0}
style={{
display: 'flex',
position: 'relative',
cursor: 'pointer',
zIndex: 1,
whiteSpace: 'pre-wrap',
}}
fullWidth
onClick={(e) => {
e.stopPropagation();
handleOpenEvent(event);
}}
mih={15}
h={height}
mah={maxHeight}
color={event?.color}
w="fit-content"
maw={200}
>
{event?.title}
</Button>
</Tooltip>
);
Loading

0 comments on commit 39dd2ee

Please sign in to comment.