diff --git a/apps/calendar/src/app/[locale]/(root)/scheduler/components/ScheduleDisplay.tsx b/apps/calendar/src/app/[locale]/(root)/scheduler/components/ScheduleDisplay.tsx index b678398e2..d0a041764 100644 --- a/apps/calendar/src/app/[locale]/(root)/scheduler/components/ScheduleDisplay.tsx +++ b/apps/calendar/src/app/[locale]/(root)/scheduler/components/ScheduleDisplay.tsx @@ -13,6 +13,7 @@ import { AlertTriangleIcon, CalendarIcon, ClockIcon, + LockIcon, SparklesIcon, TrendingUpIcon, } from '@tuturuuu/ui/icons'; @@ -225,15 +226,29 @@ export function ScheduleDisplay({ events }: ScheduleDisplayProps) { {/* Event Card */}
{/* Event Header */}
+ {event.locked && ( + + + + + +

+ Locked event: this time is blocked +

+
+
+ )} {event.isPastDeadline && ( diff --git a/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskList.tsx b/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskList.tsx index 4429ae772..0aae7d0d5 100644 --- a/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskList.tsx +++ b/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskList.tsx @@ -18,6 +18,7 @@ import { Trash2Icon, ZapIcon, } from '@tuturuuu/ui/icons'; +import { SplitIcon } from '@tuturuuu/ui/icons'; import { Input } from '@tuturuuu/ui/input'; import { Label } from '@tuturuuu/ui/label'; import { Progress } from '@tuturuuu/ui/progress'; @@ -28,6 +29,7 @@ import { SelectTrigger, SelectValue, } from '@tuturuuu/ui/select'; +import { Switch } from '@tuturuuu/ui/switch'; import { Tooltip, TooltipContent, TooltipTrigger } from '@tuturuuu/ui/tooltip'; import dayjs from 'dayjs'; import { useMemo } from 'react'; @@ -245,6 +247,29 @@ export function TaskList({ : '' }`} /> + {/* Split Toggle Button */} +
+ + +
+ + + onUpdateTask(task.id, { + allowSplit: checked, + }) + } + className="scale-90" + /> +
+
+ + Allow this task to be split into sessions + +
+
{isCompleted && ( )} diff --git a/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskModal.tsx b/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskModal.tsx index 2c1287040..6b3663d43 100644 --- a/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskModal.tsx +++ b/apps/calendar/src/app/[locale]/(root)/scheduler/components/TaskModal.tsx @@ -11,6 +11,7 @@ import { DialogTitle, } from '@tuturuuu/ui/dialog'; import { CalendarIcon, ClockIcon, PlusIcon, TagIcon } from '@tuturuuu/ui/icons'; +import { SplitIcon } from '@tuturuuu/ui/icons'; import { Input } from '@tuturuuu/ui/input'; import { Label } from '@tuturuuu/ui/label'; import { @@ -20,15 +21,15 @@ import { SelectTrigger, SelectValue, } from '@tuturuuu/ui/select'; -import { Separator } from '@tuturuuu/ui/separator'; +import { Switch } from '@tuturuuu/ui/switch'; import { Textarea } from '@tuturuuu/ui/textarea'; import dayjs from 'dayjs'; import { useState } from 'react'; interface TaskModalProps { isOpen: boolean; - onClose: () => void; - onAddTask: (task: Omit) => void; + onCloseAction: () => void; + onAddTaskAction: (task: Omit) => void; } const categoryOptions = [ @@ -52,7 +53,11 @@ const categoryOptions = [ }, ] as const; -export function TaskModal({ isOpen, onClose, onAddTask }: TaskModalProps) { +export function TaskModal({ + isOpen, + onCloseAction, + onAddTaskAction, +}: TaskModalProps) { const [formData, setFormData] = useState({ name: '', description: '', @@ -62,6 +67,7 @@ export function TaskModal({ isOpen, onClose, onAddTask }: TaskModalProps) { category: 'work' as 'work' | 'personal' | 'meeting', deadline: '', priority: 'medium' as 'low' | 'medium' | 'high', + allowSplit: true, }); const [errors, setErrors] = useState>({}); @@ -115,9 +121,10 @@ export function TaskModal({ isOpen, onClose, onAddTask }: TaskModalProps) { maxDuration: formData.maxDuration, category: formData.category, deadline: formData.deadline ? dayjs(formData.deadline) : undefined, + allowSplit: formData.allowSplit, }; - onAddTask(newTask); + onAddTaskAction(newTask); handleClose(); }; @@ -131,12 +138,13 @@ export function TaskModal({ isOpen, onClose, onAddTask }: TaskModalProps) { category: 'work', deadline: '', priority: 'medium', + allowSplit: true, }); setErrors({}); - onClose(); + onCloseAction(); }; - const updateFormData = (field: string, value: string | number) => { + const updateFormData = (field: string, value: string | number | boolean) => { setFormData((prev) => ({ ...prev, [field]: value })); if (errors[field]) { setErrors((prev) => ({ ...prev, [field]: '' })); @@ -145,7 +153,7 @@ export function TaskModal({ isOpen, onClose, onAddTask }: TaskModalProps) { return ( - + @@ -156,189 +164,185 @@ export function TaskModal({ isOpen, onClose, onAddTask }: TaskModalProps) { -
- {/* Basic Information */} -
-
- - updateFormData('name', e.target.value)} - className={errors.name ? 'border-destructive' : ''} - /> - {errors.name && ( -

{errors.name}

- )} -
- -
- -