diff --git a/package-lock.json b/package-lock.json index 60fb075..a41a8ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@mui/icons-material": "^6.4.1", "@mui/material": "^6.4.1", "@mui/x-date-pickers": "^7.24.0", + "@swc/core": "^1.10.11", "@zl-asica/react": "^0.3.10", "dayjs": "^1.11.13", "es-toolkit": "^1.29.0", @@ -3364,10 +3365,9 @@ } }, "node_modules/@swc/core": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.6.tgz", - "integrity": "sha512-zgXXsI6SAVwr6XsXyMnqlyLoa1lT+r09bAWI1xT3679ejWqI1Vnl14eJG0GjWYXCEMKHCNytfMq3OOQ62C39QQ==", - "dev": true, + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.11.tgz", + "integrity": "sha512-3zGU5y3S20cAwot9ZcsxVFNsSVaptG+dKdmAxORSE3EX7ixe1Xn5kUwLlgIsM4qrwTUWCJDLNhRS+2HLFivcDg==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -3382,16 +3382,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.10.6", - "@swc/core-darwin-x64": "1.10.6", - "@swc/core-linux-arm-gnueabihf": "1.10.6", - "@swc/core-linux-arm64-gnu": "1.10.6", - "@swc/core-linux-arm64-musl": "1.10.6", - "@swc/core-linux-x64-gnu": "1.10.6", - "@swc/core-linux-x64-musl": "1.10.6", - "@swc/core-win32-arm64-msvc": "1.10.6", - "@swc/core-win32-ia32-msvc": "1.10.6", - "@swc/core-win32-x64-msvc": "1.10.6" + "@swc/core-darwin-arm64": "1.10.11", + "@swc/core-darwin-x64": "1.10.11", + "@swc/core-linux-arm-gnueabihf": "1.10.11", + "@swc/core-linux-arm64-gnu": "1.10.11", + "@swc/core-linux-arm64-musl": "1.10.11", + "@swc/core-linux-x64-gnu": "1.10.11", + "@swc/core-linux-x64-musl": "1.10.11", + "@swc/core-win32-arm64-msvc": "1.10.11", + "@swc/core-win32-ia32-msvc": "1.10.11", + "@swc/core-win32-x64-msvc": "1.10.11" }, "peerDependencies": { "@swc/helpers": "*" @@ -3403,13 +3403,12 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.6.tgz", - "integrity": "sha512-USbMvT8Rw5PvIfF6HyTm+yW84J9c45emzmHBDIWY76vZHkFsS5MepNi+JLQyBzBBgE7ScwBRBNhRx6VNhkSoww==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.11.tgz", + "integrity": "sha512-ZpgEaNcx2e5D+Pd0yZGVbpSrEDOEubn7r2JXoNBf0O85lPjUm3HDzGRfLlV/MwxRPAkwm93eLP4l7gYnc50l3g==", "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3420,13 +3419,12 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.6.tgz", - "integrity": "sha512-7t2IozcZN4r1p27ei+Kb8IjN4aLoBDn107fPi+aPLcVp2uFgJEUzhCDuZXBNW2057Mx1OHcjzrkaleRpECz3Xg==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.11.tgz", + "integrity": "sha512-szObinnq2o7spXMDU5pdunmUeLrfV67Q77rV+DyojAiGJI1RSbEQotLOk+ONOLpoapwGUxOijFG4IuX1xiwQ2g==", "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3437,13 +3435,12 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.6.tgz", - "integrity": "sha512-CPgWT+D0bDp/qhXsLkIJ54LmKU1/zvyGaf/yz8A4iR+YoF6R5CSXENXhNJY8cIrb6+uNWJZzHJ+gefB5V51bpA==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.11.tgz", + "integrity": "sha512-tVE8aXQwd8JUB9fOGLawFJa76nrpvp3dvErjozMmWSKWqtoeO7HV83aOrVtc8G66cj4Vq7FjTE9pOJeV1FbKRw==", "cpu": [ "arm" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3454,13 +3451,12 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.6.tgz", - "integrity": "sha512-5qZ6hVnqO/ShETXdGSzvdGUVx372qydlj1YWSYiaxQzTAepEBc8TC1NVUgYtOHOKVRkky1d7p6GQ9lymsd4bHw==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.11.tgz", + "integrity": "sha512-geFkENU5GMEKO7FqHOaw9HVlpQEW10nICoM6ubFc0hXBv8dwRXU4vQbh9s/isLSFRftw1m4jEEWixAnXSw8bxQ==", "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3471,13 +3467,12 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.6.tgz", - "integrity": "sha512-hB2xZFmXCKf2iJF5y2z01PSuLqEoUP3jIX/XlIHN+/AIP7PkSKsValE63LnjlnWPnSEI0IxUyRE3T3FzWE/fQQ==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.11.tgz", + "integrity": "sha512-2mMscXe/ivq8c4tO3eQSbQDFBvagMJGlalXCspn0DgDImLYTEnt/8KHMUMGVfh0gMJTZ9q4FlGLo7mlnbx99MQ==", "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3488,13 +3483,12 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.6.tgz", - "integrity": "sha512-PRGPp0I22+oJ8RMGg8M4hXYxEffH3ayu0WoSDPOjfol1F51Wj1tfTWN4wVa2RibzJjkBwMOT0KGLGb/hSEDDXQ==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.11.tgz", + "integrity": "sha512-eu2apgDbC4xwsigpl6LS+iyw6a3mL6kB4I+6PZMbFF2nIb1Dh7RGnu70Ai6mMn1o80fTmRSKsCT3CKMfVdeNFg==", "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3505,13 +3499,12 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.6.tgz", - "integrity": "sha512-SoNBxlA86lnoV9vIz/TCyakLkdRhFSHx6tFMKNH8wAhz1kKYbZfDmpYoIzeQqdTh0tpx8e/Zu1zdK4smovsZqQ==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.11.tgz", + "integrity": "sha512-0n+wPWpDigwqRay4IL2JIvAqSKCXv6nKxPig9M7+epAlEQlqX+8Oq/Ap3yHtuhjNPb7HmnqNJLCXT1Wx+BZo0w==", "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3522,13 +3515,12 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.6.tgz", - "integrity": "sha512-6L5Y2E+FVvM+BtoA+mJFjf/SjpFr73w2kHBxINxwH8/PkjAjkePDr5m0ibQhPXV61bTwX49+1otzTY85EsUW9Q==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.11.tgz", + "integrity": "sha512-7+bMSIoqcbXKosIVd314YjckDRPneA4OpG1cb3/GrkQTEDXmWT3pFBBlJf82hzJfw7b6lfv6rDVEFBX7/PJoLA==", "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3539,13 +3531,12 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.6.tgz", - "integrity": "sha512-kxK3tW8DJwEkAkwy0vhwoBAShRebH1QTe0mvH9tlBQ21rToVZQn+GCV/I44dind80hYPw0Tw2JKFVfoEJyBszg==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.11.tgz", + "integrity": "sha512-6hkLl4+3KjP/OFTryWxpW7YFN+w4R689TSPwiII4fFgsFNupyEmLWWakKfkGgV2JVA59L4Oi02elHy/O1sbgtw==", "cpu": [ "ia32" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3556,13 +3547,12 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.6.tgz", - "integrity": "sha512-4pJka/+t8XcHee12G/R5VWcilkp5poT2EJhrybpuREkpQ7iC/4WOlOVrohbWQ4AhDQmojYQI/iS+gdF2JFLzTQ==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.11.tgz", + "integrity": "sha512-kKNE2BGu/La2k2WFHovenqZvGQAHRIU+rd2/6a7D6EiQ6EyimtbhUqjCCZ+N1f5fIAnvM+sMdLiQJq4jdd/oOQ==", "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -3576,14 +3566,12 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true, "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz", "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" diff --git a/package.json b/package.json index bceaf3d..94ffbdb 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@mui/icons-material": "^6.4.1", "@mui/material": "^6.4.1", "@mui/x-date-pickers": "^7.24.0", + "@swc/core": "^1.10.11", "@zl-asica/react": "^0.3.10", "dayjs": "^1.11.13", "es-toolkit": "^1.29.0", diff --git a/src/components/Home/Calendar/AddTaskButton/index.tsx b/src/components/Home/Calendar/AddTaskButton/index.tsx index afe41d2..03c68b8 100644 --- a/src/components/Home/Calendar/AddTaskButton/index.tsx +++ b/src/components/Home/Calendar/AddTaskButton/index.tsx @@ -8,9 +8,11 @@ import { DialogContent, DialogTitle, FormControl, + FormControlLabel, InputLabel, MenuItem, Select, + Switch, } from '@mui/material' import { generateUniqueId, useToggle } from '@zl-asica/react' import { useCallback, useEffect, useState } from 'react' @@ -20,6 +22,11 @@ interface AddTaskButtonProps { selectedDate: Dayjs | null } +interface TimeOption { + value: string + label: string +} + const AddTaskButton = ({ selectedDate }: AddTaskButtonProps) => { const addTask = useScheduleStore(state => state.addTask) @@ -35,6 +42,21 @@ const AddTaskButton = ({ selectedDate }: AddTaskButtonProps) => { const [endTime, setEndTime] = useState('') const [loading, setLoading] = useState(false) + // New recurring task states + const [isRecurring, setIsRecurring] = useState(false) + const [recurrenceType, setRecurrenceType] = useState<'daily' | 'weekly' | 'monthly'>('daily') + const [recurrenceInterval, setRecurrenceInterval] = useState(1) + const [recurrenceEndDate, setRecurrenceEndDate] = useState('') + + // Generate time options in 30-minute intervals + const timeOptions: TimeOption[] = Array.from({ length: 48 }, (_, i) => { + const hour = Math.floor(i / 2) + const minute = (i % 2) * 30 + const value = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}` + const label = `${hour === 0 ? 12 : hour > 12 ? hour - 12 : hour}:${minute.toString().padStart(2, '0')} ${hour >= 12 ? 'PM' : 'AM'}` + return { value, label } + }) + useEffect(() => { setDate(selectedDate?.format('YYYY-MM-DD') ?? new Date().toISOString().split('T')[0]) }, [selectedDate]) @@ -49,6 +71,10 @@ const AddTaskButton = ({ selectedDate }: AddTaskButtonProps) => { setDate(selectedDate?.format('YYYY-MM-DD') ?? new Date().toISOString().split('T')[0]) setStartTime('') setEndTime('') + setIsRecurring(false) + setRecurrenceType('daily') + setRecurrenceInterval(1) + setRecurrenceEndDate('') }, [selectedDate]) const handleAddTask = useCallback(async () => { @@ -63,6 +89,14 @@ const AddTaskButton = ({ selectedDate }: AddTaskButtonProps) => { date, timeRange: startTime && endTime ? { start: startTime, end: endTime } : undefined, status: 'pending' as const, + isRecurring, + ...(isRecurring && { + recurrencePattern: { + type: recurrenceType, + interval: recurrenceInterval, + ...(recurrenceEndDate && { endDate: recurrenceEndDate }), + }, + }), } try { @@ -76,7 +110,22 @@ const AddTaskButton = ({ selectedDate }: AddTaskButtonProps) => { finally { setLoading(false) } - }, [title, description, category, priority, date, startTime, endTime, addTask, resetStates, toggleOpen]) + }, [ + title, + description, + category, + priority, + date, + startTime, + endTime, + isRecurring, + recurrenceType, + recurrenceInterval, + recurrenceEndDate, + addTask, + resetStates, + toggleOpen, + ]) return ( <> @@ -103,11 +152,95 @@ const AddTaskButton = ({ selectedDate }: AddTaskButtonProps) => { Add Task - - +
+ + Start Time + + + + + End Time + + +
+ + setIsRecurring(e.target.checked)} + /> + )} + label="Recurring Task" + sx={{ mt: 2, mb: 1 }} + /> + + {isRecurring && ( + <> + + Repeat + + + + + Every + + + + + + )} + Category * + Priority *