From 1ebd90de49c560a8d3d971edf0d2a786f93ac8a6 Mon Sep 17 00:00:00 2001 From: Faaez Date: Tue, 9 Jul 2024 23:27:09 -0500 Subject: [PATCH 1/6] Add api route for base api call --- frontend/app/api/planner/route.ts | 31 ++++++ .../planner/ArchiveView/ArchiveView.tsx | 9 ++ frontend/components/planner/Planner.tsx | 11 ++- .../planner/RightSideBar/RightSideBar.tsx | 96 ------------------- .../planner/Sidebar/ArchiveModeToggle.tsx | 20 ++++ .../ManageBoardsSheetTrigger.tsx | 2 +- .../ManageCategoriesSheetTrigger.tsx | 2 +- .../components/planner/Sidebar/Sidebar.tsx | 6 +- frontend/hooks/Planner/Planner.tsx | 3 +- frontend/hooks/Planner/plannerReducer.tsx | 6 ++ frontend/hooks/Planner/types.tsx | 1 + frontend/lib/dbConnect.ts | 51 ++++++++++ frontend/models/Planner.ts | 63 ++++++++++++ frontend/package-lock.json | 85 +++++++++++++--- frontend/package.json | 1 + 15 files changed, 270 insertions(+), 117 deletions(-) create mode 100644 frontend/app/api/planner/route.ts create mode 100644 frontend/components/planner/ArchiveView/ArchiveView.tsx delete mode 100644 frontend/components/planner/RightSideBar/RightSideBar.tsx create mode 100644 frontend/components/planner/Sidebar/ArchiveModeToggle.tsx rename frontend/components/planner/Sidebar/{ => ManageBoardsDialog}/ManageBoardsSheetTrigger.tsx (90%) rename frontend/components/planner/Sidebar/{ => ManageCategoriesDialog}/ManageCategoriesSheetTrigger.tsx (97%) create mode 100644 frontend/lib/dbConnect.ts create mode 100644 frontend/models/Planner.ts diff --git a/frontend/app/api/planner/route.ts b/frontend/app/api/planner/route.ts new file mode 100644 index 0000000..d0a935b --- /dev/null +++ b/frontend/app/api/planner/route.ts @@ -0,0 +1,31 @@ +import dbConnect from '@/lib/dbConnect' +import Planner from '@/models/Planner' +import { auth } from '@clerk/nextjs/server' +import { NextResponse } from 'next/server' + +export async function GET(req: Request) { + await dbConnect() + + const { userId } = auth() + + if (!userId) { + return Response.json({ status: 401, error: 'Unauthorized' }) + } + + let user = await Planner.findOne({ clerkUserId: userId }).lean() + if (!user) { + // If user doesn't exist, create a new one + user = new Planner({ + clerkUserId: userId, + boardOrder: [], + boards: {}, + columns: {}, + categories: {}, + taskCards: {}, + subTasks: {}, + }) + await user.save() + user = user.toObject() + } + return NextResponse.json(user) +} diff --git a/frontend/components/planner/ArchiveView/ArchiveView.tsx b/frontend/components/planner/ArchiveView/ArchiveView.tsx new file mode 100644 index 0000000..01e34a5 --- /dev/null +++ b/frontend/components/planner/ArchiveView/ArchiveView.tsx @@ -0,0 +1,9 @@ +import { TaskFilterSearchBar } from '../Board/TaskFilterSearchBar' + +export const ArchiveView = () => { + return ( +
+ +
+ ) +} diff --git a/frontend/components/planner/Planner.tsx b/frontend/components/planner/Planner.tsx index 202ce1d..59f9270 100644 --- a/frontend/components/planner/Planner.tsx +++ b/frontend/components/planner/Planner.tsx @@ -7,6 +7,7 @@ import { DragDropContext } from '@hello-pangea/dnd' import { BackendErrorAlertCard } from '../global/AlertCard/AlertCard' import { MultiStepLoader } from '../ui/multi-step-loader' import { AddBoardCallout } from './AddBoardCallout' +import { ArchiveView } from './ArchiveView/ArchiveView' import { Board } from './Board/Board' import { Sidebar } from './Sidebar/Sidebar' import { handleOnDragEnd, handleOnDragStart } from './utils' @@ -30,7 +31,7 @@ export const Planner = () => { return (
- {plannerContext.boardOrder.length > 0 && plannerContext.selectedBoard && ( + {plannerContext.boardOrder.length > 0 && ( handleOnDragStart(dragStartObj, plannerDispatch)} onDragEnd={(result) => @@ -40,7 +41,13 @@ export const Planner = () => {
- + {plannerContext.currentView === 'board' ? ( + + ) : plannerContext.currentView === 'archive' ? ( + + ) : ( + <> + )}
diff --git a/frontend/components/planner/RightSideBar/RightSideBar.tsx b/frontend/components/planner/RightSideBar/RightSideBar.tsx deleted file mode 100644 index 089609a..0000000 --- a/frontend/components/planner/RightSideBar/RightSideBar.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Home, LineChart, Package, Package2, Settings, ShoppingCart, Users2 } from 'lucide-react' -import Link from 'next/link' - -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' - -export const RightSideBar = () => { - return ( - - ) -} diff --git a/frontend/components/planner/Sidebar/ArchiveModeToggle.tsx b/frontend/components/planner/Sidebar/ArchiveModeToggle.tsx new file mode 100644 index 0000000..d6973d1 --- /dev/null +++ b/frontend/components/planner/Sidebar/ArchiveModeToggle.tsx @@ -0,0 +1,20 @@ +import { Button } from '@/components/ui/button' +import { usePlanner, usePlannerDispatch } from '@/hooks/Planner/Planner' +import { Archive } from 'lucide-react' + +export const ArchiveModeToggle = () => { + const { currentView } = usePlanner() + const dispatch = usePlannerDispatch() + return ( + + ) +} diff --git a/frontend/components/planner/Sidebar/ManageBoardsSheetTrigger.tsx b/frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx similarity index 90% rename from frontend/components/planner/Sidebar/ManageBoardsSheetTrigger.tsx rename to frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx index 8925e86..c5267ce 100644 --- a/frontend/components/planner/Sidebar/ManageBoardsSheetTrigger.tsx +++ b/frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx @@ -1,7 +1,7 @@ import { Button } from '@/components/ui/button' import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet' import { Kanban } from 'lucide-react' -import { ManageBoardsDialog } from './ManageBoardsDialog/ManageBoardsDialog' +import { ManageBoardsDialog } from './ManageBoardsDialog' export const ManageBoardsSheetTrigger = () => { return ( diff --git a/frontend/components/planner/Sidebar/ManageCategoriesSheetTrigger.tsx b/frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx similarity index 97% rename from frontend/components/planner/Sidebar/ManageCategoriesSheetTrigger.tsx rename to frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx index 6812bf1..9fd64ba 100644 --- a/frontend/components/planner/Sidebar/ManageCategoriesSheetTrigger.tsx +++ b/frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx @@ -1,7 +1,7 @@ import { Button } from '@/components/ui/button' import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet' import { Tag } from 'lucide-react' -import { ManageCategoriesDialog } from './ManageCategoriesDialog/ManageCategoriesDialog' +import { ManageCategoriesDialog } from './ManageCategoriesDialog' export const ManageCategoriesSheetTrigger = () => { return ( diff --git a/frontend/components/planner/Sidebar/Sidebar.tsx b/frontend/components/planner/Sidebar/Sidebar.tsx index 3151aa3..0e02fc8 100644 --- a/frontend/components/planner/Sidebar/Sidebar.tsx +++ b/frontend/components/planner/Sidebar/Sidebar.tsx @@ -4,8 +4,9 @@ import { usePlanner, usePlannerDispatch } from '@/hooks/Planner/Planner' import { BoardInfoType } from '@/hooks/Planner/types' import { usePlannerFiltersDispatch } from '@/hooks/PlannerFilters/PlannerFilters' import { Github } from 'lucide-react' -import { ManageBoardsSheetTrigger } from './ManageBoardsSheetTrigger' -import { ManageCategoriesSheetTrigger } from './ManageCategoriesSheetTrigger' +import { ArchiveModeToggle } from './ArchiveModeToggle' +import { ManageBoardsSheetTrigger } from './ManageBoardsDialog/ManageBoardsSheetTrigger' +import { ManageCategoriesSheetTrigger } from './ManageCategoriesDialog/ManageCategoriesSheetTrigger' type BoardButtonProps = { board: BoardInfoType @@ -51,6 +52,7 @@ export const Sidebar = () => { +
diff --git a/frontend/hooks/Planner/Planner.tsx b/frontend/hooks/Planner/Planner.tsx index 0fbd075..c99c57d 100644 --- a/frontend/hooks/Planner/Planner.tsx +++ b/frontend/hooks/Planner/Planner.tsx @@ -7,6 +7,7 @@ import { PlannerType } from './types' const initialEmptyState: PlannerType = { backendErrorOccurred: false, + currentView: 'board', hasLoaded: false, selectedBoard: '', isSubTaskBeingDragged: false, @@ -42,7 +43,7 @@ export const PlannerProvider = ({ children }: { children: JSX.Element | JSX.Elem const fetchData = async () => { const token = await getToken() axios - .get(`${process.env.NEXT_PUBLIC_BACKEND_URL}/planner`, { + .get('/api/planner', { headers: { Authorization: `Bearer ${token}`, }, diff --git a/frontend/hooks/Planner/plannerReducer.tsx b/frontend/hooks/Planner/plannerReducer.tsx index 3382e15..6d9ae04 100644 --- a/frontend/hooks/Planner/plannerReducer.tsx +++ b/frontend/hooks/Planner/plannerReducer.tsx @@ -12,9 +12,15 @@ export const plannerReducer = produce((draft: Draft, action) => { break } case 'selectedBoardChanged': { + draft.currentView = 'board' draft.selectedBoard = action.payload.boardId break } + case 'archiveModeToggled': { + draft.currentView = 'archive' + draft.selectedBoard = '' + break + } case 'newBoardAdded': { const { boardId, boardName, unassignedCategoryDetails } = action.payload draft.boardOrder.push(boardId) diff --git a/frontend/hooks/Planner/types.tsx b/frontend/hooks/Planner/types.tsx index 7f5a316..c812f07 100644 --- a/frontend/hooks/Planner/types.tsx +++ b/frontend/hooks/Planner/types.tsx @@ -80,6 +80,7 @@ export type BoardsType = { export type PlannerType = { hasLoaded: boolean + currentView: 'board' | 'archive' backendErrorOccurred: boolean selectedBoard: string isSubTaskBeingDragged: boolean diff --git a/frontend/lib/dbConnect.ts b/frontend/lib/dbConnect.ts new file mode 100644 index 0000000..0b9d67b --- /dev/null +++ b/frontend/lib/dbConnect.ts @@ -0,0 +1,51 @@ +import mongoose, { Mongoose } from 'mongoose' + +const MONGO_URI: string | undefined = process.env.MONGO_URI + +if (!MONGO_URI) { + throw new Error('Please define the MONGO_URI environment variable') +} + +interface CachedType { + conn: Mongoose | null + promise: Promise | null +} + +declare global { + // Allow access to this globally in the Node.js process + // eslint-disable-next-line no-var + var mongoose: CachedType +} + +let cached: CachedType = global.mongoose + +if (!cached) { + cached = global.mongoose = { conn: null, promise: null } +} + +async function dbConnect(): Promise { + if (cached.conn) { + return cached.conn + } + + if (!cached.promise) { + const opts = { + bufferCommands: false, + } + + cached.promise = mongoose.connect(MONGO_URI!, opts).then((mongoose) => { + return mongoose + }) + } + + try { + cached.conn = await cached.promise + } catch (e) { + cached.promise = null + throw e + } + + return cached.conn +} + +export default dbConnect diff --git a/frontend/models/Planner.ts b/frontend/models/Planner.ts new file mode 100644 index 0000000..d225da8 --- /dev/null +++ b/frontend/models/Planner.ts @@ -0,0 +1,63 @@ +const mongoose = require('mongoose') +const { Schema } = mongoose + +const subTaskSchema = new Schema( + { + id: { type: String, required: true }, + title: { type: String, required: true }, + checked: { type: Boolean, default: false }, + }, + { _id: false } +) + +const taskCardSchema = new Schema( + { + id: { type: String, required: true }, + title: { type: String, required: true }, + category: { type: String, required: true }, + content: { type: String }, + checked: { type: Boolean, default: false }, + subTasks: [subTaskSchema], + }, + { _id: false } +) + +const columnSchema = new Schema( + { + id: { type: String, required: true }, + name: { type: String, required: true }, + taskCards: [String], + }, + { _id: false } +) + +const boardSchema = new Schema( + { + id: { type: String, required: true }, + name: { type: String, required: true }, + columns: [String], + categories: [String], + }, + { _id: false } +) + +const categorySchema = new Schema( + { + id: { type: String, required: true }, + name: { type: String, required: true }, + color: { type: String, required: true }, + }, + { _id: false } +) + +const plannerSchema = new Schema({ + clerkUserId: { type: String, required: true }, + boardOrder: [String], + boards: { type: Object, of: boardSchema }, + columns: { type: Object, of: columnSchema }, + categories: { type: Object, of: categorySchema }, + taskCards: { type: Object, of: taskCardSchema }, + subTasks: { type: Object, of: subTaskSchema }, +}) + +export default mongoose.models.Planner || mongoose.model('Planner', plannerSchema, 'planner') diff --git a/frontend/package-lock.json b/frontend/package-lock.json index fc37678..0a6e961 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -41,6 +41,7 @@ "lodash": "^4.17.21", "lucide-react": "^0.279.0", "mongodb": "^6.3.0", + "mongoose": "^8.5.0", "next": "latest", "next-themes": "^0.3.0", "react": "^18.2.0", @@ -2348,9 +2349,9 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", - "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz", + "integrity": "sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -4562,9 +4563,9 @@ } }, "node_modules/bson": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", - "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", + "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", "engines": { "node": ">=16.20.1" } @@ -5107,7 +5108,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -6823,6 +6823,14 @@ "node": ">=4.0" } }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/keyv": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", @@ -7044,12 +7052,12 @@ } }, "node_modules/mongodb": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", - "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", + "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -7128,11 +7136,55 @@ "node": ">=16" } }, + "node_modules/mongoose": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.0.tgz", + "integrity": "sha512-iGgZvgO+fIgX1AQMehkG+Wj8qrWc9it8vUZrSKWjrebgfwHTqUcIdTgWK8mT1us1xd83NOQxiuGbg9ZJtLxs2Q==", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "6.7.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mz": { "version": "2.7.0", @@ -8233,6 +8285,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 6c8a40e..76797d8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -42,6 +42,7 @@ "lodash": "^4.17.21", "lucide-react": "^0.279.0", "mongodb": "^6.3.0", + "mongoose": "^8.5.0", "next": "latest", "next-themes": "^0.3.0", "react": "^18.2.0", From e792129b280fab2b5c5b02c90b471a34f2d4d234 Mon Sep 17 00:00:00 2001 From: Faaez Date: Wed, 10 Jul 2024 00:46:41 -0500 Subject: [PATCH 2/6] Add middleware and two more routes --- backend/index.mjs | 3 +- backend/routes/planner/boards.mjs | 40 ----------------- backend/routes/planner/planner.mjs | 40 ----------------- frontend/app/api/planner/boards/[id]/route.ts | 43 +++++++++++++++++++ frontend/app/api/planner/boards/route.ts | 30 +++++++++++++ frontend/app/api/planner/route.ts | 17 ++------ .../boardUtils/addNewBoardToPlanner.ts | 2 +- .../boardUtils/changeBoardInfo.ts | 2 +- frontend/lib/middleware.ts | 41 ++++++++++++++++++ 9 files changed, 121 insertions(+), 97 deletions(-) delete mode 100644 backend/routes/planner/planner.mjs create mode 100644 frontend/app/api/planner/boards/[id]/route.ts create mode 100644 frontend/app/api/planner/boards/route.ts create mode 100644 frontend/lib/middleware.ts diff --git a/backend/index.mjs b/backend/index.mjs index 83c4dd8..7b6efde 100644 --- a/backend/index.mjs +++ b/backend/index.mjs @@ -6,7 +6,6 @@ import boards from './routes/planner/boards.mjs' import cards from './routes/planner/cards.mjs' import categories from './routes/planner/categories.mjs' import columns from './routes/planner/columns.mjs' -import planner from './routes/planner/planner.mjs' import subtasks from './routes/planner/subtasks.mjs' const PORT = process.env.PORT || 5050 @@ -28,7 +27,7 @@ app.use(express.json()) app.use(ClerkExpressRequireAuth()) -app.use('/', [planner, boards, columns, cards, subtasks, categories]) +app.use('/', [boards, columns, cards, subtasks, categories]) // Global error handling app.use((err, _req, res, next) => { diff --git a/backend/routes/planner/boards.mjs b/backend/routes/planner/boards.mjs index 89516b1..a69c4a6 100644 --- a/backend/routes/planner/boards.mjs +++ b/backend/routes/planner/boards.mjs @@ -4,44 +4,6 @@ import { errorHandler } from '../../middleware/index.mjs' const router = express.Router() -const addNewBoard = async (req, res) => { - const userId = req.auth.userId - const { boardId, boardName, unassignedCategoryDetails } = req.body - await db.collection('planner').updateMany( - { clerkUserId: userId }, - { - $push: { - boardOrder: boardId, - }, - $set: { - [`boards.${boardId}`]: { - id: boardId, - name: boardName, - columns: [], - categories: [unassignedCategoryDetails.id], - }, - [`categories.${unassignedCategoryDetails.id}`]: unassignedCategoryDetails, - }, - } - ) - res.status(201).end() -} - -const changeBoardName = async (req, res) => { - const userId = req.auth.userId - const { boardId } = req.params - const { newName } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`boards.${boardId}.name`]: newName, - }, - } - ) - res.status(200).end() -} - const deleteBoard = async (req, res) => { const userId = req.auth.userId const { boardId } = req.params @@ -59,8 +21,6 @@ const deleteBoard = async (req, res) => { res.status(204).end() } -router.post('/planner/boards/', errorHandler(addNewBoard)) -router.patch('/planner/boards/:boardId', errorHandler(changeBoardName)) router.delete('/planner/boards/:boardId', errorHandler(deleteBoard)) export default router diff --git a/backend/routes/planner/planner.mjs b/backend/routes/planner/planner.mjs deleted file mode 100644 index 464df40..0000000 --- a/backend/routes/planner/planner.mjs +++ /dev/null @@ -1,40 +0,0 @@ -import express from 'express' -import db from '../../db/conn.mjs' - -const router = express.Router() - -// Get all planner data for given user -router.get('/planner', async (req, res) => { - try { - const userId = req.auth.userId - const user = await db.collection('planner').findOne({ clerkUserId: userId }) - if (!user) { - const newUser = { - clerkUserId: userId, - boardOrder: [], - boards: {}, - columns: {}, - categories: {}, - taskCards: {}, - subTasks: {}, - } - await db.collection('planner').insertOne(newUser) - } - - const results = await db - .collection('planner') - .aggregate([ - { $match: { clerkUserId: userId } }, - { $project: { boardOrder: 1, boards: 1, columns: 1, categories: 1, taskCards: 1, subTasks: 1, _id: 0 } }, - { $limit: 1 }, - ]) - .toArray() - - res.send(results[0]).status(200) - } catch (error) { - console.error(error) - res.status(500).send('Internal Server Error') - } -}) - -export default router diff --git a/frontend/app/api/planner/boards/[id]/route.ts b/frontend/app/api/planner/boards/[id]/route.ts new file mode 100644 index 0000000..bf1063c --- /dev/null +++ b/frontend/app/api/planner/boards/[id]/route.ts @@ -0,0 +1,43 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const PATCH = withMiddleware(async (req: ExtendedNextRequest, { params }: { params: Params }) => { + const { id } = params + const { userId } = req + const { newName } = await req.json() + try { + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`boards.${id}.name`]: newName, + }, + } + ) + return NextResponse.json({ status: 200, message: 'Board name changed successfully' }) + } catch (error) { + return NextResponse.json({ status: 500, error: 'Internal Server Error' }) + } +}) + +export const DELETE = withMiddleware(async (req: ExtendedNextRequest, { params }: { params: Params }) => { + const { userId } = req + const { id } = params + try { + await Planner.updateOne( + { clerkUserId: userId }, + { + $pull: { + boardOrder: id, + }, + $unset: { + [`boards.${id}`]: '', + }, + } + ) + return NextResponse.json({ status: 204, message: 'Board deleted successfully' }) + } catch (error) { + return NextResponse.json({ status: 500, error: 'Internal Server Error' }) + } +}) diff --git a/frontend/app/api/planner/boards/route.ts b/frontend/app/api/planner/boards/route.ts new file mode 100644 index 0000000..fc69a4d --- /dev/null +++ b/frontend/app/api/planner/boards/route.ts @@ -0,0 +1,30 @@ +import { ExtendedNextRequest, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const POST = withMiddleware(async (req: ExtendedNextRequest) => { + const { userId } = req + const { boardId, boardName, unassignedCategoryDetails } = await req.json() + try { + await Planner.updateMany( + { clerkUserId: userId }, + { + $push: { + boardOrder: boardId, + }, + $set: { + [`boards.${boardId}`]: { + id: boardId, + name: boardName, + columns: [], + categories: [unassignedCategoryDetails.id], + }, + [`categories.${unassignedCategoryDetails.id}`]: unassignedCategoryDetails, + }, + } + ) + return NextResponse.json({ status: 201, message: 'Board added successfully' }) + } catch (error) { + return NextResponse.json({ status: 500, error: 'Internal Server Error' }) + } +}) diff --git a/frontend/app/api/planner/route.ts b/frontend/app/api/planner/route.ts index d0a935b..f5561c5 100644 --- a/frontend/app/api/planner/route.ts +++ b/frontend/app/api/planner/route.ts @@ -1,20 +1,11 @@ -import dbConnect from '@/lib/dbConnect' +import { ExtendedNextRequest, withMiddleware } from '@/lib/middleware' import Planner from '@/models/Planner' -import { auth } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' -export async function GET(req: Request) { - await dbConnect() - - const { userId } = auth() - - if (!userId) { - return Response.json({ status: 401, error: 'Unauthorized' }) - } - +export const GET = withMiddleware(async (req: ExtendedNextRequest) => { + const { userId } = req let user = await Planner.findOne({ clerkUserId: userId }).lean() if (!user) { - // If user doesn't exist, create a new one user = new Planner({ clerkUserId: userId, boardOrder: [], @@ -28,4 +19,4 @@ export async function GET(req: Request) { user = user.toObject() } return NextResponse.json(user) -} +}) diff --git a/frontend/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts b/frontend/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts index fa1a003..8c14bf9 100644 --- a/frontend/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts +++ b/frontend/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts @@ -25,7 +25,7 @@ export const addNewBoardToPlanner = async ( const token = await getToken() axios .post( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards`, + '/api/planner/boards', { boardId, boardName, diff --git a/frontend/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts b/frontend/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts index b96dc26..a7dd720 100644 --- a/frontend/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts +++ b/frontend/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts @@ -17,7 +17,7 @@ export const changeBoardInfo = async ( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${boardId}`, + `/api/planner/boards/${boardId}`, { newName, }, diff --git a/frontend/lib/middleware.ts b/frontend/lib/middleware.ts new file mode 100644 index 0000000..849fead --- /dev/null +++ b/frontend/lib/middleware.ts @@ -0,0 +1,41 @@ +// utils/middleware.ts +import dbConnect from '@/lib/dbConnect' +import { auth } from '@clerk/nextjs/server' +import { NextRequest, NextResponse } from 'next/server' + +export interface ExtendedNextRequest extends NextRequest { + userId?: string +} + +export interface Params { + id: string +} + +export interface ExtendedNextContext { + params: Params +} + +type Handler = (req: ExtendedNextRequest, context: ExtendedNextContext) => Promise + +export function withDbConnect(handler: Handler): Handler { + return async (req, context) => { + await dbConnect() + return handler(req, context) + } +} + +export function withAuth(handler: Handler): Handler { + return async (req, context) => { + const authObj = auth() + const { userId } = authObj + if (!userId) { + return NextResponse.json({ status: 401, error: 'Unauthorized' }) + } + req.userId = userId + return handler(req, context) + } +} + +export function withMiddleware(handler: Handler): Handler { + return withAuth(withDbConnect(handler)) +} From 81f5ecf12608aa60ec1d40e30ab8f024e5436390 Mon Sep 17 00:00:00 2001 From: Faaez Date: Wed, 10 Jul 2024 00:52:39 -0500 Subject: [PATCH 3/6] Move error handling to middleware --- frontend/app/api/planner/boards/[id]/route.ts | 50 ++++++++----------- frontend/app/api/planner/boards/route.ts | 38 +++++++------- frontend/lib/middleware.ts | 24 ++++++--- 3 files changed, 54 insertions(+), 58 deletions(-) diff --git a/frontend/app/api/planner/boards/[id]/route.ts b/frontend/app/api/planner/boards/[id]/route.ts index bf1063c..662dce5 100644 --- a/frontend/app/api/planner/boards/[id]/route.ts +++ b/frontend/app/api/planner/boards/[id]/route.ts @@ -6,38 +6,30 @@ export const PATCH = withMiddleware(async (req: ExtendedNextRequest, { params }: const { id } = params const { userId } = req const { newName } = await req.json() - try { - await Planner.updateOne( - { clerkUserId: userId }, - { - $set: { - [`boards.${id}.name`]: newName, - }, - } - ) - return NextResponse.json({ status: 200, message: 'Board name changed successfully' }) - } catch (error) { - return NextResponse.json({ status: 500, error: 'Internal Server Error' }) - } + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`boards.${id}.name`]: newName, + }, + } + ) + return NextResponse.json({ status: 200, message: 'Board name changed successfully' }) }) export const DELETE = withMiddleware(async (req: ExtendedNextRequest, { params }: { params: Params }) => { const { userId } = req const { id } = params - try { - await Planner.updateOne( - { clerkUserId: userId }, - { - $pull: { - boardOrder: id, - }, - $unset: { - [`boards.${id}`]: '', - }, - } - ) - return NextResponse.json({ status: 204, message: 'Board deleted successfully' }) - } catch (error) { - return NextResponse.json({ status: 500, error: 'Internal Server Error' }) - } + await Planner.updateOne( + { clerkUserId: userId }, + { + $pull: { + boardOrder: id, + }, + $unset: { + [`boards.${id}`]: '', + }, + } + ) + return NextResponse.json({ status: 204, message: 'Board deleted successfully' }) }) diff --git a/frontend/app/api/planner/boards/route.ts b/frontend/app/api/planner/boards/route.ts index fc69a4d..1f6c79a 100644 --- a/frontend/app/api/planner/boards/route.ts +++ b/frontend/app/api/planner/boards/route.ts @@ -5,26 +5,22 @@ import { NextResponse } from 'next/server' export const POST = withMiddleware(async (req: ExtendedNextRequest) => { const { userId } = req const { boardId, boardName, unassignedCategoryDetails } = await req.json() - try { - await Planner.updateMany( - { clerkUserId: userId }, - { - $push: { - boardOrder: boardId, + await Planner.updateMany( + { clerkUserId: userId }, + { + $push: { + boardOrder: boardId, + }, + $set: { + [`boards.${boardId}`]: { + id: boardId, + name: boardName, + columns: [], + categories: [unassignedCategoryDetails.id], }, - $set: { - [`boards.${boardId}`]: { - id: boardId, - name: boardName, - columns: [], - categories: [unassignedCategoryDetails.id], - }, - [`categories.${unassignedCategoryDetails.id}`]: unassignedCategoryDetails, - }, - } - ) - return NextResponse.json({ status: 201, message: 'Board added successfully' }) - } catch (error) { - return NextResponse.json({ status: 500, error: 'Internal Server Error' }) - } + [`categories.${unassignedCategoryDetails.id}`]: unassignedCategoryDetails, + }, + } + ) + return NextResponse.json({ status: 201, message: 'Board added successfully' }) }) diff --git a/frontend/lib/middleware.ts b/frontend/lib/middleware.ts index 849fead..200b9f7 100644 --- a/frontend/lib/middleware.ts +++ b/frontend/lib/middleware.ts @@ -19,20 +19,28 @@ type Handler = (req: ExtendedNextRequest, context: ExtendedNextContext) => Promi export function withDbConnect(handler: Handler): Handler { return async (req, context) => { - await dbConnect() - return handler(req, context) + try { + await dbConnect() + return handler(req, context) + } catch (error) { + return NextResponse.json({ status: 500, error: 'Internal Server Error' }) + } } } export function withAuth(handler: Handler): Handler { return async (req, context) => { - const authObj = auth() - const { userId } = authObj - if (!userId) { - return NextResponse.json({ status: 401, error: 'Unauthorized' }) + try { + const authObj = auth() + const { userId } = authObj + if (!userId) { + return NextResponse.json({ status: 401, error: 'Unauthorized' }) + } + req.userId = userId + return handler(req, context) + } catch (error) { + return NextResponse.json({ status: 500, error: 'Internal Server Error' }) } - req.userId = userId - return handler(req, context) } } From e298852f0dc4682181c9fc3ceb89368aaeac3854 Mon Sep 17 00:00:00 2001 From: Faaez Date: Wed, 10 Jul 2024 10:44:27 -0500 Subject: [PATCH 4/6] Add card routes --- backend/index.mjs | 4 +- backend/routes/planner/boards.mjs | 26 ---- backend/routes/planner/cards.mjs | 139 ------------------ .../boards/{[id] => [boardId]}/route.ts | 14 +- frontend/app/api/planner/boards/route.ts | 2 +- .../api/planner/cards/[cardId]/move/route.ts | 31 ++++ .../app/api/planner/cards/[cardId]/route.ts | 30 ++++ .../[columnId]/cards/[cardId]/route.ts | 19 +++ .../columns/[columnId]/cards/reorder/route.ts | 22 +++ .../planner/columns/[columnId]/cards/route.ts | 22 +++ .../cardUtils/addNewCardToColumn.ts | 2 +- .../cardUtils/changeCardCategory.ts | 4 +- .../cardUtils/changeCardCheckedStatus.ts | 4 +- .../cardUtils/changeCardContent.ts | 4 +- .../plannerUtils/cardUtils/changeCardTitle.ts | 4 +- .../cardUtils/moveCardAcrossColumns.ts | 2 +- .../cardUtils/moveCardWithinColumn.ts | 2 +- frontend/lib/middleware.ts | 4 +- 18 files changed, 147 insertions(+), 188 deletions(-) delete mode 100644 backend/routes/planner/boards.mjs delete mode 100644 backend/routes/planner/cards.mjs rename frontend/app/api/planner/boards/{[id] => [boardId]}/route.ts (68%) create mode 100644 frontend/app/api/planner/cards/[cardId]/move/route.ts create mode 100644 frontend/app/api/planner/cards/[cardId]/route.ts create mode 100644 frontend/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts create mode 100644 frontend/app/api/planner/columns/[columnId]/cards/reorder/route.ts create mode 100644 frontend/app/api/planner/columns/[columnId]/cards/route.ts diff --git a/backend/index.mjs b/backend/index.mjs index 7b6efde..c0db1c0 100644 --- a/backend/index.mjs +++ b/backend/index.mjs @@ -2,8 +2,6 @@ import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node' import cors from 'cors' import express from 'express' import './loadEnvironment.mjs' -import boards from './routes/planner/boards.mjs' -import cards from './routes/planner/cards.mjs' import categories from './routes/planner/categories.mjs' import columns from './routes/planner/columns.mjs' import subtasks from './routes/planner/subtasks.mjs' @@ -27,7 +25,7 @@ app.use(express.json()) app.use(ClerkExpressRequireAuth()) -app.use('/', [boards, columns, cards, subtasks, categories]) +app.use('/', [columns, subtasks, categories]) // Global error handling app.use((err, _req, res, next) => { diff --git a/backend/routes/planner/boards.mjs b/backend/routes/planner/boards.mjs deleted file mode 100644 index a69c4a6..0000000 --- a/backend/routes/planner/boards.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import express from 'express' -import db from '../../db/conn.mjs' -import { errorHandler } from '../../middleware/index.mjs' - -const router = express.Router() - -const deleteBoard = async (req, res) => { - const userId = req.auth.userId - const { boardId } = req.params - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $pull: { - boardOrder: boardId, - }, - $unset: { - [`boards.${boardId}`]: '', - }, - } - ) - res.status(204).end() -} - -router.delete('/planner/boards/:boardId', errorHandler(deleteBoard)) - -export default router diff --git a/backend/routes/planner/cards.mjs b/backend/routes/planner/cards.mjs deleted file mode 100644 index 4557ccb..0000000 --- a/backend/routes/planner/cards.mjs +++ /dev/null @@ -1,139 +0,0 @@ -import express from 'express' -import db from '../../db/conn.mjs' -import { errorHandler } from '../../middleware/index.mjs' - -const router = express.Router() - -const addNewCardToColumn = async (req, res) => { - const userId = req.auth.userId - const { columnId } = req.params - const { newTaskCardDetails: newCard, updatedTaskCards } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`columns.${columnId}.taskCards`]: updatedTaskCards, - [`taskCards.${newCard.id}`]: newCard, - }, - } - ) - res.status(201).end() -} - -const changeCardCheckedStatus = async (req, res) => { - const userId = req.auth.userId - const { taskCardId } = req.params - const { isChecked } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`taskCards.${taskCardId}.checked`]: isChecked, - }, - } - ) - res.status(204).end() -} - -const changeCardTitle = async (req, res) => { - const userId = req.auth.userId - const { taskCardId } = req.params - const { newTitle } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`taskCards.${taskCardId}.title`]: newTitle, - }, - } - ) - res.status(204).end() -} - -const changeCardContent = async (req, res) => { - const userId = req.auth.userId - const { taskCardId } = req.params - const { newContent } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`taskCards.${taskCardId}.content`]: newContent, - }, - } - ) - res.status(204).end() -} - -const changeCardCategory = async (req, res) => { - const userId = req.auth.userId - const { taskCardId } = req.params - const { newCategoryId } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`taskCards.${taskCardId}.category`]: newCategoryId, - }, - } - ) - res.status(204).end() -} - -const moveCardWithinColumn = async (req, res) => { - const userId = req.auth.userId - const { columnId } = req.params - const { reorderedCardIds } = req.body - await db - .collection('planner') - .updateOne( - { clerkUserId: userId, [`columns.${columnId}.id`]: columnId }, - { $set: { [`columns.${columnId}.taskCards`]: reorderedCardIds } } - ) - res.status(204).end() -} - -// Function to move a card across different columns -const moveCardAcrossColumns = async (req, res) => { - const userId = req.auth.userId - const { sourceColumnId, destColumnId, sourceColumnTaskCardIds, destColumnTaskCardIds } = req.body - await db.collection('planner').updateMany( - { - clerkUserId: userId, - $or: [{ [`columns.${sourceColumnId}.id`]: sourceColumnId }, { [`columns.${destColumnId}.id`]: destColumnId }], - }, - { - $set: { - [`columns.${sourceColumnId}.taskCards`]: sourceColumnTaskCardIds, - [`columns.${destColumnId}.taskCards`]: destColumnTaskCardIds, - }, - } - ) - res.status(204).end() -} - -const deleteCard = async (req, res) => { - const userId = req.auth.userId - const { columnId, taskCardId } = req.params - // Remove the task from the taskCards object using $unset - await db.collection('planner').updateOne({ clerkUserId: userId }, { $unset: { [`taskCards.${taskCardId}`]: '' } }) - // Remove the task from the taskCards list within the specified column using $pull - await db - .collection('planner') - .updateOne( - { clerkUserId: userId, [`columns.${columnId}.id`]: columnId }, - { $pull: { [`columns.${columnId}.taskCards`]: taskCardId } } - ) - res.status(204).end() -} - -router.post('/planner/columns/:columnId/cards', errorHandler(addNewCardToColumn)) -router.patch('/planner/cards/:taskCardId/checked', errorHandler(changeCardCheckedStatus)) -router.patch('/planner/cards/:taskCardId/title', errorHandler(changeCardTitle)) -router.patch('/planner/cards/:taskCardId/content', errorHandler(changeCardContent)) -router.patch('/planner/cards/:taskCardId/category', errorHandler(changeCardCategory)) -router.patch('/planner/columns/:columnId/cards/move', errorHandler(moveCardWithinColumn)) // CHANGE -router.patch('/planner/columns/move', errorHandler(moveCardAcrossColumns)) -router.delete('/planner/columns/:columnId/cards/:taskCardId/delete', errorHandler(deleteCard)) - -export default router diff --git a/frontend/app/api/planner/boards/[id]/route.ts b/frontend/app/api/planner/boards/[boardId]/route.ts similarity index 68% rename from frontend/app/api/planner/boards/[id]/route.ts rename to frontend/app/api/planner/boards/[boardId]/route.ts index 662dce5..dae822d 100644 --- a/frontend/app/api/planner/boards/[id]/route.ts +++ b/frontend/app/api/planner/boards/[boardId]/route.ts @@ -3,33 +3,33 @@ import Planner from '@/models/Planner' import { NextResponse } from 'next/server' export const PATCH = withMiddleware(async (req: ExtendedNextRequest, { params }: { params: Params }) => { - const { id } = params const { userId } = req + const { boardId } = params const { newName } = await req.json() await Planner.updateOne( { clerkUserId: userId }, { $set: { - [`boards.${id}.name`]: newName, + [`boards.${boardId}.name`]: newName, }, } ) - return NextResponse.json({ status: 200, message: 'Board name changed successfully' }) + return NextResponse.json({ status: 200 }) }) export const DELETE = withMiddleware(async (req: ExtendedNextRequest, { params }: { params: Params }) => { const { userId } = req - const { id } = params + const { boardId } = params await Planner.updateOne( { clerkUserId: userId }, { $pull: { - boardOrder: id, + boardOrder: boardId, }, $unset: { - [`boards.${id}`]: '', + [`boards.${boardId}`]: '', }, } ) - return NextResponse.json({ status: 204, message: 'Board deleted successfully' }) + return NextResponse.json({ status: 204 }) }) diff --git a/frontend/app/api/planner/boards/route.ts b/frontend/app/api/planner/boards/route.ts index 1f6c79a..baca422 100644 --- a/frontend/app/api/planner/boards/route.ts +++ b/frontend/app/api/planner/boards/route.ts @@ -22,5 +22,5 @@ export const POST = withMiddleware(async (req: ExtendedNextRequest) => { }, } ) - return NextResponse.json({ status: 201, message: 'Board added successfully' }) + return NextResponse.json({ status: 201 }) }) diff --git a/frontend/app/api/planner/cards/[cardId]/move/route.ts b/frontend/app/api/planner/cards/[cardId]/move/route.ts new file mode 100644 index 0000000..ad5b2b1 --- /dev/null +++ b/frontend/app/api/planner/cards/[cardId]/move/route.ts @@ -0,0 +1,31 @@ +import { ExtendedNextRequest, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface MoveCardRequestBody { + sourceColumnId: string + destColumnId: string + sourceColumnTaskCardIds: string[] + destColumnTaskCardIds: string[] +} + +export const PATCH = withMiddleware(async (req: ExtendedNextRequest): Promise => { + const { userId } = req + const { sourceColumnId, destColumnId, sourceColumnTaskCardIds, destColumnTaskCardIds }: MoveCardRequestBody = + await req.json() + + await Planner.updateMany( + { + clerkUserId: userId, + $or: [{ [`columns.${sourceColumnId}.id`]: sourceColumnId }, { [`columns.${destColumnId}.id`]: destColumnId }], + }, + { + $set: { + [`columns.${sourceColumnId}.taskCards`]: sourceColumnTaskCardIds, + [`columns.${destColumnId}.taskCards`]: destColumnTaskCardIds, + }, + } + ) + + return NextResponse.json({ status: 204 }) +}) diff --git a/frontend/app/api/planner/cards/[cardId]/route.ts b/frontend/app/api/planner/cards/[cardId]/route.ts new file mode 100644 index 0000000..9dc7063 --- /dev/null +++ b/frontend/app/api/planner/cards/[cardId]/route.ts @@ -0,0 +1,30 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface CardModificationRequestBody { + title?: string + content?: string + checked?: boolean + category?: string +} + +export const PATCH = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { cardId } = params + const body: CardModificationRequestBody = await req.json() + + const [key, value] = Object.entries(body)[0] + const updateField = { [`taskCards.${cardId}.${key}`]: value } + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: updateField, + } + ) + + return NextResponse.json({ status: 200 }) + } +) diff --git a/frontend/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts b/frontend/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts new file mode 100644 index 0000000..6dd626d --- /dev/null +++ b/frontend/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts @@ -0,0 +1,19 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const DELETE = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { columnId, cardId } = params + + await Planner.updateOne({ clerkUserId: userId }, { $unset: { [`taskCards.${cardId}`]: '' } }) + + await Planner.updateOne( + { clerkUserId: userId, [`columns.${columnId}.id`]: columnId }, + { $pull: { [`columns.${columnId}.taskCards`]: cardId } } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/columns/[columnId]/cards/reorder/route.ts b/frontend/app/api/planner/columns/[columnId]/cards/reorder/route.ts new file mode 100644 index 0000000..fa52950 --- /dev/null +++ b/frontend/app/api/planner/columns/[columnId]/cards/reorder/route.ts @@ -0,0 +1,22 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface ReorderCardsRequestBody { + reorderedCardIds: string[] +} + +export const PATCH = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { columnId } = params + const { reorderedCardIds }: ReorderCardsRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId, [`columns.${columnId}.id`]: columnId }, + { $set: { [`columns.${columnId}.taskCards`]: reorderedCardIds } } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/columns/[columnId]/cards/route.ts b/frontend/app/api/planner/columns/[columnId]/cards/route.ts new file mode 100644 index 0000000..d8b3470 --- /dev/null +++ b/frontend/app/api/planner/columns/[columnId]/cards/route.ts @@ -0,0 +1,22 @@ +// pages/api/planner/columns/[columnId]/cards/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const POST = withMiddleware(async (req: ExtendedNextRequest, { params }: { params: Params }) => { + const { userId } = req + const { columnId } = params + const { newTaskCardDetails: newCard, updatedTaskCards } = await req.json() + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`columns.${columnId}.taskCards`]: updatedTaskCards, + [`taskCards.${newCard.id}`]: newCard, + }, + } + ) + + return NextResponse.json({ status: 201 }) +}) diff --git a/frontend/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts b/frontend/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts index 59f6968..85eb3ef 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts @@ -34,7 +34,7 @@ export const addNewCardToColumn = async ( const token = await getToken() axios .post( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/columns/${column.id}/cards`, + `/api/planner/columns/${column.id}/cards`, { newTaskCardDetails, updatedTaskCards, diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardCategory.ts b/frontend/app/utils/plannerUtils/cardUtils/changeCardCategory.ts index 75fa51e..f8e0b97 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/changeCardCategory.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/changeCardCategory.ts @@ -17,9 +17,9 @@ export default async function changeCardCategory( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCardId}/category`, + `/api/planner/cards/${taskCardId}`, { - newCategoryId, + category: newCategoryId, }, { headers: { diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts b/frontend/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts index 244a3db..2b3a70c 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts @@ -17,9 +17,9 @@ export default async function changeCardCheckedStatus( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCardId}/checked`, + `/api/planner/cards/${taskCardId}`, { - isChecked, + checked: isChecked, }, { headers: { diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardContent.ts b/frontend/app/utils/plannerUtils/cardUtils/changeCardContent.ts index 14d4dc4..b139b60 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/changeCardContent.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/changeCardContent.ts @@ -7,9 +7,9 @@ const debouncedApiCall = debounce( async (taskCardId: string, newContent: string, dispatch: Dispatch, token: string | null) => { axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCardId}/content`, + `/api/planner/cards/${taskCardId}`, { - newContent, + content: newContent, }, { headers: { diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardTitle.ts b/frontend/app/utils/plannerUtils/cardUtils/changeCardTitle.ts index b7d6346..bb3851a 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/changeCardTitle.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/changeCardTitle.ts @@ -7,9 +7,9 @@ const debouncedApiCall = debounce( async (taskCardId: string, newTitle: string, dispatch: Dispatch, token: string | null) => { axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCardId}/title`, + `/api/planner/cards/${taskCardId}`, { - newTitle, + title: newTitle, }, { headers: { diff --git a/frontend/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts b/frontend/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts index 222785c..9c9a71f 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts @@ -32,7 +32,7 @@ export default async function moveCardAcrossColumns( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/columns/move`, + `/api/planner/cards/${draggedCardId}/move`, { sourceColumnId, destColumnId, diff --git a/frontend/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts b/frontend/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts index 700aede..8a4712e 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts @@ -26,7 +26,7 @@ export default async function moveCardWithinColumn( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/columns/${columnId}/cards/move`, + `/api/planner/columns/${columnId}/cards/reorder`, { reorderedCardIds }, { headers: { diff --git a/frontend/lib/middleware.ts b/frontend/lib/middleware.ts index 200b9f7..932a7ce 100644 --- a/frontend/lib/middleware.ts +++ b/frontend/lib/middleware.ts @@ -8,7 +8,9 @@ export interface ExtendedNextRequest extends NextRequest { } export interface Params { - id: string + boardId?: string + columnId?: string + cardId?: string } export interface ExtendedNextContext { From fffa6f0d23d9ae1bf857144da25886e5aaeb17d9 Mon Sep 17 00:00:00 2001 From: Faaez Date: Wed, 10 Jul 2024 11:47:50 -0500 Subject: [PATCH 5/6] Complete all other routes --- backend/index.mjs | 3 +- backend/routes/planner/categories.mjs | 66 ------------------- .../categories/[categoryId]/route.ts | 29 ++++++++ .../boards/[boardId]/categories/route.ts | 32 +++++++++ .../[boardId]/columns/[columnId]/route.ts | 25 +++++++ .../boards/[boardId]/columns/reorder/route.ts | 22 +++++++ .../planner/boards/[boardId]/columns/route.ts | 29 ++++++++ .../app/api/planner/cards/[cardId]/route.ts | 2 +- .../[cardId]/subtasks/[subTaskId]/route.ts | 21 ++++++ .../cards/[cardId]/subtasks/move/route.ts | 23 +++++++ .../planner/cards/[cardId]/subtasks/route.ts | 29 ++++++++ .../planner/categories/[categoryId]/route.ts | 29 ++++++++ .../api/planner/subtasks/[subTaskId]/route.ts | 28 ++++++++ .../plannerUtils/boardUtils/deleteBoard.ts | 2 +- .../plannerUtils/cardUtils/deleteCard.ts | 4 +- .../categoryUtils/addNewCategory.ts | 2 +- .../categoryUtils/changeCategoryInfo.ts | 2 +- .../categoryUtils/deleteCategory.ts | 2 +- .../plannerUtils/columnUtils/addNewColumn.ts | 2 +- .../columnUtils/changeColumnName.ts | 2 +- .../columnUtils/changeColumnOrder.ts | 2 +- .../plannerUtils/columnUtils/deleteColumn.ts | 2 +- .../subTaskUtils/addNewSubTaskToCard.ts | 2 +- .../changeSubTaskCheckedStatus.ts | 4 +- .../subTaskUtils/changeSubTaskTitle.ts | 4 +- .../subTaskUtils/deleteSubTask.ts | 2 +- .../subTaskUtils/reorderSubtasks.ts | 2 +- frontend/lib/middleware.ts | 2 + 28 files changed, 288 insertions(+), 86 deletions(-) delete mode 100644 backend/routes/planner/categories.mjs create mode 100644 frontend/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts create mode 100644 frontend/app/api/planner/boards/[boardId]/categories/route.ts create mode 100644 frontend/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts create mode 100644 frontend/app/api/planner/boards/[boardId]/columns/reorder/route.ts create mode 100644 frontend/app/api/planner/boards/[boardId]/columns/route.ts create mode 100644 frontend/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts create mode 100644 frontend/app/api/planner/cards/[cardId]/subtasks/move/route.ts create mode 100644 frontend/app/api/planner/cards/[cardId]/subtasks/route.ts create mode 100644 frontend/app/api/planner/categories/[categoryId]/route.ts create mode 100644 frontend/app/api/planner/subtasks/[subTaskId]/route.ts diff --git a/backend/index.mjs b/backend/index.mjs index c0db1c0..38d3c01 100644 --- a/backend/index.mjs +++ b/backend/index.mjs @@ -2,7 +2,6 @@ import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node' import cors from 'cors' import express from 'express' import './loadEnvironment.mjs' -import categories from './routes/planner/categories.mjs' import columns from './routes/planner/columns.mjs' import subtasks from './routes/planner/subtasks.mjs' @@ -25,7 +24,7 @@ app.use(express.json()) app.use(ClerkExpressRequireAuth()) -app.use('/', [columns, subtasks, categories]) +app.use('/', [columns, subtasks]) // Global error handling app.use((err, _req, res, next) => { diff --git a/backend/routes/planner/categories.mjs b/backend/routes/planner/categories.mjs deleted file mode 100644 index 3587c91..0000000 --- a/backend/routes/planner/categories.mjs +++ /dev/null @@ -1,66 +0,0 @@ -import express from 'express' -import db from '../../db/conn.mjs' -import { errorHandler } from '../../middleware/index.mjs' - -const router = express.Router() - -const addNewCategory = async (req, res) => { - const userId = req.auth.userId - const { boardId } = req.params - const { newCategoryDetails } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`categories.${newCategoryDetails.id}`]: newCategoryDetails, - }, - } - ) - await db - .collection('planner') - .updateOne({ clerkUserId: userId }, { $push: { [`boards.${boardId}.categories`]: newCategoryDetails.id } }) - res.status(201).end() -} - -const changeCategoryInfo = async (req, res) => { - const userId = req.auth.userId - const { categoryId } = req.params - const { newName, newColor } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`categories.${categoryId}.name`]: newName, - [`categories.${categoryId}.color`]: newColor, - }, - } - ) - res.status(201).end() -} - -const deleteCategory = async (req, res) => { - const userId = req.auth.userId - const { boardId, categoryId } = req.params - const docs = await db.collection('planner').findOne({ clerkUserId: userId }) - const updateObject = {} - for (const [key, value] of Object.entries(docs.taskCards)) { - if (value.category === categoryId) { - updateObject[`taskCards.${key}.category`] = 'unassigned' - } - } - if (Object.keys(updateObject).length === 0) { - return - } - await db.collection('planner').updateOne({ clerkUserId: userId }, { $set: updateObject }) - await db.collection('planner').updateOne({ clerkUserId: userId }, { $unset: { [`categories.${categoryId}`]: '' } }) - await db - .collection('planner') - .updateOne({ clerkUserId: userId }, { $pull: { [`boards.${boardId}.categories`]: categoryId } }) - res.status(204).end() -} - -router.post('/planner/boards/:boardId/categories', errorHandler(addNewCategory)) -router.patch('/planner/categories/:categoryId', errorHandler(changeCategoryInfo)) -router.delete('/planner/boards/:boardId/categories/:categoryId', errorHandler(deleteCategory)) - -export default router diff --git a/frontend/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts b/frontend/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts new file mode 100644 index 0000000..807ec4a --- /dev/null +++ b/frontend/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts @@ -0,0 +1,29 @@ +// pages/api/planner/boards/[boardId]/categories/[categoryId]/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const DELETE = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { boardId, categoryId } = params + + const docs = await Planner.findOne({ clerkUserId: userId }) + const updateObject: any = {} + + for (const [key, value] of Object.entries(docs.taskCards)) { + if ((value as any).category === categoryId) { + updateObject[`taskCards.${key}.category`] = 'unassigned' + } + } + + if (Object.keys(updateObject).length > 0) { + await Planner.updateOne({ clerkUserId: userId }, { $set: updateObject }) + } + + await Planner.updateOne({ clerkUserId: userId }, { $unset: { [`categories.${categoryId}`]: '' } }) + await Planner.updateOne({ clerkUserId: userId }, { $pull: { [`boards.${boardId}.categories`]: categoryId } }) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/boards/[boardId]/categories/route.ts b/frontend/app/api/planner/boards/[boardId]/categories/route.ts new file mode 100644 index 0000000..529053d --- /dev/null +++ b/frontend/app/api/planner/boards/[boardId]/categories/route.ts @@ -0,0 +1,32 @@ +// pages/api/planner/boards/[boardId]/categories/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface AddNewCategoryRequestBody { + newCategoryDetails: { id: string; [key: string]: any } +} + +export const POST = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { boardId } = params + const { newCategoryDetails }: AddNewCategoryRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`categories.${newCategoryDetails.id}`]: newCategoryDetails, + }, + } + ) + + await Planner.updateOne( + { clerkUserId: userId }, + { $push: { [`boards.${boardId}.categories`]: newCategoryDetails.id } } + ) + + return NextResponse.json({ status: 201 }) + } +) diff --git a/frontend/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts b/frontend/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts new file mode 100644 index 0000000..b5a3e38 --- /dev/null +++ b/frontend/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts @@ -0,0 +1,25 @@ +// pages/api/planner/boards/[boardId]/columns/[columnId]/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const DELETE = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { boardId, columnId } = params + + await Planner.updateOne( + { clerkUserId: userId }, + { + $pull: { + [`boards.${boardId}.columns`]: columnId, + }, + $unset: { + [`columns.${columnId}`]: 1, + }, + } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/boards/[boardId]/columns/reorder/route.ts b/frontend/app/api/planner/boards/[boardId]/columns/reorder/route.ts new file mode 100644 index 0000000..6dd36d3 --- /dev/null +++ b/frontend/app/api/planner/boards/[boardId]/columns/reorder/route.ts @@ -0,0 +1,22 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface ChangeColumnOrderRequestBody { + newColumnOrder: string[] +} + +export const PATCH = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { boardId } = params + const { newColumnOrder }: ChangeColumnOrderRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId, [`boards.${boardId}.id`]: boardId }, + { $set: { [`boards.${boardId}.columns`]: newColumnOrder } } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/boards/[boardId]/columns/route.ts b/frontend/app/api/planner/boards/[boardId]/columns/route.ts new file mode 100644 index 0000000..9802a9b --- /dev/null +++ b/frontend/app/api/planner/boards/[boardId]/columns/route.ts @@ -0,0 +1,29 @@ +// pages/api/planner/boards/[boardId]/columns/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface AddNewColumnRequestBody { + newColumnDetails: { id: string; [key: string]: any } + updatedColumns: string[] +} + +export const POST = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { boardId } = params + const { newColumnDetails, updatedColumns }: AddNewColumnRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`boards.${boardId}.columns`]: updatedColumns, + [`columns.${newColumnDetails.id}`]: newColumnDetails, + }, + } + ) + + return NextResponse.json({ status: 201 }) + } +) diff --git a/frontend/app/api/planner/cards/[cardId]/route.ts b/frontend/app/api/planner/cards/[cardId]/route.ts index 9dc7063..c8cfb2a 100644 --- a/frontend/app/api/planner/cards/[cardId]/route.ts +++ b/frontend/app/api/planner/cards/[cardId]/route.ts @@ -25,6 +25,6 @@ export const PATCH = withMiddleware( } ) - return NextResponse.json({ status: 200 }) + return NextResponse.json({ status: 204 }) } ) diff --git a/frontend/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts b/frontend/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts new file mode 100644 index 0000000..ad83065 --- /dev/null +++ b/frontend/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts @@ -0,0 +1,21 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +export const DELETE = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { cardId, subTaskId } = params + + // Remove the subtask from the subtask object using $unset + await Planner.updateOne({ clerkUserId: userId }, { $unset: { [`subTasks.${subTaskId}`]: '' } }) + + // Remove the subtask from the subtask list within the specified taskcard using $pull + await Planner.updateOne( + { clerkUserId: userId, [`taskCards.${cardId}.id`]: cardId }, + { $pull: { [`taskCards.${cardId}.subTasks`]: subTaskId } } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/cards/[cardId]/subtasks/move/route.ts b/frontend/app/api/planner/cards/[cardId]/subtasks/move/route.ts new file mode 100644 index 0000000..e9d5a61 --- /dev/null +++ b/frontend/app/api/planner/cards/[cardId]/subtasks/move/route.ts @@ -0,0 +1,23 @@ +// pages/api/planner/cards/[taskCardId]/subtasks/move/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface MoveSubtaskRequestBody { + reorderedSubTasks: string[] +} + +export const PATCH = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { cardId } = params + const { reorderedSubTasks }: MoveSubtaskRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId, [`taskCards.${cardId}.id`]: cardId }, + { $set: { [`taskCards.${cardId}.subTasks`]: reorderedSubTasks } } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/api/planner/cards/[cardId]/subtasks/route.ts b/frontend/app/api/planner/cards/[cardId]/subtasks/route.ts new file mode 100644 index 0000000..de74809 --- /dev/null +++ b/frontend/app/api/planner/cards/[cardId]/subtasks/route.ts @@ -0,0 +1,29 @@ +// pages/api/planner/cards/[taskCardId]/subtasks/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface AddNewSubTaskRequestBody { + newSubTaskDetails: { id: string; [key: string]: any } + newSubTasksOrder: string[] +} + +export const POST = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { cardId } = params + const { newSubTaskDetails, newSubTasksOrder }: AddNewSubTaskRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`taskCards.${cardId}.subTasks`]: newSubTasksOrder, + [`subTasks.${newSubTaskDetails.id}`]: newSubTaskDetails, + }, + } + ) + + return NextResponse.json({ status: 201 }) + } +) diff --git a/frontend/app/api/planner/categories/[categoryId]/route.ts b/frontend/app/api/planner/categories/[categoryId]/route.ts new file mode 100644 index 0000000..a6f161b --- /dev/null +++ b/frontend/app/api/planner/categories/[categoryId]/route.ts @@ -0,0 +1,29 @@ +// pages/api/planner/categories/[categoryId]/route.ts +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface ChangeCategoryInfoRequestBody { + newName: string + newColor: string +} + +export const PATCH = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { categoryId } = params + const { newName, newColor }: ChangeCategoryInfoRequestBody = await req.json() + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: { + [`categories.${categoryId}.name`]: newName, + [`categories.${categoryId}.color`]: newColor, + }, + } + ) + + return NextResponse.json({ status: 201 }) + } +) diff --git a/frontend/app/api/planner/subtasks/[subTaskId]/route.ts b/frontend/app/api/planner/subtasks/[subTaskId]/route.ts new file mode 100644 index 0000000..0133ab6 --- /dev/null +++ b/frontend/app/api/planner/subtasks/[subTaskId]/route.ts @@ -0,0 +1,28 @@ +import { ExtendedNextRequest, Params, withMiddleware } from '@/lib/middleware' +import Planner from '@/models/Planner' +import { NextResponse } from 'next/server' + +interface SubTaskModificationRequestBody { + title?: string + checked?: boolean +} + +export const PATCH = withMiddleware( + async (req: ExtendedNextRequest, { params }: { params: Params }): Promise => { + const { userId } = req + const { subTaskId } = params + const body: SubTaskModificationRequestBody = await req.json() + + const [key, value] = Object.entries(body)[0] + const updateField = { [`subTasks.${subTaskId}.${key}`]: value } + + await Planner.updateOne( + { clerkUserId: userId }, + { + $set: updateField, + } + ) + + return NextResponse.json({ status: 204 }) + } +) diff --git a/frontend/app/utils/plannerUtils/boardUtils/deleteBoard.ts b/frontend/app/utils/plannerUtils/boardUtils/deleteBoard.ts index b680197..d67dc2d 100644 --- a/frontend/app/utils/plannerUtils/boardUtils/deleteBoard.ts +++ b/frontend/app/utils/plannerUtils/boardUtils/deleteBoard.ts @@ -14,7 +14,7 @@ export default async function deleteBoard( }) const token = await getToken() axios - .delete(`${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${boardId}`, { + .delete(`/api/planner/boards/${boardId}`, { headers: { Authorization: `Bearer ${token}`, }, diff --git a/frontend/app/utils/plannerUtils/cardUtils/deleteCard.ts b/frontend/app/utils/plannerUtils/cardUtils/deleteCard.ts index de64928..95aa6a1 100644 --- a/frontend/app/utils/plannerUtils/cardUtils/deleteCard.ts +++ b/frontend/app/utils/plannerUtils/cardUtils/deleteCard.ts @@ -17,7 +17,7 @@ export default async function deleteCard( const token = await getToken() axios - .delete(`${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/columns/${columnId}/cards/${taskCardId}/delete`, { + .delete(`/api/planner/columns/${columnId}/cards/${taskCardId}`, { headers: { Authorization: `Bearer ${token}`, }, @@ -27,4 +27,4 @@ export default async function deleteCard( type: 'backendErrorOccurred', }) }) -} \ No newline at end of file +} diff --git a/frontend/app/utils/plannerUtils/categoryUtils/addNewCategory.ts b/frontend/app/utils/plannerUtils/categoryUtils/addNewCategory.ts index e5b37d9..a09f8f1 100644 --- a/frontend/app/utils/plannerUtils/categoryUtils/addNewCategory.ts +++ b/frontend/app/utils/plannerUtils/categoryUtils/addNewCategory.ts @@ -21,7 +21,7 @@ export const addNewCategory = async ( const token = await getToken() axios .post( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${boardId}/categories`, + `/api/planner/boards/${boardId}/categories`, { newCategoryDetails, }, diff --git a/frontend/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts b/frontend/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts index cfb5673..ee850eb 100644 --- a/frontend/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts +++ b/frontend/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts @@ -22,7 +22,7 @@ export const changeCategoryInfo = async ( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/categories/${categoryId}`, + `/api/planner/categories/${categoryId}`, { newName, newColor, diff --git a/frontend/app/utils/plannerUtils/categoryUtils/deleteCategory.ts b/frontend/app/utils/plannerUtils/categoryUtils/deleteCategory.ts index e85aaf2..81ad754 100644 --- a/frontend/app/utils/plannerUtils/categoryUtils/deleteCategory.ts +++ b/frontend/app/utils/plannerUtils/categoryUtils/deleteCategory.ts @@ -16,7 +16,7 @@ export default async function deleteCategory( }) const token = await getToken() axios - .delete(`${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${boardId}/categories/${categoryId}`, { + .delete(`/api/planner/boards/${boardId}/categories/${categoryId}`, { headers: { Authorization: `Bearer ${token}`, }, diff --git a/frontend/app/utils/plannerUtils/columnUtils/addNewColumn.ts b/frontend/app/utils/plannerUtils/columnUtils/addNewColumn.ts index ccbc9d1..cdb569b 100644 --- a/frontend/app/utils/plannerUtils/columnUtils/addNewColumn.ts +++ b/frontend/app/utils/plannerUtils/columnUtils/addNewColumn.ts @@ -27,7 +27,7 @@ export const addNewColumn = async ( const token = await getToken() axios .post( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${board.id}/columns`, + `/api/planner/boards/${board.id}/columns`, { newColumnDetails, updatedColumns, diff --git a/frontend/app/utils/plannerUtils/columnUtils/changeColumnName.ts b/frontend/app/utils/plannerUtils/columnUtils/changeColumnName.ts index ecd4629..8c8abde 100644 --- a/frontend/app/utils/plannerUtils/columnUtils/changeColumnName.ts +++ b/frontend/app/utils/plannerUtils/columnUtils/changeColumnName.ts @@ -17,7 +17,7 @@ export default async function changeColumnName( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/columns/${columnId}`, + `/api/planner/columns/${columnId}`, { newName, }, diff --git a/frontend/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts b/frontend/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts index 840412b..3a55cdc 100644 --- a/frontend/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts +++ b/frontend/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts @@ -24,7 +24,7 @@ export const changeColumnOrder = async ( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${boardId}/columns/reorder`, + `/api/planner/boards/${boardId}/columns/reorder`, { newColumnOrder, }, diff --git a/frontend/app/utils/plannerUtils/columnUtils/deleteColumn.ts b/frontend/app/utils/plannerUtils/columnUtils/deleteColumn.ts index a52dab4..91f23ea 100644 --- a/frontend/app/utils/plannerUtils/columnUtils/deleteColumn.ts +++ b/frontend/app/utils/plannerUtils/columnUtils/deleteColumn.ts @@ -17,7 +17,7 @@ export default async function deleteColumn( const token = await getToken() axios - .delete(`${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/boards/${boardId}/columns/${columnId}/delete`, { + .delete(`/api/planner/boards/${boardId}/columns/${columnId}`, { headers: { Authorization: `Bearer ${token}`, }, diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts b/frontend/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts index f60c8b8..a649f07 100644 --- a/frontend/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts +++ b/frontend/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts @@ -25,7 +25,7 @@ const addNewSubTask = async ( const token = await getToken() axios .post( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCardId}/subtasks`, + `/api/planner/cards/${taskCardId}/subtasks`, { newSubTaskDetails, newSubTasksOrder, diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts b/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts index 7b954be..e5e8b7b 100644 --- a/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts +++ b/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts @@ -17,9 +17,9 @@ export default async function changeSubTaskCheckedStatus( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/subtasks/${subTaskId}/checked`, + `/api/planner/subtasks/${subTaskId}`, { - isChecked, + checked: isChecked, }, { headers: { diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts b/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts index afb1d24..64ff0f0 100644 --- a/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts +++ b/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts @@ -7,9 +7,9 @@ const debouncedApiCall = debounce( async (subTaskId: string, newTitle: string, dispatch: Dispatch, token: string | null) => { axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/subtasks/${subTaskId}/title`, + `/api/planner/subtasks/${subTaskId}`, { - newTitle, + title: newTitle, }, { headers: { diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts b/frontend/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts index b9ab2b8..498bd85 100644 --- a/frontend/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts +++ b/frontend/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts @@ -26,7 +26,7 @@ export default async function deleteSubTask( }) const token = await getToken() axios - .delete(`${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCard.id}/subtasks/${subTaskId}/delete`, { + .delete(`/api/planner/cards/${taskCard.id}/subtasks/${subTaskId}`, { headers: { Authorization: `Bearer ${token}`, }, diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts b/frontend/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts index f7296ac..d098295 100644 --- a/frontend/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts +++ b/frontend/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts @@ -28,7 +28,7 @@ export const reorderSubTasks = async ( const token = await getToken() axios .patch( - `${process.env.NEXT_PUBLIC_BACKEND_URL}/planner/cards/${taskCardId}/subtasks/move`, + `/api/planner/cards/${taskCardId}/subtasks/move`, { reorderedSubTasks, }, diff --git a/frontend/lib/middleware.ts b/frontend/lib/middleware.ts index 932a7ce..2f3a530 100644 --- a/frontend/lib/middleware.ts +++ b/frontend/lib/middleware.ts @@ -11,6 +11,8 @@ export interface Params { boardId?: string columnId?: string cardId?: string + categoryId?: string + subTaskId?: string } export interface ExtendedNextContext { From 2fecfe12bd99addab1d23304ef62764f05ede0ed Mon Sep 17 00:00:00 2001 From: Faaez Date: Wed, 10 Jul 2024 11:51:07 -0500 Subject: [PATCH 6/6] Remove backend folder --- frontend/.eslintrc.json => .eslintrc.json | 0 .../categories/[categoryId]/route.ts | 0 .../boards/[boardId]/categories/route.ts | 0 .../[boardId]/columns/[columnId]/route.ts | 0 .../boards/[boardId]/columns/reorder/route.ts | 0 .../planner/boards/[boardId]/columns/route.ts | 0 .../api/planner/boards/[boardId]/route.ts | 0 .../app => app}/api/planner/boards/route.ts | 0 .../api/planner/cards/[cardId]/move/route.ts | 0 .../api/planner/cards/[cardId]/route.ts | 0 .../[cardId]/subtasks/[subTaskId]/route.ts | 0 .../cards/[cardId]/subtasks/move/route.ts | 0 .../planner/cards/[cardId]/subtasks/route.ts | 0 .../planner/categories/[categoryId]/route.ts | 0 .../[columnId]/cards/[cardId]/route.ts | 0 .../columns/[columnId]/cards/reorder/route.ts | 0 .../planner/columns/[columnId]/cards/route.ts | 0 {frontend/app => app}/api/planner/route.ts | 0 .../api/planner/subtasks/[subTaskId]/route.ts | 0 {frontend/app => app}/favicon.ico | Bin {frontend/app => app}/globals.css | 0 {frontend/app => app}/home/layout.tsx | 0 {frontend/app => app}/home/page.tsx | 0 {frontend/app => app}/layout.tsx | 0 {frontend/app => app}/page.tsx | 0 .../boardUtils/addNewBoardToPlanner.ts | 0 .../boardUtils/changeBoardInfo.ts | 0 .../plannerUtils/boardUtils/deleteBoard.ts | 0 .../cardUtils/addNewCardToColumn.ts | 0 .../cardUtils/changeCardCategory.ts | 0 .../cardUtils/changeCardCheckedStatus.ts | 0 .../cardUtils/changeCardContent.ts | 0 .../plannerUtils/cardUtils/changeCardTitle.ts | 0 .../plannerUtils/cardUtils/deleteCard.ts | 0 .../cardUtils/moveCardAcrossColumns.ts | 0 .../cardUtils/moveCardWithinColumn.ts | 0 .../categoryUtils/addNewCategory.ts | 0 .../categoryUtils/changeCategoryInfo.ts | 0 .../categoryUtils/deleteCategory.ts | 0 .../plannerUtils/columnUtils/addNewColumn.ts | 0 .../columnUtils/changeColumnName.ts | 0 .../columnUtils/changeColumnOrder.ts | 0 .../plannerUtils/columnUtils/deleteColumn.ts | 0 .../utils/plannerUtils/plannerUtils.ts | 0 .../subTaskUtils/addNewSubTaskToCard.ts | 0 .../changeSubTaskCheckedStatus.ts | 0 .../subTaskUtils/changeSubTaskTitle.ts | 0 .../subTaskUtils/deleteSubTask.ts | 0 .../subTaskUtils/reorderSubtasks.ts | 0 .../app => app}/utils/plannerUtils/types.ts | 0 .../fonts/CalSans-SemiBold.woff2 | Bin backend/db/conn.mjs | 14 - backend/index.mjs | 36 - backend/loadEnvironment.mjs | 2 - backend/middleware/index.mjs | 12 - backend/package-lock.json | 1053 ----------------- backend/package.json | 13 - backend/routes/planner/columns.mjs | 73 -- backend/routes/planner/subtasks.mjs | 87 -- frontend/components.json => components.json | 0 .../global/AlertCard/AlertCard.tsx | 0 .../LoadingSpinner/LoadingSpinner.module.css | 0 .../global/LoadingSpinner/LoadingSpinner.tsx | 0 .../global/ModeToggle.tsx | 0 .../global/Navbar/NavLinks.tsx | 0 .../global/Navbar/NewsAlertBanner.tsx | 0 .../global/Navbar/SiteLogo.tsx | 0 .../global/Navbar/index.tsx | 0 .../global/ProtectedRoute.tsx | 0 .../planner/AddBoardCallout.tsx | 0 .../planner/ArchiveView/ArchiveView.tsx | 0 .../planner/Board/Board.tsx | 0 .../Board/FilterToolbar/CategoryFilter.tsx | 0 .../Board/FilterToolbar/DateFilterDisplay.tsx | 0 .../Board/FilterToolbar/FilterToolbar.tsx | 0 .../Board/FilterToolbar/ResetButton.tsx | 0 .../Board/TaskColumns/AddNewCardButton.tsx | 0 .../Board/TaskColumns/AddNewColumnButton.tsx | 0 .../Board/TaskColumns/ColumnHeader.tsx | 0 .../TaskColumns/TaskCard/CategoryBadge.tsx | 0 .../TaskCard/ColumnsDropdownOptionsMenu.tsx | 0 .../TaskColumns/TaskCard/DueDateIndicator.tsx | 0 .../InitializingTaskCard/CancelButton.tsx | 0 .../InitializingTaskCard/CategoryBadge.tsx | 0 .../InitializingTaskCard.tsx | 0 .../TaskColumns/TaskCard/ProgressBar.tsx | 0 .../Board/TaskColumns/TaskCard/SubTasks.tsx | 0 .../Board/TaskColumns/TaskCard/TaskCard.tsx | 0 .../ContextMenuWrapper.tsx | 0 .../DeleteCardContextMenuItem.tsx | 0 .../MoveCardToOtherBoardContextMenuItem.tsx | 0 .../MoveToBottomContextMenuItem.tsx | 0 .../MoveToTopContextMenuItem.tsx | 0 .../TaskCardContextMenu.tsx | 0 .../TaskCardDialog/AddNewSubTaskButton.tsx | 0 .../EditableSubTasks/EditableSubTask.tsx | 0 .../EditableSubTasks/EditableSubTasks.tsx | 0 .../TaskCardDialog/EditableSubTasks/types.tsx | 0 .../TaskCardDialog/EditableSubTasks/utils.ts | 0 .../TaskCardDialog/TaskCardDialog.tsx | 0 .../Board/TaskColumns/TaskCard/utils.ts | 0 .../planner/Board/TaskColumns/TaskColumn.tsx | 0 .../planner/Board/TaskColumns/TaskColumns.tsx | 0 .../planner/Board/TaskColumns/helpers.ts | 0 .../Board/TaskColumns/initial-data-v2.js | 0 .../planner/Board/TaskColumns/initial-data.js | 0 .../planner/Board/TaskFilterSearchBar.tsx | 0 .../planner/Planner.tsx | 0 .../planner/Sidebar/ArchiveModeToggle.tsx | 0 .../planner/Sidebar/EventCalendar.tsx | 0 .../planner/Sidebar/LiveDate.tsx | 0 .../ManageBoardsDialog/AddNewBoardButton.tsx | 0 .../AddNewBoardDialogContent.tsx | 0 .../ManageBoardsDialog/AddNewBoardForm.tsx | 0 .../DeleteBoardConfirmDialog.tsx | 0 .../ManageBoardsDialog/ManageBoardsDialog.tsx | 0 .../ManageBoardsSheetTrigger.tsx | 0 .../ModifyBoardDialogContent.tsx | 0 .../AddNewCategoryButton.tsx | 0 .../AddNewCategoryDialogContent.tsx | 0 .../CategoryColorPicker.tsx | 0 .../DeleteCategoryConfirmDialog.tsx | 0 .../ManageCategoriesDialog.tsx | 0 .../ManageCategoriesSheetTrigger.tsx | 0 .../ModifyCategoryDialogContent.tsx | 0 .../planner/Sidebar/Sidebar.tsx | 0 .../planner/SignInCallout.tsx | 0 .../planner/utils.ts | 0 .../theme-provider.tsx | 0 .../ui/alert-dialog.tsx | 0 .../components => components}/ui/alert.tsx | 0 .../ui/aurora-background.tsx | 0 .../components => components}/ui/avatar.tsx | 0 .../ui/background-boxes.tsx | 0 .../components => components}/ui/badge.tsx | 0 .../components => components}/ui/button.tsx | 0 .../components => components}/ui/calendar.tsx | 0 .../components => components}/ui/card.tsx | 0 .../components => components}/ui/checkbox.tsx | 0 .../components => components}/ui/command.tsx | 0 .../ui/context-menu.tsx | 0 .../components => components}/ui/dialog.tsx | 0 .../ui/dropdown-menu.tsx | 0 .../components => components}/ui/form.tsx | 0 .../ui/glowing-stars.tsx | 0 .../components => components}/ui/input.tsx | 0 .../components => components}/ui/label.tsx | 0 .../components => components}/ui/menubar.tsx | 0 .../ui/moving-border.tsx | 0 .../ui/multi-step-loader.tsx | 0 .../components => components}/ui/popover.tsx | 0 .../components => components}/ui/progress.tsx | 0 .../ui/scroll-area.tsx | 0 .../components => components}/ui/select.tsx | 0 .../ui/separator.tsx | 0 .../components => components}/ui/sheet.tsx | 0 .../components => components}/ui/tabs.tsx | 0 .../components => components}/ui/textarea.tsx | 0 .../components => components}/ui/toast.tsx | 0 .../components => components}/ui/toaster.tsx | 0 .../components => components}/ui/tooltip.tsx | 0 .../components => components}/ui/use-toast.ts | 0 {frontend/config => config}/mongo-client.ts | 0 .../constants => constants}/constants.ts | 0 {frontend/docs => docs}/database.drawio | 0 {frontend/hooks => hooks}/Planner/Planner.tsx | 0 .../Planner/plannerReducer.tsx | 0 {frontend/hooks => hooks}/Planner/types.tsx | 0 .../PlannerFilters/PlannerFilters.tsx | 0 {frontend/lib => lib}/dbConnect.ts | 0 {frontend/lib => lib}/middleware.ts | 0 {frontend/lib => lib}/utils.ts | 0 frontend/middleware.ts => middleware.ts | 0 {frontend/models => models}/Planner.ts | 0 frontend/next.config.js => next.config.js | 0 .../package-lock.json => package-lock.json | 0 frontend/package.json => package.json | 0 .../postcss.config.js => postcss.config.js | 0 .../tailwind.config.js => tailwind.config.js | 0 .../tailwind.config.ts => tailwind.config.ts | 0 frontend/tsconfig.json => tsconfig.json | 0 181 files changed, 1290 deletions(-) rename frontend/.eslintrc.json => .eslintrc.json (100%) rename {frontend/app => app}/api/planner/boards/[boardId]/categories/[categoryId]/route.ts (100%) rename {frontend/app => app}/api/planner/boards/[boardId]/categories/route.ts (100%) rename {frontend/app => app}/api/planner/boards/[boardId]/columns/[columnId]/route.ts (100%) rename {frontend/app => app}/api/planner/boards/[boardId]/columns/reorder/route.ts (100%) rename {frontend/app => app}/api/planner/boards/[boardId]/columns/route.ts (100%) rename {frontend/app => app}/api/planner/boards/[boardId]/route.ts (100%) rename {frontend/app => app}/api/planner/boards/route.ts (100%) rename {frontend/app => app}/api/planner/cards/[cardId]/move/route.ts (100%) rename {frontend/app => app}/api/planner/cards/[cardId]/route.ts (100%) rename {frontend/app => app}/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts (100%) rename {frontend/app => app}/api/planner/cards/[cardId]/subtasks/move/route.ts (100%) rename {frontend/app => app}/api/planner/cards/[cardId]/subtasks/route.ts (100%) rename {frontend/app => app}/api/planner/categories/[categoryId]/route.ts (100%) rename {frontend/app => app}/api/planner/columns/[columnId]/cards/[cardId]/route.ts (100%) rename {frontend/app => app}/api/planner/columns/[columnId]/cards/reorder/route.ts (100%) rename {frontend/app => app}/api/planner/columns/[columnId]/cards/route.ts (100%) rename {frontend/app => app}/api/planner/route.ts (100%) rename {frontend/app => app}/api/planner/subtasks/[subTaskId]/route.ts (100%) rename {frontend/app => app}/favicon.ico (100%) rename {frontend/app => app}/globals.css (100%) rename {frontend/app => app}/home/layout.tsx (100%) rename {frontend/app => app}/home/page.tsx (100%) rename {frontend/app => app}/layout.tsx (100%) rename {frontend/app => app}/page.tsx (100%) rename {frontend/app => app}/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts (100%) rename {frontend/app => app}/utils/plannerUtils/boardUtils/changeBoardInfo.ts (100%) rename {frontend/app => app}/utils/plannerUtils/boardUtils/deleteBoard.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/addNewCardToColumn.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/changeCardCategory.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/changeCardContent.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/changeCardTitle.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/deleteCard.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts (100%) rename {frontend/app => app}/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts (100%) rename {frontend/app => app}/utils/plannerUtils/categoryUtils/addNewCategory.ts (100%) rename {frontend/app => app}/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts (100%) rename {frontend/app => app}/utils/plannerUtils/categoryUtils/deleteCategory.ts (100%) rename {frontend/app => app}/utils/plannerUtils/columnUtils/addNewColumn.ts (100%) rename {frontend/app => app}/utils/plannerUtils/columnUtils/changeColumnName.ts (100%) rename {frontend/app => app}/utils/plannerUtils/columnUtils/changeColumnOrder.ts (100%) rename {frontend/app => app}/utils/plannerUtils/columnUtils/deleteColumn.ts (100%) rename {frontend/app => app}/utils/plannerUtils/plannerUtils.ts (100%) rename {frontend/app => app}/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts (100%) rename {frontend/app => app}/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts (100%) rename {frontend/app => app}/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts (100%) rename {frontend/app => app}/utils/plannerUtils/subTaskUtils/deleteSubTask.ts (100%) rename {frontend/app => app}/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts (100%) rename {frontend/app => app}/utils/plannerUtils/types.ts (100%) rename {frontend/assets => assets}/fonts/CalSans-SemiBold.woff2 (100%) delete mode 100644 backend/db/conn.mjs delete mode 100644 backend/index.mjs delete mode 100644 backend/loadEnvironment.mjs delete mode 100644 backend/middleware/index.mjs delete mode 100644 backend/package-lock.json delete mode 100644 backend/package.json delete mode 100644 backend/routes/planner/columns.mjs delete mode 100644 backend/routes/planner/subtasks.mjs rename frontend/components.json => components.json (100%) rename {frontend/components => components}/global/AlertCard/AlertCard.tsx (100%) rename {frontend/components => components}/global/LoadingSpinner/LoadingSpinner.module.css (100%) rename {frontend/components => components}/global/LoadingSpinner/LoadingSpinner.tsx (100%) rename {frontend/components => components}/global/ModeToggle.tsx (100%) rename {frontend/components => components}/global/Navbar/NavLinks.tsx (100%) rename {frontend/components => components}/global/Navbar/NewsAlertBanner.tsx (100%) rename {frontend/components => components}/global/Navbar/SiteLogo.tsx (100%) rename {frontend/components => components}/global/Navbar/index.tsx (100%) rename {frontend/components => components}/global/ProtectedRoute.tsx (100%) rename {frontend/components => components}/planner/AddBoardCallout.tsx (100%) rename {frontend/components => components}/planner/ArchiveView/ArchiveView.tsx (100%) rename {frontend/components => components}/planner/Board/Board.tsx (100%) rename {frontend/components => components}/planner/Board/FilterToolbar/CategoryFilter.tsx (100%) rename {frontend/components => components}/planner/Board/FilterToolbar/DateFilterDisplay.tsx (100%) rename {frontend/components => components}/planner/Board/FilterToolbar/FilterToolbar.tsx (100%) rename {frontend/components => components}/planner/Board/FilterToolbar/ResetButton.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/AddNewCardButton.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/AddNewColumnButton.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/ColumnHeader.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/CategoryBadge.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/ColumnsDropdownOptionsMenu.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/DueDateIndicator.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CancelButton.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CategoryBadge.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/InitializingTaskCard.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/ProgressBar.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/SubTasks.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCard.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/ContextMenuWrapper.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/DeleteCardContextMenuItem.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveCardToOtherBoardContextMenuItem.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToBottomContextMenuItem.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToTopContextMenuItem.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/TaskCardContextMenu.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardDialog/AddNewSubTaskButton.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTask.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTasks.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/types.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/utils.ts (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/TaskCardDialog/TaskCardDialog.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskCard/utils.ts (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskColumn.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/TaskColumns.tsx (100%) rename {frontend/components => components}/planner/Board/TaskColumns/helpers.ts (100%) rename {frontend/components => components}/planner/Board/TaskColumns/initial-data-v2.js (100%) rename {frontend/components => components}/planner/Board/TaskColumns/initial-data.js (100%) rename {frontend/components => components}/planner/Board/TaskFilterSearchBar.tsx (100%) rename {frontend/components => components}/planner/Planner.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ArchiveModeToggle.tsx (100%) rename {frontend/components => components}/planner/Sidebar/EventCalendar.tsx (100%) rename {frontend/components => components}/planner/Sidebar/LiveDate.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/AddNewBoardButton.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/AddNewBoardDialogContent.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/AddNewBoardForm.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/DeleteBoardConfirmDialog.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/ManageBoardsDialog.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageBoardsDialog/ModifyBoardDialogContent.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryButton.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryDialogContent.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/CategoryColorPicker.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/DeleteCategoryConfirmDialog.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesDialog.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx (100%) rename {frontend/components => components}/planner/Sidebar/ManageCategoriesDialog/ModifyCategoryDialogContent.tsx (100%) rename {frontend/components => components}/planner/Sidebar/Sidebar.tsx (100%) rename {frontend/components => components}/planner/SignInCallout.tsx (100%) rename {frontend/components => components}/planner/utils.ts (100%) rename {frontend/components => components}/theme-provider.tsx (100%) rename {frontend/components => components}/ui/alert-dialog.tsx (100%) rename {frontend/components => components}/ui/alert.tsx (100%) rename {frontend/components => components}/ui/aurora-background.tsx (100%) rename {frontend/components => components}/ui/avatar.tsx (100%) rename {frontend/components => components}/ui/background-boxes.tsx (100%) rename {frontend/components => components}/ui/badge.tsx (100%) rename {frontend/components => components}/ui/button.tsx (100%) rename {frontend/components => components}/ui/calendar.tsx (100%) rename {frontend/components => components}/ui/card.tsx (100%) rename {frontend/components => components}/ui/checkbox.tsx (100%) rename {frontend/components => components}/ui/command.tsx (100%) rename {frontend/components => components}/ui/context-menu.tsx (100%) rename {frontend/components => components}/ui/dialog.tsx (100%) rename {frontend/components => components}/ui/dropdown-menu.tsx (100%) rename {frontend/components => components}/ui/form.tsx (100%) rename {frontend/components => components}/ui/glowing-stars.tsx (100%) rename {frontend/components => components}/ui/input.tsx (100%) rename {frontend/components => components}/ui/label.tsx (100%) rename {frontend/components => components}/ui/menubar.tsx (100%) rename {frontend/components => components}/ui/moving-border.tsx (100%) rename {frontend/components => components}/ui/multi-step-loader.tsx (100%) rename {frontend/components => components}/ui/popover.tsx (100%) rename {frontend/components => components}/ui/progress.tsx (100%) rename {frontend/components => components}/ui/scroll-area.tsx (100%) rename {frontend/components => components}/ui/select.tsx (100%) rename {frontend/components => components}/ui/separator.tsx (100%) rename {frontend/components => components}/ui/sheet.tsx (100%) rename {frontend/components => components}/ui/tabs.tsx (100%) rename {frontend/components => components}/ui/textarea.tsx (100%) rename {frontend/components => components}/ui/toast.tsx (100%) rename {frontend/components => components}/ui/toaster.tsx (100%) rename {frontend/components => components}/ui/tooltip.tsx (100%) rename {frontend/components => components}/ui/use-toast.ts (100%) rename {frontend/config => config}/mongo-client.ts (100%) rename {frontend/constants => constants}/constants.ts (100%) rename {frontend/docs => docs}/database.drawio (100%) rename {frontend/hooks => hooks}/Planner/Planner.tsx (100%) rename {frontend/hooks => hooks}/Planner/plannerReducer.tsx (100%) rename {frontend/hooks => hooks}/Planner/types.tsx (100%) rename {frontend/hooks => hooks}/PlannerFilters/PlannerFilters.tsx (100%) rename {frontend/lib => lib}/dbConnect.ts (100%) rename {frontend/lib => lib}/middleware.ts (100%) rename {frontend/lib => lib}/utils.ts (100%) rename frontend/middleware.ts => middleware.ts (100%) rename {frontend/models => models}/Planner.ts (100%) rename frontend/next.config.js => next.config.js (100%) rename frontend/package-lock.json => package-lock.json (100%) rename frontend/package.json => package.json (100%) rename frontend/postcss.config.js => postcss.config.js (100%) rename frontend/tailwind.config.js => tailwind.config.js (100%) rename frontend/tailwind.config.ts => tailwind.config.ts (100%) rename frontend/tsconfig.json => tsconfig.json (100%) diff --git a/frontend/.eslintrc.json b/.eslintrc.json similarity index 100% rename from frontend/.eslintrc.json rename to .eslintrc.json diff --git a/frontend/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts b/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts similarity index 100% rename from frontend/app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts rename to app/api/planner/boards/[boardId]/categories/[categoryId]/route.ts diff --git a/frontend/app/api/planner/boards/[boardId]/categories/route.ts b/app/api/planner/boards/[boardId]/categories/route.ts similarity index 100% rename from frontend/app/api/planner/boards/[boardId]/categories/route.ts rename to app/api/planner/boards/[boardId]/categories/route.ts diff --git a/frontend/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts b/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts similarity index 100% rename from frontend/app/api/planner/boards/[boardId]/columns/[columnId]/route.ts rename to app/api/planner/boards/[boardId]/columns/[columnId]/route.ts diff --git a/frontend/app/api/planner/boards/[boardId]/columns/reorder/route.ts b/app/api/planner/boards/[boardId]/columns/reorder/route.ts similarity index 100% rename from frontend/app/api/planner/boards/[boardId]/columns/reorder/route.ts rename to app/api/planner/boards/[boardId]/columns/reorder/route.ts diff --git a/frontend/app/api/planner/boards/[boardId]/columns/route.ts b/app/api/planner/boards/[boardId]/columns/route.ts similarity index 100% rename from frontend/app/api/planner/boards/[boardId]/columns/route.ts rename to app/api/planner/boards/[boardId]/columns/route.ts diff --git a/frontend/app/api/planner/boards/[boardId]/route.ts b/app/api/planner/boards/[boardId]/route.ts similarity index 100% rename from frontend/app/api/planner/boards/[boardId]/route.ts rename to app/api/planner/boards/[boardId]/route.ts diff --git a/frontend/app/api/planner/boards/route.ts b/app/api/planner/boards/route.ts similarity index 100% rename from frontend/app/api/planner/boards/route.ts rename to app/api/planner/boards/route.ts diff --git a/frontend/app/api/planner/cards/[cardId]/move/route.ts b/app/api/planner/cards/[cardId]/move/route.ts similarity index 100% rename from frontend/app/api/planner/cards/[cardId]/move/route.ts rename to app/api/planner/cards/[cardId]/move/route.ts diff --git a/frontend/app/api/planner/cards/[cardId]/route.ts b/app/api/planner/cards/[cardId]/route.ts similarity index 100% rename from frontend/app/api/planner/cards/[cardId]/route.ts rename to app/api/planner/cards/[cardId]/route.ts diff --git a/frontend/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts b/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts similarity index 100% rename from frontend/app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts rename to app/api/planner/cards/[cardId]/subtasks/[subTaskId]/route.ts diff --git a/frontend/app/api/planner/cards/[cardId]/subtasks/move/route.ts b/app/api/planner/cards/[cardId]/subtasks/move/route.ts similarity index 100% rename from frontend/app/api/planner/cards/[cardId]/subtasks/move/route.ts rename to app/api/planner/cards/[cardId]/subtasks/move/route.ts diff --git a/frontend/app/api/planner/cards/[cardId]/subtasks/route.ts b/app/api/planner/cards/[cardId]/subtasks/route.ts similarity index 100% rename from frontend/app/api/planner/cards/[cardId]/subtasks/route.ts rename to app/api/planner/cards/[cardId]/subtasks/route.ts diff --git a/frontend/app/api/planner/categories/[categoryId]/route.ts b/app/api/planner/categories/[categoryId]/route.ts similarity index 100% rename from frontend/app/api/planner/categories/[categoryId]/route.ts rename to app/api/planner/categories/[categoryId]/route.ts diff --git a/frontend/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts b/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts similarity index 100% rename from frontend/app/api/planner/columns/[columnId]/cards/[cardId]/route.ts rename to app/api/planner/columns/[columnId]/cards/[cardId]/route.ts diff --git a/frontend/app/api/planner/columns/[columnId]/cards/reorder/route.ts b/app/api/planner/columns/[columnId]/cards/reorder/route.ts similarity index 100% rename from frontend/app/api/planner/columns/[columnId]/cards/reorder/route.ts rename to app/api/planner/columns/[columnId]/cards/reorder/route.ts diff --git a/frontend/app/api/planner/columns/[columnId]/cards/route.ts b/app/api/planner/columns/[columnId]/cards/route.ts similarity index 100% rename from frontend/app/api/planner/columns/[columnId]/cards/route.ts rename to app/api/planner/columns/[columnId]/cards/route.ts diff --git a/frontend/app/api/planner/route.ts b/app/api/planner/route.ts similarity index 100% rename from frontend/app/api/planner/route.ts rename to app/api/planner/route.ts diff --git a/frontend/app/api/planner/subtasks/[subTaskId]/route.ts b/app/api/planner/subtasks/[subTaskId]/route.ts similarity index 100% rename from frontend/app/api/planner/subtasks/[subTaskId]/route.ts rename to app/api/planner/subtasks/[subTaskId]/route.ts diff --git a/frontend/app/favicon.ico b/app/favicon.ico similarity index 100% rename from frontend/app/favicon.ico rename to app/favicon.ico diff --git a/frontend/app/globals.css b/app/globals.css similarity index 100% rename from frontend/app/globals.css rename to app/globals.css diff --git a/frontend/app/home/layout.tsx b/app/home/layout.tsx similarity index 100% rename from frontend/app/home/layout.tsx rename to app/home/layout.tsx diff --git a/frontend/app/home/page.tsx b/app/home/page.tsx similarity index 100% rename from frontend/app/home/page.tsx rename to app/home/page.tsx diff --git a/frontend/app/layout.tsx b/app/layout.tsx similarity index 100% rename from frontend/app/layout.tsx rename to app/layout.tsx diff --git a/frontend/app/page.tsx b/app/page.tsx similarity index 100% rename from frontend/app/page.tsx rename to app/page.tsx diff --git a/frontend/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts b/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts similarity index 100% rename from frontend/app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts rename to app/utils/plannerUtils/boardUtils/addNewBoardToPlanner.ts diff --git a/frontend/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts b/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts similarity index 100% rename from frontend/app/utils/plannerUtils/boardUtils/changeBoardInfo.ts rename to app/utils/plannerUtils/boardUtils/changeBoardInfo.ts diff --git a/frontend/app/utils/plannerUtils/boardUtils/deleteBoard.ts b/app/utils/plannerUtils/boardUtils/deleteBoard.ts similarity index 100% rename from frontend/app/utils/plannerUtils/boardUtils/deleteBoard.ts rename to app/utils/plannerUtils/boardUtils/deleteBoard.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts b/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts rename to app/utils/plannerUtils/cardUtils/addNewCardToColumn.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardCategory.ts b/app/utils/plannerUtils/cardUtils/changeCardCategory.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/changeCardCategory.ts rename to app/utils/plannerUtils/cardUtils/changeCardCategory.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts b/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts rename to app/utils/plannerUtils/cardUtils/changeCardCheckedStatus.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardContent.ts b/app/utils/plannerUtils/cardUtils/changeCardContent.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/changeCardContent.ts rename to app/utils/plannerUtils/cardUtils/changeCardContent.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/changeCardTitle.ts b/app/utils/plannerUtils/cardUtils/changeCardTitle.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/changeCardTitle.ts rename to app/utils/plannerUtils/cardUtils/changeCardTitle.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/deleteCard.ts b/app/utils/plannerUtils/cardUtils/deleteCard.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/deleteCard.ts rename to app/utils/plannerUtils/cardUtils/deleteCard.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts b/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts rename to app/utils/plannerUtils/cardUtils/moveCardAcrossColumns.ts diff --git a/frontend/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts b/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts similarity index 100% rename from frontend/app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts rename to app/utils/plannerUtils/cardUtils/moveCardWithinColumn.ts diff --git a/frontend/app/utils/plannerUtils/categoryUtils/addNewCategory.ts b/app/utils/plannerUtils/categoryUtils/addNewCategory.ts similarity index 100% rename from frontend/app/utils/plannerUtils/categoryUtils/addNewCategory.ts rename to app/utils/plannerUtils/categoryUtils/addNewCategory.ts diff --git a/frontend/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts b/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts similarity index 100% rename from frontend/app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts rename to app/utils/plannerUtils/categoryUtils/changeCategoryInfo.ts diff --git a/frontend/app/utils/plannerUtils/categoryUtils/deleteCategory.ts b/app/utils/plannerUtils/categoryUtils/deleteCategory.ts similarity index 100% rename from frontend/app/utils/plannerUtils/categoryUtils/deleteCategory.ts rename to app/utils/plannerUtils/categoryUtils/deleteCategory.ts diff --git a/frontend/app/utils/plannerUtils/columnUtils/addNewColumn.ts b/app/utils/plannerUtils/columnUtils/addNewColumn.ts similarity index 100% rename from frontend/app/utils/plannerUtils/columnUtils/addNewColumn.ts rename to app/utils/plannerUtils/columnUtils/addNewColumn.ts diff --git a/frontend/app/utils/plannerUtils/columnUtils/changeColumnName.ts b/app/utils/plannerUtils/columnUtils/changeColumnName.ts similarity index 100% rename from frontend/app/utils/plannerUtils/columnUtils/changeColumnName.ts rename to app/utils/plannerUtils/columnUtils/changeColumnName.ts diff --git a/frontend/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts b/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts similarity index 100% rename from frontend/app/utils/plannerUtils/columnUtils/changeColumnOrder.ts rename to app/utils/plannerUtils/columnUtils/changeColumnOrder.ts diff --git a/frontend/app/utils/plannerUtils/columnUtils/deleteColumn.ts b/app/utils/plannerUtils/columnUtils/deleteColumn.ts similarity index 100% rename from frontend/app/utils/plannerUtils/columnUtils/deleteColumn.ts rename to app/utils/plannerUtils/columnUtils/deleteColumn.ts diff --git a/frontend/app/utils/plannerUtils/plannerUtils.ts b/app/utils/plannerUtils/plannerUtils.ts similarity index 100% rename from frontend/app/utils/plannerUtils/plannerUtils.ts rename to app/utils/plannerUtils/plannerUtils.ts diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts b/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts similarity index 100% rename from frontend/app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts rename to app/utils/plannerUtils/subTaskUtils/addNewSubTaskToCard.ts diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts b/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts similarity index 100% rename from frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts rename to app/utils/plannerUtils/subTaskUtils/changeSubTaskCheckedStatus.ts diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts b/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts similarity index 100% rename from frontend/app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts rename to app/utils/plannerUtils/subTaskUtils/changeSubTaskTitle.ts diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts b/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts similarity index 100% rename from frontend/app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts rename to app/utils/plannerUtils/subTaskUtils/deleteSubTask.ts diff --git a/frontend/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts b/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts similarity index 100% rename from frontend/app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts rename to app/utils/plannerUtils/subTaskUtils/reorderSubtasks.ts diff --git a/frontend/app/utils/plannerUtils/types.ts b/app/utils/plannerUtils/types.ts similarity index 100% rename from frontend/app/utils/plannerUtils/types.ts rename to app/utils/plannerUtils/types.ts diff --git a/frontend/assets/fonts/CalSans-SemiBold.woff2 b/assets/fonts/CalSans-SemiBold.woff2 similarity index 100% rename from frontend/assets/fonts/CalSans-SemiBold.woff2 rename to assets/fonts/CalSans-SemiBold.woff2 diff --git a/backend/db/conn.mjs b/backend/db/conn.mjs deleted file mode 100644 index bfda8ce..0000000 --- a/backend/db/conn.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import { MongoClient } from 'mongodb' - -const connectionString = process.env.MONGO_URI || '' -const client = new MongoClient(connectionString) -let conn - -try { - conn = await client.connect() -} catch (e) { - console.error(e) -} - -let db = conn.db('planner') -export default db diff --git a/backend/index.mjs b/backend/index.mjs deleted file mode 100644 index 38d3c01..0000000 --- a/backend/index.mjs +++ /dev/null @@ -1,36 +0,0 @@ -import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node' -import cors from 'cors' -import express from 'express' -import './loadEnvironment.mjs' -import columns from './routes/planner/columns.mjs' -import subtasks from './routes/planner/subtasks.mjs' - -const PORT = process.env.PORT || 5050 -const app = express() -const allowedOrigin = process.env.ALLOWED_ORIGIN - -const corsOptions = { - origin: function (origin, callback) { - if (origin === allowedOrigin) { - callback(null, true) - } else { - callback(new Error('Not allowed by CORS')) - } - }, -} - -app.use(cors(corsOptions)) -app.use(express.json()) - -app.use(ClerkExpressRequireAuth()) - -app.use('/', [columns, subtasks]) - -// Global error handling -app.use((err, _req, res, next) => { - res.status(500).send('Uh oh! An unexpected error occured.') -}) - -app.listen(PORT, () => { - console.log(`Server is running on port: ${PORT}`) -}) diff --git a/backend/loadEnvironment.mjs b/backend/loadEnvironment.mjs deleted file mode 100644 index 50c8721..0000000 --- a/backend/loadEnvironment.mjs +++ /dev/null @@ -1,2 +0,0 @@ -import dotenv from 'dotenv' -dotenv.config() diff --git a/backend/middleware/index.mjs b/backend/middleware/index.mjs deleted file mode 100644 index dad7fb7..0000000 --- a/backend/middleware/index.mjs +++ /dev/null @@ -1,12 +0,0 @@ -const handleServerError = (res, error) => { - console.error(error) - res.status(500).send('Internal Server Error') -} - -export const errorHandler = (handler) => async (req, res, next) => { - try { - await handler(req, res, next) - } catch (error) { - handleServerError(res, error) - } -} diff --git a/backend/package-lock.json b/backend/package-lock.json deleted file mode 100644 index 42514b1..0000000 --- a/backend/package-lock.json +++ /dev/null @@ -1,1053 +0,0 @@ -{ - "name": "backend", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@clerk/clerk-sdk-node": "^5.0.12", - "cors": "^2.8.5", - "dotenv": "^16.3.1", - "express": "^4.18.2", - "express-async-errors": "^3.1.1", - "mongodb": "^6.3.0" - } - }, - "node_modules/@clerk/backend": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@clerk/backend/-/backend-1.2.4.tgz", - "integrity": "sha512-H6K1kHPaDFM6pBdwDAHh1jWSZxCWhGPzDmqgc7LByjqKS6RZUf3cs5mJkIXyopUpHY7wvwj50vSF0xJ46MEzNA==", - "dependencies": { - "@clerk/shared": "2.3.1", - "@clerk/types": "4.6.1", - "cookie": "0.5.0", - "snakecase-keys": "5.4.4", - "tslib": "2.4.1" - }, - "engines": { - "node": ">=18.17.0" - } - }, - "node_modules/@clerk/clerk-sdk-node": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/@clerk/clerk-sdk-node/-/clerk-sdk-node-5.0.12.tgz", - "integrity": "sha512-pH4AUDmKLOOcSP9GALpMaYwbMQbLFwuDb7Bvf1Di3ve9bEeoGEnt6UnnjiYvo3p+x02+NLwUmlF+Bek842mYGg==", - "dependencies": { - "@clerk/backend": "1.2.4", - "@clerk/shared": "2.3.1", - "@clerk/types": "4.6.1", - "tslib": "2.4.1" - }, - "engines": { - "node": ">=18.17.0" - } - }, - "node_modules/@clerk/shared": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-2.3.1.tgz", - "integrity": "sha512-WX7cCViYqkNMnbFfT2B93ykNcSseoYM1obMUynO60VBl9Zi6Epde5tn9VRamhuOdojgPR+DyYkH9AzBpXFYnSg==", - "hasInstallScript": true, - "dependencies": { - "@clerk/types": "4.6.1", - "glob-to-regexp": "0.4.1", - "js-cookie": "3.0.5", - "std-env": "^3.7.0", - "swr": "^2.2.0" - }, - "engines": { - "node": ">=18.17.0" - }, - "peerDependencies": { - "react": ">=18 || >=19.0.0-beta", - "react-dom": ">=18 || >=19.0.0-beta" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@clerk/types": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@clerk/types/-/types-4.6.1.tgz", - "integrity": "sha512-QFeNKPYDmTJ88l5QYG0SPwbABk42wRMalW3M/wAtr+wnQxBCXyX2XRZe9h4g2rH1VF+wG4Xe56abeeD+xE4iEw==", - "dependencies": { - "csstype": "3.1.1" - }, - "engines": { - "node": ">=18.17.0" - } - }, - "node_modules/@mongodb-js/saslprep": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", - "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", - "dependencies": { - "sparse-bitfield": "^3.0.3" - } - }, - "node_modules/@types/webidl-conversions": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" - }, - "node_modules/@types/whatwg-url": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.3.tgz", - "integrity": "sha512-z1ELvMijRL1QmU7QuzDkeYXSF2+dXI0ITKoQsIoVKcNBOiK5RMmWy+pYYxJTHFt8vkpZe7UsvRErQwcxZkjoUw==", - "dependencies": { - "@types/webidl-conversions": "*" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/bson": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", - "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", - "engines": { - "node": ">=16.20.1" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-async-errors": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", - "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", - "peerDependencies": { - "express": "^4.16.2" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "engines": { - "node": ">=14" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mongodb": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", - "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", - "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", - "mongodb-connection-string-url": "^3.0.0" - }, - "engines": { - "node": ">=16.20.1" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", - "gcp-metadata": "^5.2.0", - "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.2.2", - "socks": "^2.7.1" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "gcp-metadata": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - }, - "socks": { - "optional": true - } - } - }, - "node_modules/mongodb-connection-string-url": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", - "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", - "dependencies": { - "@types/whatwg-url": "^11.0.2", - "whatwg-url": "^13.0.0" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/snakecase-keys": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-5.4.4.tgz", - "integrity": "sha512-YTywJG93yxwHLgrYLZjlC75moVEX04LZM4FHfihjHe1FCXm+QaLOFfSf535aXOAd0ArVQMWUAe8ZPm4VtWyXaA==", - "dependencies": { - "map-obj": "^4.1.0", - "snake-case": "^3.0.4", - "type-fest": "^2.5.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/sparse-bitfield": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "dependencies": { - "memory-pager": "^1.0.2" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" - }, - "node_modules/swr": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.2.5.tgz", - "integrity": "sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==", - "dependencies": { - "client-only": "^0.0.1", - "use-sync-external-store": "^1.2.0" - }, - "peerDependencies": { - "react": "^16.11.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=16" - } - } - } -} diff --git a/backend/package.json b/backend/package.json deleted file mode 100644 index 2397bf6..0000000 --- a/backend/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "dependencies": { - "@clerk/clerk-sdk-node": "^5.0.12", - "cors": "^2.8.5", - "dotenv": "^16.3.1", - "express": "^4.18.2", - "express-async-errors": "^3.1.1", - "mongodb": "^6.3.0" - }, - "scripts": { - "dev": "nodemon index.mjs" - } -} diff --git a/backend/routes/planner/columns.mjs b/backend/routes/planner/columns.mjs deleted file mode 100644 index 89b376a..0000000 --- a/backend/routes/planner/columns.mjs +++ /dev/null @@ -1,73 +0,0 @@ -import express from 'express' -import db from '../../db/conn.mjs' -import { errorHandler } from '../../middleware/index.mjs' - -const router = express.Router() - -const addNewColumn = async (req, res) => { - const userId = req.auth.userId - const { boardId } = req.params - const { newColumnDetails: newColumn, updatedColumns } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`boards.${boardId}.columns`]: updatedColumns, - [`columns.${newColumn.id}`]: newColumn, - }, - } - ) - res.status(201).end() -} - -const changeColumnOrder = async (req, res) => { - const userId = req.auth.userId - const { boardId } = req.params - const { newColumnOrder } = req.body - await db - .collection('planner') - .updateOne( - { clerkUserId: userId, [`boards.${boardId}.id`]: boardId }, - { $set: { [`boards.${boardId}.columns`]: newColumnOrder } } - ) - res.status(204).end() -} - -const deleteColumn = async (req, res) => { - const userId = req.auth.userId - const { boardId, columnId } = req.params - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $pull: { - [`boards.${boardId}.columns`]: columnId, - }, - $unset: { - [`columns.${columnId}`]: 1, - }, - } - ) - res.status(204).end() -} - -const changeColumnName = async (req, res) => { - const userId = req.auth.userId - const { columnId } = req.params - const { newName } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`columns.${columnId}.name`]: newName, - }, - } - ) - res.status(204).end() -} - -router.patch('/planner/columns/:columnId', errorHandler(changeColumnName)) -router.post('/planner/boards/:boardId/columns', errorHandler(addNewColumn)) -router.patch('/planner/boards/:boardId/columns/reorder', errorHandler(changeColumnOrder)) -router.delete('/planner/boards/:boardId/columns/:columnId/delete', errorHandler(deleteColumn)) - -export default router diff --git a/backend/routes/planner/subtasks.mjs b/backend/routes/planner/subtasks.mjs deleted file mode 100644 index 3bc1aa6..0000000 --- a/backend/routes/planner/subtasks.mjs +++ /dev/null @@ -1,87 +0,0 @@ -import express from 'express' -import db from '../../db/conn.mjs' -import { errorHandler } from '../../middleware/index.mjs' - -const router = express.Router() - -const addNewSubTaskToCard = async (req, res) => { - const userId = req.auth.userId - const { taskCardId } = req.params - const { newSubTaskDetails: newSubTask, newSubTasksOrder } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`taskCards.${taskCardId}.subTasks`]: newSubTasksOrder, - [`subTasks.${newSubTask.id}`]: newSubTask, - }, - } - ) - res.status(201).end() -} - -const changeSubTaskCheckedStatus = async (req, res) => { - const userId = req.auth.userId - const { subTaskId } = req.params - const { isChecked } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`subTasks.${subTaskId}.checked`]: isChecked, - }, - } - ) - res.status(204).end() -} - -const changeSubTaskTitle = async (req, res) => { - const userId = req.auth.userId - const { subTaskId } = req.params - const { newTitle } = req.body - await db.collection('planner').updateOne( - { clerkUserId: userId }, - { - $set: { - [`subTasks.${subTaskId}.title`]: newTitle, - }, - } - ) - res.status(204).end() -} - -const moveSubtaskWithinCard = async (req, res) => { - const userId = req.auth.userId - const { taskCardId } = req.params - const { reorderedSubTasks } = req.body - await db - .collection('planner') - .updateOne( - { clerkUserId: userId, [`taskCards.${taskCardId}.id`]: taskCardId }, - { $set: { [`taskCards.${taskCardId}.subTasks`]: reorderedSubTasks } } - ) - res.status(204).end() -} - -const deleteSubTask = async (req, res) => { - const userId = req.auth.userId - const { taskCardId, subTaskId } = req.params - // Remove the subtask from the subtask object using $unset - await db.collection('planner').updateOne({ clerkUserId: userId }, { $unset: { [`subTasks.${subTaskId}`]: '' } }) - // Remove the subtask from the subtask list within the specified taskcard using $pull - await db - .collection('planner') - .updateOne( - { clerkUserId: userId, [`taskCards.${taskCardId}.id`]: taskCardId }, - { $pull: { [`taskCards.${taskCardId}.subTasks`]: subTaskId } } - ) - res.status(204).end() -} - -router.post('/planner/cards/:taskCardId/subtasks', errorHandler(addNewSubTaskToCard)) -router.patch('/planner/subtasks/:subTaskId/checked', errorHandler(changeSubTaskCheckedStatus)) -router.patch('/planner/subtasks/:subTaskId/title', errorHandler(changeSubTaskTitle)) -router.patch('/planner/cards/:taskCardId/subtasks/move', errorHandler(moveSubtaskWithinCard)) -router.delete('/planner/cards/:taskCardId/subtasks/:subTaskId/delete', errorHandler(deleteSubTask)) - -export default router diff --git a/frontend/components.json b/components.json similarity index 100% rename from frontend/components.json rename to components.json diff --git a/frontend/components/global/AlertCard/AlertCard.tsx b/components/global/AlertCard/AlertCard.tsx similarity index 100% rename from frontend/components/global/AlertCard/AlertCard.tsx rename to components/global/AlertCard/AlertCard.tsx diff --git a/frontend/components/global/LoadingSpinner/LoadingSpinner.module.css b/components/global/LoadingSpinner/LoadingSpinner.module.css similarity index 100% rename from frontend/components/global/LoadingSpinner/LoadingSpinner.module.css rename to components/global/LoadingSpinner/LoadingSpinner.module.css diff --git a/frontend/components/global/LoadingSpinner/LoadingSpinner.tsx b/components/global/LoadingSpinner/LoadingSpinner.tsx similarity index 100% rename from frontend/components/global/LoadingSpinner/LoadingSpinner.tsx rename to components/global/LoadingSpinner/LoadingSpinner.tsx diff --git a/frontend/components/global/ModeToggle.tsx b/components/global/ModeToggle.tsx similarity index 100% rename from frontend/components/global/ModeToggle.tsx rename to components/global/ModeToggle.tsx diff --git a/frontend/components/global/Navbar/NavLinks.tsx b/components/global/Navbar/NavLinks.tsx similarity index 100% rename from frontend/components/global/Navbar/NavLinks.tsx rename to components/global/Navbar/NavLinks.tsx diff --git a/frontend/components/global/Navbar/NewsAlertBanner.tsx b/components/global/Navbar/NewsAlertBanner.tsx similarity index 100% rename from frontend/components/global/Navbar/NewsAlertBanner.tsx rename to components/global/Navbar/NewsAlertBanner.tsx diff --git a/frontend/components/global/Navbar/SiteLogo.tsx b/components/global/Navbar/SiteLogo.tsx similarity index 100% rename from frontend/components/global/Navbar/SiteLogo.tsx rename to components/global/Navbar/SiteLogo.tsx diff --git a/frontend/components/global/Navbar/index.tsx b/components/global/Navbar/index.tsx similarity index 100% rename from frontend/components/global/Navbar/index.tsx rename to components/global/Navbar/index.tsx diff --git a/frontend/components/global/ProtectedRoute.tsx b/components/global/ProtectedRoute.tsx similarity index 100% rename from frontend/components/global/ProtectedRoute.tsx rename to components/global/ProtectedRoute.tsx diff --git a/frontend/components/planner/AddBoardCallout.tsx b/components/planner/AddBoardCallout.tsx similarity index 100% rename from frontend/components/planner/AddBoardCallout.tsx rename to components/planner/AddBoardCallout.tsx diff --git a/frontend/components/planner/ArchiveView/ArchiveView.tsx b/components/planner/ArchiveView/ArchiveView.tsx similarity index 100% rename from frontend/components/planner/ArchiveView/ArchiveView.tsx rename to components/planner/ArchiveView/ArchiveView.tsx diff --git a/frontend/components/planner/Board/Board.tsx b/components/planner/Board/Board.tsx similarity index 100% rename from frontend/components/planner/Board/Board.tsx rename to components/planner/Board/Board.tsx diff --git a/frontend/components/planner/Board/FilterToolbar/CategoryFilter.tsx b/components/planner/Board/FilterToolbar/CategoryFilter.tsx similarity index 100% rename from frontend/components/planner/Board/FilterToolbar/CategoryFilter.tsx rename to components/planner/Board/FilterToolbar/CategoryFilter.tsx diff --git a/frontend/components/planner/Board/FilterToolbar/DateFilterDisplay.tsx b/components/planner/Board/FilterToolbar/DateFilterDisplay.tsx similarity index 100% rename from frontend/components/planner/Board/FilterToolbar/DateFilterDisplay.tsx rename to components/planner/Board/FilterToolbar/DateFilterDisplay.tsx diff --git a/frontend/components/planner/Board/FilterToolbar/FilterToolbar.tsx b/components/planner/Board/FilterToolbar/FilterToolbar.tsx similarity index 100% rename from frontend/components/planner/Board/FilterToolbar/FilterToolbar.tsx rename to components/planner/Board/FilterToolbar/FilterToolbar.tsx diff --git a/frontend/components/planner/Board/FilterToolbar/ResetButton.tsx b/components/planner/Board/FilterToolbar/ResetButton.tsx similarity index 100% rename from frontend/components/planner/Board/FilterToolbar/ResetButton.tsx rename to components/planner/Board/FilterToolbar/ResetButton.tsx diff --git a/frontend/components/planner/Board/TaskColumns/AddNewCardButton.tsx b/components/planner/Board/TaskColumns/AddNewCardButton.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/AddNewCardButton.tsx rename to components/planner/Board/TaskColumns/AddNewCardButton.tsx diff --git a/frontend/components/planner/Board/TaskColumns/AddNewColumnButton.tsx b/components/planner/Board/TaskColumns/AddNewColumnButton.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/AddNewColumnButton.tsx rename to components/planner/Board/TaskColumns/AddNewColumnButton.tsx diff --git a/frontend/components/planner/Board/TaskColumns/ColumnHeader.tsx b/components/planner/Board/TaskColumns/ColumnHeader.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/ColumnHeader.tsx rename to components/planner/Board/TaskColumns/ColumnHeader.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/CategoryBadge.tsx b/components/planner/Board/TaskColumns/TaskCard/CategoryBadge.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/CategoryBadge.tsx rename to components/planner/Board/TaskColumns/TaskCard/CategoryBadge.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/ColumnsDropdownOptionsMenu.tsx b/components/planner/Board/TaskColumns/TaskCard/ColumnsDropdownOptionsMenu.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/ColumnsDropdownOptionsMenu.tsx rename to components/planner/Board/TaskColumns/TaskCard/ColumnsDropdownOptionsMenu.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/DueDateIndicator.tsx b/components/planner/Board/TaskColumns/TaskCard/DueDateIndicator.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/DueDateIndicator.tsx rename to components/planner/Board/TaskColumns/TaskCard/DueDateIndicator.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CancelButton.tsx b/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CancelButton.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CancelButton.tsx rename to components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CancelButton.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CategoryBadge.tsx b/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CategoryBadge.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CategoryBadge.tsx rename to components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/CategoryBadge.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/InitializingTaskCard.tsx b/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/InitializingTaskCard.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/InitializingTaskCard.tsx rename to components/planner/Board/TaskColumns/TaskCard/InitializingTaskCard/InitializingTaskCard.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/ProgressBar.tsx b/components/planner/Board/TaskColumns/TaskCard/ProgressBar.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/ProgressBar.tsx rename to components/planner/Board/TaskColumns/TaskCard/ProgressBar.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/SubTasks.tsx b/components/planner/Board/TaskColumns/TaskCard/SubTasks.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/SubTasks.tsx rename to components/planner/Board/TaskColumns/TaskCard/SubTasks.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCard.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCard.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCard.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCard.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/ContextMenuWrapper.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/ContextMenuWrapper.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/ContextMenuWrapper.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/ContextMenuWrapper.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/DeleteCardContextMenuItem.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/DeleteCardContextMenuItem.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/DeleteCardContextMenuItem.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/DeleteCardContextMenuItem.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveCardToOtherBoardContextMenuItem.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveCardToOtherBoardContextMenuItem.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveCardToOtherBoardContextMenuItem.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveCardToOtherBoardContextMenuItem.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToBottomContextMenuItem.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToBottomContextMenuItem.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToBottomContextMenuItem.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToBottomContextMenuItem.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToTopContextMenuItem.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToTopContextMenuItem.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToTopContextMenuItem.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/MoveToTopContextMenuItem.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/TaskCardContextMenu.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/TaskCardContextMenu.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/TaskCardContextMenu.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardContextMenu/TaskCardContextMenu.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/AddNewSubTaskButton.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/AddNewSubTaskButton.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/AddNewSubTaskButton.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/AddNewSubTaskButton.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTask.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTask.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTask.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTask.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTasks.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTasks.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTasks.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/EditableSubTasks.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/types.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/types.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/types.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/types.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/utils.ts b/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/utils.ts similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/utils.ts rename to components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/EditableSubTasks/utils.ts diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/TaskCardDialog.tsx b/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/TaskCardDialog.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/TaskCardDialog.tsx rename to components/planner/Board/TaskColumns/TaskCard/TaskCardDialog/TaskCardDialog.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskCard/utils.ts b/components/planner/Board/TaskColumns/TaskCard/utils.ts similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskCard/utils.ts rename to components/planner/Board/TaskColumns/TaskCard/utils.ts diff --git a/frontend/components/planner/Board/TaskColumns/TaskColumn.tsx b/components/planner/Board/TaskColumns/TaskColumn.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskColumn.tsx rename to components/planner/Board/TaskColumns/TaskColumn.tsx diff --git a/frontend/components/planner/Board/TaskColumns/TaskColumns.tsx b/components/planner/Board/TaskColumns/TaskColumns.tsx similarity index 100% rename from frontend/components/planner/Board/TaskColumns/TaskColumns.tsx rename to components/planner/Board/TaskColumns/TaskColumns.tsx diff --git a/frontend/components/planner/Board/TaskColumns/helpers.ts b/components/planner/Board/TaskColumns/helpers.ts similarity index 100% rename from frontend/components/planner/Board/TaskColumns/helpers.ts rename to components/planner/Board/TaskColumns/helpers.ts diff --git a/frontend/components/planner/Board/TaskColumns/initial-data-v2.js b/components/planner/Board/TaskColumns/initial-data-v2.js similarity index 100% rename from frontend/components/planner/Board/TaskColumns/initial-data-v2.js rename to components/planner/Board/TaskColumns/initial-data-v2.js diff --git a/frontend/components/planner/Board/TaskColumns/initial-data.js b/components/planner/Board/TaskColumns/initial-data.js similarity index 100% rename from frontend/components/planner/Board/TaskColumns/initial-data.js rename to components/planner/Board/TaskColumns/initial-data.js diff --git a/frontend/components/planner/Board/TaskFilterSearchBar.tsx b/components/planner/Board/TaskFilterSearchBar.tsx similarity index 100% rename from frontend/components/planner/Board/TaskFilterSearchBar.tsx rename to components/planner/Board/TaskFilterSearchBar.tsx diff --git a/frontend/components/planner/Planner.tsx b/components/planner/Planner.tsx similarity index 100% rename from frontend/components/planner/Planner.tsx rename to components/planner/Planner.tsx diff --git a/frontend/components/planner/Sidebar/ArchiveModeToggle.tsx b/components/planner/Sidebar/ArchiveModeToggle.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ArchiveModeToggle.tsx rename to components/planner/Sidebar/ArchiveModeToggle.tsx diff --git a/frontend/components/planner/Sidebar/EventCalendar.tsx b/components/planner/Sidebar/EventCalendar.tsx similarity index 100% rename from frontend/components/planner/Sidebar/EventCalendar.tsx rename to components/planner/Sidebar/EventCalendar.tsx diff --git a/frontend/components/planner/Sidebar/LiveDate.tsx b/components/planner/Sidebar/LiveDate.tsx similarity index 100% rename from frontend/components/planner/Sidebar/LiveDate.tsx rename to components/planner/Sidebar/LiveDate.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardButton.tsx b/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardButton.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardButton.tsx rename to components/planner/Sidebar/ManageBoardsDialog/AddNewBoardButton.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardDialogContent.tsx b/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardDialogContent.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardDialogContent.tsx rename to components/planner/Sidebar/ManageBoardsDialog/AddNewBoardDialogContent.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardForm.tsx b/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardForm.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/AddNewBoardForm.tsx rename to components/planner/Sidebar/ManageBoardsDialog/AddNewBoardForm.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/DeleteBoardConfirmDialog.tsx b/components/planner/Sidebar/ManageBoardsDialog/DeleteBoardConfirmDialog.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/DeleteBoardConfirmDialog.tsx rename to components/planner/Sidebar/ManageBoardsDialog/DeleteBoardConfirmDialog.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsDialog.tsx b/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsDialog.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsDialog.tsx rename to components/planner/Sidebar/ManageBoardsDialog/ManageBoardsDialog.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx b/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx rename to components/planner/Sidebar/ManageBoardsDialog/ManageBoardsSheetTrigger.tsx diff --git a/frontend/components/planner/Sidebar/ManageBoardsDialog/ModifyBoardDialogContent.tsx b/components/planner/Sidebar/ManageBoardsDialog/ModifyBoardDialogContent.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageBoardsDialog/ModifyBoardDialogContent.tsx rename to components/planner/Sidebar/ManageBoardsDialog/ModifyBoardDialogContent.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryButton.tsx b/components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryButton.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryButton.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryButton.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryDialogContent.tsx b/components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryDialogContent.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryDialogContent.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/AddNewCategoryDialogContent.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/CategoryColorPicker.tsx b/components/planner/Sidebar/ManageCategoriesDialog/CategoryColorPicker.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/CategoryColorPicker.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/CategoryColorPicker.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/DeleteCategoryConfirmDialog.tsx b/components/planner/Sidebar/ManageCategoriesDialog/DeleteCategoryConfirmDialog.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/DeleteCategoryConfirmDialog.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/DeleteCategoryConfirmDialog.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesDialog.tsx b/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesDialog.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesDialog.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesDialog.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx b/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/ManageCategoriesSheetTrigger.tsx diff --git a/frontend/components/planner/Sidebar/ManageCategoriesDialog/ModifyCategoryDialogContent.tsx b/components/planner/Sidebar/ManageCategoriesDialog/ModifyCategoryDialogContent.tsx similarity index 100% rename from frontend/components/planner/Sidebar/ManageCategoriesDialog/ModifyCategoryDialogContent.tsx rename to components/planner/Sidebar/ManageCategoriesDialog/ModifyCategoryDialogContent.tsx diff --git a/frontend/components/planner/Sidebar/Sidebar.tsx b/components/planner/Sidebar/Sidebar.tsx similarity index 100% rename from frontend/components/planner/Sidebar/Sidebar.tsx rename to components/planner/Sidebar/Sidebar.tsx diff --git a/frontend/components/planner/SignInCallout.tsx b/components/planner/SignInCallout.tsx similarity index 100% rename from frontend/components/planner/SignInCallout.tsx rename to components/planner/SignInCallout.tsx diff --git a/frontend/components/planner/utils.ts b/components/planner/utils.ts similarity index 100% rename from frontend/components/planner/utils.ts rename to components/planner/utils.ts diff --git a/frontend/components/theme-provider.tsx b/components/theme-provider.tsx similarity index 100% rename from frontend/components/theme-provider.tsx rename to components/theme-provider.tsx diff --git a/frontend/components/ui/alert-dialog.tsx b/components/ui/alert-dialog.tsx similarity index 100% rename from frontend/components/ui/alert-dialog.tsx rename to components/ui/alert-dialog.tsx diff --git a/frontend/components/ui/alert.tsx b/components/ui/alert.tsx similarity index 100% rename from frontend/components/ui/alert.tsx rename to components/ui/alert.tsx diff --git a/frontend/components/ui/aurora-background.tsx b/components/ui/aurora-background.tsx similarity index 100% rename from frontend/components/ui/aurora-background.tsx rename to components/ui/aurora-background.tsx diff --git a/frontend/components/ui/avatar.tsx b/components/ui/avatar.tsx similarity index 100% rename from frontend/components/ui/avatar.tsx rename to components/ui/avatar.tsx diff --git a/frontend/components/ui/background-boxes.tsx b/components/ui/background-boxes.tsx similarity index 100% rename from frontend/components/ui/background-boxes.tsx rename to components/ui/background-boxes.tsx diff --git a/frontend/components/ui/badge.tsx b/components/ui/badge.tsx similarity index 100% rename from frontend/components/ui/badge.tsx rename to components/ui/badge.tsx diff --git a/frontend/components/ui/button.tsx b/components/ui/button.tsx similarity index 100% rename from frontend/components/ui/button.tsx rename to components/ui/button.tsx diff --git a/frontend/components/ui/calendar.tsx b/components/ui/calendar.tsx similarity index 100% rename from frontend/components/ui/calendar.tsx rename to components/ui/calendar.tsx diff --git a/frontend/components/ui/card.tsx b/components/ui/card.tsx similarity index 100% rename from frontend/components/ui/card.tsx rename to components/ui/card.tsx diff --git a/frontend/components/ui/checkbox.tsx b/components/ui/checkbox.tsx similarity index 100% rename from frontend/components/ui/checkbox.tsx rename to components/ui/checkbox.tsx diff --git a/frontend/components/ui/command.tsx b/components/ui/command.tsx similarity index 100% rename from frontend/components/ui/command.tsx rename to components/ui/command.tsx diff --git a/frontend/components/ui/context-menu.tsx b/components/ui/context-menu.tsx similarity index 100% rename from frontend/components/ui/context-menu.tsx rename to components/ui/context-menu.tsx diff --git a/frontend/components/ui/dialog.tsx b/components/ui/dialog.tsx similarity index 100% rename from frontend/components/ui/dialog.tsx rename to components/ui/dialog.tsx diff --git a/frontend/components/ui/dropdown-menu.tsx b/components/ui/dropdown-menu.tsx similarity index 100% rename from frontend/components/ui/dropdown-menu.tsx rename to components/ui/dropdown-menu.tsx diff --git a/frontend/components/ui/form.tsx b/components/ui/form.tsx similarity index 100% rename from frontend/components/ui/form.tsx rename to components/ui/form.tsx diff --git a/frontend/components/ui/glowing-stars.tsx b/components/ui/glowing-stars.tsx similarity index 100% rename from frontend/components/ui/glowing-stars.tsx rename to components/ui/glowing-stars.tsx diff --git a/frontend/components/ui/input.tsx b/components/ui/input.tsx similarity index 100% rename from frontend/components/ui/input.tsx rename to components/ui/input.tsx diff --git a/frontend/components/ui/label.tsx b/components/ui/label.tsx similarity index 100% rename from frontend/components/ui/label.tsx rename to components/ui/label.tsx diff --git a/frontend/components/ui/menubar.tsx b/components/ui/menubar.tsx similarity index 100% rename from frontend/components/ui/menubar.tsx rename to components/ui/menubar.tsx diff --git a/frontend/components/ui/moving-border.tsx b/components/ui/moving-border.tsx similarity index 100% rename from frontend/components/ui/moving-border.tsx rename to components/ui/moving-border.tsx diff --git a/frontend/components/ui/multi-step-loader.tsx b/components/ui/multi-step-loader.tsx similarity index 100% rename from frontend/components/ui/multi-step-loader.tsx rename to components/ui/multi-step-loader.tsx diff --git a/frontend/components/ui/popover.tsx b/components/ui/popover.tsx similarity index 100% rename from frontend/components/ui/popover.tsx rename to components/ui/popover.tsx diff --git a/frontend/components/ui/progress.tsx b/components/ui/progress.tsx similarity index 100% rename from frontend/components/ui/progress.tsx rename to components/ui/progress.tsx diff --git a/frontend/components/ui/scroll-area.tsx b/components/ui/scroll-area.tsx similarity index 100% rename from frontend/components/ui/scroll-area.tsx rename to components/ui/scroll-area.tsx diff --git a/frontend/components/ui/select.tsx b/components/ui/select.tsx similarity index 100% rename from frontend/components/ui/select.tsx rename to components/ui/select.tsx diff --git a/frontend/components/ui/separator.tsx b/components/ui/separator.tsx similarity index 100% rename from frontend/components/ui/separator.tsx rename to components/ui/separator.tsx diff --git a/frontend/components/ui/sheet.tsx b/components/ui/sheet.tsx similarity index 100% rename from frontend/components/ui/sheet.tsx rename to components/ui/sheet.tsx diff --git a/frontend/components/ui/tabs.tsx b/components/ui/tabs.tsx similarity index 100% rename from frontend/components/ui/tabs.tsx rename to components/ui/tabs.tsx diff --git a/frontend/components/ui/textarea.tsx b/components/ui/textarea.tsx similarity index 100% rename from frontend/components/ui/textarea.tsx rename to components/ui/textarea.tsx diff --git a/frontend/components/ui/toast.tsx b/components/ui/toast.tsx similarity index 100% rename from frontend/components/ui/toast.tsx rename to components/ui/toast.tsx diff --git a/frontend/components/ui/toaster.tsx b/components/ui/toaster.tsx similarity index 100% rename from frontend/components/ui/toaster.tsx rename to components/ui/toaster.tsx diff --git a/frontend/components/ui/tooltip.tsx b/components/ui/tooltip.tsx similarity index 100% rename from frontend/components/ui/tooltip.tsx rename to components/ui/tooltip.tsx diff --git a/frontend/components/ui/use-toast.ts b/components/ui/use-toast.ts similarity index 100% rename from frontend/components/ui/use-toast.ts rename to components/ui/use-toast.ts diff --git a/frontend/config/mongo-client.ts b/config/mongo-client.ts similarity index 100% rename from frontend/config/mongo-client.ts rename to config/mongo-client.ts diff --git a/frontend/constants/constants.ts b/constants/constants.ts similarity index 100% rename from frontend/constants/constants.ts rename to constants/constants.ts diff --git a/frontend/docs/database.drawio b/docs/database.drawio similarity index 100% rename from frontend/docs/database.drawio rename to docs/database.drawio diff --git a/frontend/hooks/Planner/Planner.tsx b/hooks/Planner/Planner.tsx similarity index 100% rename from frontend/hooks/Planner/Planner.tsx rename to hooks/Planner/Planner.tsx diff --git a/frontend/hooks/Planner/plannerReducer.tsx b/hooks/Planner/plannerReducer.tsx similarity index 100% rename from frontend/hooks/Planner/plannerReducer.tsx rename to hooks/Planner/plannerReducer.tsx diff --git a/frontend/hooks/Planner/types.tsx b/hooks/Planner/types.tsx similarity index 100% rename from frontend/hooks/Planner/types.tsx rename to hooks/Planner/types.tsx diff --git a/frontend/hooks/PlannerFilters/PlannerFilters.tsx b/hooks/PlannerFilters/PlannerFilters.tsx similarity index 100% rename from frontend/hooks/PlannerFilters/PlannerFilters.tsx rename to hooks/PlannerFilters/PlannerFilters.tsx diff --git a/frontend/lib/dbConnect.ts b/lib/dbConnect.ts similarity index 100% rename from frontend/lib/dbConnect.ts rename to lib/dbConnect.ts diff --git a/frontend/lib/middleware.ts b/lib/middleware.ts similarity index 100% rename from frontend/lib/middleware.ts rename to lib/middleware.ts diff --git a/frontend/lib/utils.ts b/lib/utils.ts similarity index 100% rename from frontend/lib/utils.ts rename to lib/utils.ts diff --git a/frontend/middleware.ts b/middleware.ts similarity index 100% rename from frontend/middleware.ts rename to middleware.ts diff --git a/frontend/models/Planner.ts b/models/Planner.ts similarity index 100% rename from frontend/models/Planner.ts rename to models/Planner.ts diff --git a/frontend/next.config.js b/next.config.js similarity index 100% rename from frontend/next.config.js rename to next.config.js diff --git a/frontend/package-lock.json b/package-lock.json similarity index 100% rename from frontend/package-lock.json rename to package-lock.json diff --git a/frontend/package.json b/package.json similarity index 100% rename from frontend/package.json rename to package.json diff --git a/frontend/postcss.config.js b/postcss.config.js similarity index 100% rename from frontend/postcss.config.js rename to postcss.config.js diff --git a/frontend/tailwind.config.js b/tailwind.config.js similarity index 100% rename from frontend/tailwind.config.js rename to tailwind.config.js diff --git a/frontend/tailwind.config.ts b/tailwind.config.ts similarity index 100% rename from frontend/tailwind.config.ts rename to tailwind.config.ts diff --git a/frontend/tsconfig.json b/tsconfig.json similarity index 100% rename from frontend/tsconfig.json rename to tsconfig.json