Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions backend/src/routes/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import DeadlineController from '../controllers/DeadlineController';
const router = Router();

// Get all events for a particular user
router.get('/events/by-user/:user', EventController.getUserEvents);
router.get('/events/by-user/:user_id', EventController.getUserEvents);

// Add an event
router.post('/events', EventController.postEvent);
Expand All @@ -21,7 +21,7 @@ router.put('/events/id/:id', EventController.putEvent);
router.delete('/events/id/:id', EventController.deleteEvent);

// Get all deadlines for a particular user
router.get('/deadlines/by-user/:user', DeadlineController.getUserDeadlines);
router.get('/deadlines/by-user/:user_id', DeadlineController.getUserDeadlines);

// Add a deadline
router.post('/deadlines', DeadlineController.postDeadline);
Expand Down
258 changes: 258 additions & 0 deletions frontend/src/app/dashboard/calendar/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ export default function Home() {
title: data.draggedEl.innerText,
id: new Date().getTime().toString(),
start: data.date, // <-- necessary for FullCalendar
end_time: newEvent.end_time,
break_time: newEvent.break_time,
created_at: newEvent.created_at,
description: newEvent.description,
is_generated: false,
is_recurring: newEvent.is_recurring,
location_place: newEvent.location_place,
recurrence_end_date: newEvent.recurrence_end_date,
recurrence_pattern: newEvent.recurrence_pattern,
recurrence_start_date: newEvent.recurrence_start_date,
};
setAllEvents([...allEvents, event]);

Expand Down Expand Up @@ -215,6 +225,19 @@ export default function Home() {
user_id: user.uid,
start: new Date(newEvent.start_time), // <-- ensure start is there
end: newEvent.end_time ? new Date(newEvent.end_time) : undefined,
title: newEvent.title,

id: newEvent.id, // UUIDs are strings
break_time: newEvent.break_time,
start_time: newEvent.start_time,
created_at: new Date().toISOString(),
description: newEvent.description,
is_generated: false,
is_recurring: newEvent.is_recurring,
location_place: newEvent.location_place,
recurrence_end_date: newEvent.recurrence_end_date,
recurrence_pattern: newEvent.recurrence_pattern,
recurrence_start_date: newEvent.recurrence_start_date,
};
setAllEvents([...allEvents, eventWithUser]);

Expand All @@ -233,6 +256,14 @@ export default function Home() {
});
}

function generatePerfectSchedule() {
console.log('Generate perfect schedule clicked');
// Add your logic to generate the perfect schedule here
// For example, you can call an API endpoint or perform some calculations
// and then update the state accordingly.
}


