diff --git a/.eslintrc.json b/.eslintrc.json index f7af4a62c..f00583812 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,12 @@ "browser": true, "es2021": true }, - "extends": ["next/core-web-vitals", "google", "prettier"], + "extends": [ + "next/core-web-vitals", + "google", + "prettier", + "plugin:@tanstack/eslint-plugin-query/recommended" + ], "overrides": [], "parserOptions": { "ecmaVersion": "latest", diff --git a/package-lock.json b/package-lock.json index a4b0e1789..02e411361 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,8 @@ "@radix-ui/react-tabs": "^1.1.0", "@react-email/components": "^0.0.25", "@tailwindcss/typography": "^0.5.15", + "@tanstack/react-query": "^5.51.11", + "@tanstack/react-query-devtools": "^5.55.0", "@tanstack/react-table": "^8.20.5", "@tanstack/react-virtual": "^3.10.6", "class-variance-authority": "^0.7.0", @@ -63,6 +65,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@tanstack/eslint-plugin-query": "^5.51.13", "@types/node": "^20.16.1", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", @@ -3215,6 +3218,76 @@ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" } }, + "node_modules/@tanstack/eslint-plugin-query": { + "version": "5.53.0", + "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.53.0.tgz", + "integrity": "sha512-Q3WgvK2YTGc3h5EaktDouRkKBPGl3QQFLPZBagpBa6zD70PiNoDY72wWrX9T4yKClMmSulAa0wg5Nj3LVXGkEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.3.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.54.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.54.1.tgz", + "integrity": "sha512-hKS+WRpT5zBFip21pB6Jx1C0hranWQrbv5EJ7qPoiV5MYI3C8rTCqWC9DdBseiPT1JgQWh8Y55YthuYZNiw3Xw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.54.0.tgz", + "integrity": "sha512-B8Sa6mh7/4m2fyk2/YnUXeOZ1/us7G/C/i1It8YcCbieXc8vf1AdSYjR+mZIoJeKOKLqA741hZqfj8d4F1NCVg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.55.0.tgz", + "integrity": "sha512-2uYuxEbRQD8TORUiTUacEOwt1e8aoSqUOJFGY5TUrh6rQ3U85zrMS2wvbNhBhXGh6Vj69QDCP2yv8tIY7joo6Q==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.54.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.55.0.tgz", + "integrity": "sha512-omUloSS7Ru+LNmXeK56ygtAgMXMR5M74v8kn4lRjMkjT/aTJHWGI2yJh0I1EE1a8tjwXyviqy+qWfJaeqQcTIA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-devtools": "5.54.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.55.0", + "react": "^18 || ^19" + } + }, "node_modules/@tanstack/react-table": { "version": "8.20.5", "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.5.tgz", @@ -3790,6 +3863,134 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@typescript-eslint/utils": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz", + "integrity": "sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.4.0", + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/typescript-estree": "8.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz", + "integrity": "sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz", + "integrity": "sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz", + "integrity": "sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz", + "integrity": "sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.4.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", diff --git a/package.json b/package.json index c2e265857..99c2690bc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "prepare": "husky install" }, "devDependencies": { + "@tanstack/eslint-plugin-query": "^5.51.13", "@types/node": "^20.16.1", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", @@ -49,6 +50,8 @@ "@radix-ui/react-tabs": "^1.1.0", "@react-email/components": "^0.0.25", "@tailwindcss/typography": "^0.5.15", + "@tanstack/react-query": "^5.51.11", + "@tanstack/react-query-devtools": "^5.55.0", "@tanstack/react-table": "^8.20.5", "@tanstack/react-virtual": "^3.10.6", "class-variance-authority": "^0.7.0", diff --git a/src/app/admin/[type]/page.js b/src/app/admin/[type]/page.js index 14256428c..82dec4c2b 100644 --- a/src/app/admin/[type]/page.js +++ b/src/app/admin/[type]/page.js @@ -1,8 +1,8 @@ "use client"; import ProtectedPage from "@/components/ProtectedPage"; import Admins from "@/components/admin/dashboards/Admins"; -import Events from "@/components/admin/services/calendar/Events"; -import CheckIn from "@/components/admin/services/checkin/CheckIn"; +import Events from "@/components/admin/services/calendar"; +import CheckIn from "@/components/admin/services/checkin"; import Committees from "@/components/admin/dashboards/Committees"; import Feedback from "@/components/admin/dashboards/Feedback"; import Interests from "@/components/admin/dashboards/Interests"; diff --git a/src/app/api/statistics/route.js b/src/app/api/statistics/route.js deleted file mode 100644 index b2623ebea..000000000 --- a/src/app/api/statistics/route.js +++ /dev/null @@ -1,82 +0,0 @@ -import { NextResponse } from "next/server"; -import { db } from "../../../utils/firebase"; -import { collection, getDocs, getDoc, doc } from "firebase/firestore"; -import { authenticate } from "@/utils/auth"; - -export const GET = async () => { - const res = NextResponse; - - const { auth } = await authenticate({ - admins: [1], - }); - - if (auth !== 200) { - return res.json( - { message: `Authentication Error: ${"MESSAGE VARIABLE SHOULD BE HERE"}` }, - { status: auth }, - ); - } - - try { - const [statistics, events] = await Promise.all([ - getDoc(doc(db, "statistics", "statistics")), - getDocs(collection(db, "events")), - ]); - const { - teams, - participants, - volunteers, - judges, - mentors, - committees, - sponsors, - panels, - admins, - } = statistics.data(); - - const attendees = {}; - - events.forEach((doc) => { - const { name, attendance } = doc.data(); - attendees[name] = attendance; - }); - - const users = { - participants, - teams, - judges, - volunteers, - mentors, - committees, - sponsors, - panels, - admins, - }; - - const sizeData = ["XS", "S", "M", "L", "XL", "XXL"]; - const statusData = ["1", "0", "-1"]; - - const size = {}; - const status = {}; - - Object.entries(users).forEach(([group, entries]) => { - size[group] = Object.fromEntries( - Object.entries(entries).filter(([key]) => sizeData.includes(key)), - ); - - status[group] = Object.fromEntries( - Object.entries(entries).filter(([key]) => statusData.includes(key)), - ); - }); - - return res.json( - { items: { users: { status, size }, events: attendees } }, - { status: 200 }, - ); - } catch (err) { - return res.json( - { message: `Internal Server Error: ${err}` }, - { status: 500 }, - ); - } -}; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 2ee7f87a3..7440aa4de 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,7 +1,7 @@ /* eslint-disable new-cap */ import "./globals.css"; import { Poppins } from "next/font/google"; -import Session from "@/components/Session"; +import Providers from "@/components/Providers"; import { Toaster } from "react-hot-toast"; import { getServerSession } from "next-auth"; import { options } from "@/utils/auth"; @@ -24,10 +24,10 @@ const RootLayout = async ({ children }: Props) => {
{view === "month" && ( <> - {new Date(event.start).toLocaleTimeString(navigator.language, { + {new Date(event.startDate).toLocaleTimeString(navigator.language, { hour: "2-digit", minute: "2-digit", })} diff --git a/src/components/admin/services/calendar/Events.jsx b/src/components/admin/services/calendar/Events.jsx deleted file mode 100644 index 86cbc6bd3..000000000 --- a/src/components/admin/services/calendar/Events.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import "react-big-calendar/lib/css/react-big-calendar.css"; -import { LABELS } from "@/data/admin/Calendar"; -import { api } from "@/utils/api"; -import CalendarWrapper from "./CalendarWrapper"; - -const CalendarEvents = async () => { - const min = new Date( - new Date().getTime() - 20 * 7 * 24 * 60 * 60 * 1000, - ).toISOString(); - - const max = new Date( - new Date().getTime() + 20 * 7 * 24 * 60 * 60 * 1000, - ).toISOString(); - - const hackathon = await api({ - method: "GET", - url: `https://www.googleapis.com/calendar/v3/calendars/${process.env.NEXT_PUBLIC_GOOGLE_CALENDAR}/events?key=${process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_API_KEY}&singleEvents=true&orderBy=startTime&timeMin=${min}&timeMax=${max}`, - }); - - const leads = await api({ - method: "GET", - url: `https://www.googleapis.com/calendar/v3/calendars/${process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_LEADS}/events?key=${process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_API_KEY}&singleEvents=true&orderBy=startTime&timeMin=${min}&timeMax=${max}`, - }); - - const hackathonItems = hackathon.items; - const leadsItems = leads.items; - - const rawEvents = [...hackathonItems, ...leadsItems]; - - rawEvents.forEach((item) => { - item.start = new Date(item.start.dateTime); - item.end = new Date(item.end.dateTime); - const [category, assignee] = item.description - .split("\n")[0] - .split("#") - .map((item) => item.trim()) - .filter((item) => item !== ""); - item.category = category; - item.color = LABELS[item.category].background; - item.assignee = assignee; - item.hidden = false; - }); - - return ( -