Skip to content

Commit

Permalink
advancing calender functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
RWEMAREMY committed Sep 11, 2024
1 parent c4ba4bf commit edb1a0f
Showing 1 changed file with 164 additions and 70 deletions.
234 changes: 164 additions & 70 deletions src/components/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import { ADD_EVENT, GET_EVENTS } from '../Mutations/event';
import moment from 'moment';
/* istanbul ignore next */

type Trainee = {
id: number;
name: string;
role: 'admin' | 'manager' | 'trainee';
};

const Calendar = () => {
useDocumentTitle('Calendar');
const [addEventModel, setAddEventModel] = useState(false);
Expand All @@ -27,6 +33,21 @@ const Calendar = () => {
const [data, setData] = useState<EventInput[]>([]);
const [getEvents] = useLazyQuery(GET_EVENTS);
const [createEvent] = useMutation(ADD_EVENT);
const [showTraineeDropdown, setShowTraineeDropdown] = useState(false);
const [trainees, setTrainees] = useState<Trainee[]>([
{ id: 1, name: 'John Doe', role: 'admin' },
{ id: 2, name: 'Jane Smith', role: 'manager' },
{ id: 3, name: 'Bob Johnson', role: 'trainee' },
{ id: 4, name: 'Alice Brown', role: 'trainee' },
{ id: 5, name: 'Charlie Green', role: 'manager' },
{ id: 6, name: 'Diana White', role: 'trainee' },
{ id: 7, name: 'Ethan Black', role: 'admin' },
{ id: 8, name: 'Fiona Blue', role: 'manager' },
{ id: 9, name: 'George Gray', role: 'trainee' },
{ id: 10, name: 'Hannah Purple', role: 'trainee' },
]);
const [selectedTrainees, setSelectedTrainees] = useState<number[]>([]);

useEffect(() => {
const fetchData = async () => {
/* istanbul ignore next */
Expand All @@ -52,26 +73,24 @@ const Calendar = () => {
};
fetchData();
}, []);

const { t } = useTranslation();
const renderEvent =
/* istanbul ignore next */

(e: EventContentArg) => (
/* istanbul ignore next */
<div
data-html={true}
data-tip={`<div>${e.event.title}<br> ${e.event.extendedProps.hostName} <br> ${e.event.extendedProps.timeToStart} - ${e.event.extendedProps.timeToFinish}</div> `}
className="bg-primary text-white max-w-full min-w-full overflow-auto text-xs md:text-sm"
>
<p className="px-3 py-1 ">{e.event.title}</p>
<p className="px-3 py-1 ">{e.event.extendedProps.hostName}</p>
<p className="px-3 py-1 ">
{e.event.extendedProps.timeToStart} -{' '}
{e.event.extendedProps.timeToFinish}
</p>
<ReactTooltip data-html={true} />
</div>
);
const renderEvent = (e: EventContentArg) => (
<div
data-html={true}
data-tip={`<div>${e.event.title}<br> ${e.event.extendedProps.hostName} <br> ${e.event.extendedProps.timeToStart} - ${e.event.extendedProps.timeToFinish}</div> `}
className="bg-primary text-white max-w-full min-w-full overflow-auto text-xs md:text-sm"
>
<p className="px-3 py-1 ">{e.event.title}</p>
<p className="px-3 py-1 ">{e.event.extendedProps.hostName}</p>
<p className="px-3 py-1 ">
{e.event.extendedProps.timeToStart} -{' '}
{e.event.extendedProps.timeToFinish}
</p>
<ReactTooltip data-html={true} />
</div>
);

const removeModel = (e: any) => {
e.preventDefault();
Expand All @@ -83,7 +102,6 @@ const Calendar = () => {
const newState = !addEventModel;
setAddEventModel(newState);
};
/* istanbul ignore next */

const handleAddEvent = (e: any) => {
e.preventDefault();
Expand All @@ -104,12 +122,33 @@ const Calendar = () => {
}, 1000);
};

const handleAddGuest = (traineeId: number) => {
setSelectedTrainees((prev) =>
prev.includes(traineeId)
? prev.filter((id) => id !== traineeId)
: [...prev, traineeId],
);
};

const getRoleClass = (role: Trainee['role']) => {
switch (role) {
case 'admin':
return 'bg-red-500';
case 'manager':
return 'bg-yellow-500';
case 'trainee':
return 'bg-green-500';
default:
return 'bg-gray-500';
}
};

return (
<>
{/* =========================== Start:: RegisterTraineeModel =========================== */}
<div
className={`font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${addEventModel === true ? 'block' : 'hidden'
}`}
className={`font-serif h-screen w-screen bg-black bg-opacity-30 backdrop-blur-sm fixed top-0 left-0 z-20 flex items-center justify-center px-4 ${
addEventModel === true ? 'block' : 'hidden'
}`}
>
<div className="bg-indigo-100 dark:bg-dark-bg w-full sm:w-3/4 md:w-1/2 xl:w-4/12 rounded-lg p-4 pb-8">
<div className="card-title w-full flex flex-wrap justify-center items-center ">
Expand All @@ -119,14 +158,10 @@ const Calendar = () => {
<hr className=" bg-primary border-gray-300 my-3 w-full" />
</div>
<div className="card-body">
{/* istanbul ignore next */}
<form
data-testid="handleAddEvent"
className=" py-3 px-8"
onSubmit /* istanbul ignore next */={(e) =>
/* istanbul ignore next */
handleAddEvent(e)
}
className=" py-3 px-8 overflow-y-auto h-full "
onSubmit={(e) => handleAddEvent(e)}
>
<div className="input my-3 h-9 ">
<div className="grouped-input flex items-center h-full w-full rounded-md">
Expand All @@ -137,7 +172,6 @@ const Calendar = () => {
className=" dark:bg-dark-tertiary border dark:text-white border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
placeholder={t('Event title')}
value={newEvent.title}
// eslint-disable-next-line prettier/prettier
onChange={(e) =>
setNewEvent({ ...newEvent, title: e.target.value })
}
Expand All @@ -153,11 +187,11 @@ const Calendar = () => {
className=" dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
placeholder={t('Host name')}
value={newEvent.hostName}
onChange /* istanbul ignore next */={(e) =>
/* istanbul ignore next */ setNewEvent({
...newEvent,
hostName: e.target.value,
})
onChange={(e) =>
setNewEvent({
...newEvent,
hostName: e.target.value,
})
}
/>
</div>
Expand All @@ -170,11 +204,11 @@ const Calendar = () => {
placeholderText={t('Start Date')}
style={{ marginRight: '10px' }}
selected={newEvent.start}
onChange /* istanbul ignore next */={(start: any) =>
/* istanbul ignore next */ setNewEvent({
...newEvent,
start,
})
onChange={(start: any) =>
setNewEvent({
...newEvent,
start,
})
}
/>
</div>
Expand All @@ -187,43 +221,104 @@ const Calendar = () => {
placeholderText={t('End Date')}
style={{ marginRight: '10px' }}
selected={newEvent.end}
onChange=/* istanbul ignore next */ {(end: any) =>
/* istanbul ignore next */
setNewEvent({ ...newEvent, end })
}
onChange={(end: any) => setNewEvent({ ...newEvent, end })}
/>
</div>
</div>

<div className="input my-3 h-9 ">
<div className="grouped-input flex items-center h-full w-full rounded-md">
<input
type="time"
name="hostName"
className="dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
placeholder={t('Start time')}
value={newEvent.timeToStart}
onChange /* istanbul ignore next */={(e) =>
/* istanbul ignore next */
setNewEvent({ ...newEvent, timeToStart: e.target.value })
}
/>
<div className="input my-3">
<div className="flex space-x-2">
<div className="w-1/2">
<input
type="time"
name="startTime"
className="dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-3 font-sans text-xs py-2 w-full"
placeholder={t('Start time')}
value={newEvent.timeToStart}
onChange={(e) =>
setNewEvent({
...newEvent,
timeToStart: e.target.value,
})
}
/>
</div>
<div className="w-1/2">
<input
type="time"
name="endTime"
className="dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-3 font-sans text-xs py-2 w-full"
placeholder={t('End time')}
value={newEvent.timeToFinish}
onChange={(e) =>
setNewEvent({
...newEvent,
timeToFinish: e.target.value,
})
}
/>
</div>
</div>
</div>

<div className="input my-3 h-9 ">
<div className="grouped-input flex items-center h-full w-full rounded-md">
<input
type="time"
name="hostName"
className="dark:bg-dark-tertiary dark:text-white border border-primary rounded outline-none px-5 font-sans text-xs py-2 w-full"
placeholder={t('End time')}
value={newEvent.timeToFinish}
onChange=/* istanbul ignore next */ {(e) =>
/* istanbul ignore next */
setNewEvent({ ...newEvent, timeToFinish: e.target.value })
}
/>
<div className="input my-3">
<div className="flex items-center justify-between">
<span className="text-sm mb-2">{t('Add guests')}</span>
<button
type="button"
className="bg-primary text-white rounded-full w-6 h-6 flex items-center justify-center mb-2"
onClick={() => setShowTraineeDropdown(!showTraineeDropdown)}
>
{showTraineeDropdown ? '-' : '+'}
</button>
</div>
{showTraineeDropdown && (
<div className="dark:bg-dark-tertiary dark:text-white mt-2 p-2 border border-primary rounded-md h-40 overflow-y-auto">
{trainees.map((trainee) => (
<div key={trainee.id} className="flex items-center mb-2">
<input
type="checkbox"
id={`trainee-${trainee.id}`}
checked={selectedTrainees.includes(trainee.id)}
onChange={() => handleAddGuest(trainee.id)}
className="mr-2"
/>
<label
htmlFor={`trainee-${trainee.id}`}
className="flex items-center"
>
<span
className={`w-2 h-2 rounded-full ${getRoleClass(
trainee.role,
)} mr-2`}
></span>
{trainee.name} ({trainee.role})
</label>
</div>
))}
</div>
)}
<div className="dark:bg-dark-tertiary dark:text-white mt-2 p-2 border border-primary rounded-md min-h-[40px] ">
{selectedTrainees.map((id) => {
const trainee = trainees.find((t) => t.id === id);
if (!trainee) return null;
return (
<span
key={id}
className={`inline-block ${getRoleClass(
trainee.role,
)} text-white rounded-full px-2 py-1 text-xs mr-2 mb-2 relative`}
>
{trainee.name} ({trainee.role})
<button
onClick={() => handleAddGuest(id)}
className="absolute -top-1 -right-1 bg-red-500 text-white rounded-full w-4 h-4 flex items-center justify-center text-xs hover:bg-red-600 text-center font-extrabold"
>
×
</button>
</span>
);
})}
</div>
</div>

Expand All @@ -243,7 +338,6 @@ const Calendar = () => {
</div>
</div>
</div>
{/* =========================== End:: RegisterTraineeModel =============================== */}

<div className="px-4 pb-20 w-full dark:bg-dark-frame-bg dark:text-white h-full overflow-y-scroll font-serif">
<div className="w-full flex justify-center text-xl md:text-4xl dark:text-primary mb-10">
Expand Down

0 comments on commit edb1a0f

Please sign in to comment.