return (
<>
<nav className="flex justify-between mb-12 border-b border-violet-100 p-4">
Expand Down Expand Up @@ -416,6 +447,219 @@ export default function Home() {
onChange={(e) => handleChange(e)}
placeholder=" Title"
/>

<input
type="text"
name="description"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
focus:ring-2
focus:ring-inset focus:ring-violet-600
sm:text-sm sm:leading-6"
value={newEvent.description || ''}
onChange={(e) =>
setNewEvent({
...newEvent,
description: e.target.value,
})
}
placeholder=" Description"
/>

<input
type="text"
name="location"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
focus:ring-2
focus:ring-inset focus:ring-violet-600
sm:text-sm sm:leading-6"
value={newEvent.location_place || ''}
onChange={(e) =>
setNewEvent({
...newEvent,
location_place: e.target.value,
})
}
placeholder=" Location"
/>
<input
type="DateTime-local"
name="start_time"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 text-center
focus:ring-2
focus:ring-inset focus:ring-violet-600"
value={
newEvent.start_time
? new Date(newEvent.start_time)
.toLocaleString('sv-SE')
.replace(' ', 'T')
: newEvent.start_time
}
onChange={(e) =>
setNewEvent({
...newEvent,
start_time: new Date(
e.target.value
).toISOString(),
})
}
placeholder="Start Time"
/>
<input
type="DateTime-local"
name="end_time"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
focus:ring-2
focus:ring-inset focus:ring-violet-600"
value={
newEvent.end_time
? new Date(newEvent.end_time)
.toLocaleString('sv-SE')
.replace(' ', 'T')
: newEvent.end_time || ''
}
onChange={(e) =>
setNewEvent({
...newEvent,
end_time: new Date(
e.target.value
).toISOString(),
})
}
placeholder=" End Time" // Does not work
/>
<input
type="checkbox"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
focus:ring-2
focus:ring-inset focus:ring-violet-600"
name="is_recurring"
checked={newEvent.is_recurring}
onChange={(e) =>
setNewEvent({
...newEvent,
is_recurring: e.target.checked,
})
}
placeholder=" Recurring"
/>
<label
htmlFor="is_recurring"
className="text-sm text-gray-500"
>
Reocurring
</label>
{newEvent.is_recurring && (
<input
type="DateTime-local"
name="recurrence_start_date"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
focus:ring-2
focus:ring-inset focus:ring-violet-600"
value={
newEvent.recurrence_start_date
? new Date(newEvent.recurrence_start_date)
.toLocaleString('sv-SE')
.replace(' ', 'T')
: newEvent.recurrence_start_date || ''
}
onChange={(e) =>
setNewEvent({
...newEvent,
recurrence_start_date: new Date(
e.target.value
).toISOString(),
})
}
placeholder=" Recurrence Start Date"
/>
)}
{newEvent.is_recurring && (
<input
type="DateTime-local"
name="recurrence_end_date"
className="block w-full rounded-md border-0 py-1.5 text-gray-900
shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400
focus:ring-2
focus:ring-inset focus:ring-violet-600"
value={
newEvent.recurrence_end_date
? new Date(newEvent.recurrence_end_date)
.toLocaleString('sv-SE')
.replace(' ', 'T')
: newEvent.recurrence_end_date || ''
}
onChange={(e) =>
setNewEvent({
...newEvent,
recurrence_end_date: new Date(
e.target.value
).toISOString(),
})
}
placeholder=" Recurrence End Date"
/>
)}
{newEvent.is_recurring && (
<>
<label>
<input
type="radio"
name="recurrence_pattern"
value="daily"
checked={
newEvent.recurrence_pattern === 'daily'
} // Explicitly control the checked state
onChange={(e) =>
setNewEvent({
...newEvent,
recurrence_pattern: e.target.value,
})
}
/>
Daily
</label>
<label>
<input
type="radio"
name="recurrence_pattern"
value="weekly"
checked={
newEvent.recurrence_pattern === 'weekly'
} // Explicitly control the checked state
onChange={(e) =>
setNewEvent({
...newEvent,
recurrence_pattern: e.target.value,
})
}
/>
Weekly
</label>
<label>
<input
type="radio"
name="recurrence_pattern"
value="monthly"
checked={
newEvent.recurrence_pattern === 'monthly'
} // Explicitly control the checked state
onChange={(e) =>
setNewEvent({
...newEvent,
recurrence_pattern: e.target.value,
})
}
/>
Monthly
</label>
</>
)}
</div>
<div className="mt-5 sm:mt-6 sm:grid sm:grid-flow-row-dense sm:grid-cols-2 sm:gap-3">
<button
Expand All @@ -442,6 +686,20 @@ export default function Home() {
</div>
</Dialog>
</Transition.Root>
<div className="fixed bottom-20 right-8 z-50 flex flex-col items-center space-y-2">
<div className="bg-white dark:bg-gray-800 px-3 py-2 rounded-md shadow-md text-center">
<span className="text-sm text-gray-700 dark:text-gray-300 break-words text-center">
Generate Your Perfect Schedule
</span>
</div>
<button
onClick={generatePerfectSchedule}
className="flex items-center justify-center w-16 h-16 bg-violet-500 text-white rounded-full shadow-lg hover:bg-violet-600 transition-colors duration-200"
aria-label="Generate Your Perfect Schedule"
>
<span className="text-xs text-center">Gen</span>
</button>
</div>
</main>
</>
);
Expand Down