diff --git a/package-lock.json b/package-lock.json index 4c126e37b1c090602b921df4b333e28f89c97d98..459b2227cce39d19951c37da3eba4458035b75f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,12 @@ "version": "0.1.0", "dependencies": { "@tailwindcss/aspect-ratio": "^0.4.2", + "chroma-js": "^2.4.2", "jose": "^5.3.0", "js-cookie": "^3.0.5", "next": "14.2.3", "react": "^18", + "react-chartjs-2": "^5.2.0", "react-dom": "^18", "react-select": "^5.8.0" }, @@ -2330,6 +2332,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==", + "peer": true + }, "node_modules/@next/env": { "version": "14.2.3", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.3.tgz", @@ -3536,6 +3544,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chart.js": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", + "peer": true, + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3570,6 +3590,11 @@ "node": ">= 6" } }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -6501,6 +6526,15 @@ "node": ">=0.10.0" } }, + "node_modules/react-chartjs-2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz", + "integrity": "sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA==", + "peerDependencies": { + "chart.js": "^4.1.1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", diff --git a/package.json b/package.json index 7cf3ab137ad85490f4f24efc84cbf4dd60903081..f9e94e36ed36bfa864f43a911327d1743842b629 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ }, "dependencies": { "@tailwindcss/aspect-ratio": "^0.4.2", + "chroma-js": "^2.4.2", "jose": "^5.3.0", "js-cookie": "^3.0.5", "next": "14.2.3", "react": "^18", + "react-chartjs-2": "^5.2.0", "react-dom": "^18", "react-select": "^5.8.0" }, diff --git a/src/app/(dashboard)/assign-zone-project/AssignProject.jsx b/src/app/(dashboard)/assign-zone-project/AssignProject.jsx index 3c923a83f0492ba33864c5cedcb94cf62bc572dd..55660685e12137e733a32d1c931aebc826531736 100644 --- a/src/app/(dashboard)/assign-zone-project/AssignProject.jsx +++ b/src/app/(dashboard)/assign-zone-project/AssignProject.jsx @@ -3,7 +3,7 @@ import React, { useState, useEffect, useRef } from 'react' import { useNotification } from '@/context/NotificationContext' import CancelIcon from "@/static/image/svg/cancel.svg" import UserIcon from "@/static/image/svg/user.svg" -import DeskIcon from "@/static/image/svg/study-desk.svg" +import DeskIcon from "@/static/image/svg/desk-1.svg" import fetchRequest from "@/app/lib/fetchRequest"; diff --git a/src/app/(dashboard)/assign-zone-project/CompleteAffectation.jsx b/src/app/(dashboard)/assign-zone-project/CompleteAffectation.jsx index 76045feeb37275237416da5c038a4c6d39c8e69c..649f94f5d491e9e87781281f842dc8636725e4ff 100644 --- a/src/app/(dashboard)/assign-zone-project/CompleteAffectation.jsx +++ b/src/app/(dashboard)/assign-zone-project/CompleteAffectation.jsx @@ -3,7 +3,7 @@ import React, { useState, useEffect, useRef } from 'react' import { useNotification } from '@/context/NotificationContext' import CancelIcon from "@/static/image/svg/cancel.svg" import UserIcon from "@/static/image/svg/user.svg" -import DeskIcon from "@/static/image/svg/study-desk.svg" +import DeskIcon from "@/static/image/svg/desk-1.svg" import AddIcon from "@/static/image/svg/add.svg" import fetchRequest from "@/app/lib/fetchRequest"; import Loader from '@/components/Loader/Loader' diff --git a/src/app/(dashboard)/planning/PlanningTable.jsx b/src/app/(dashboard)/planning/PlanningTable.jsx index 34228d79a8940601c5a65af20d0004f6c113bf71..0db1822080d008a6a286261b3dfbb57f361cd64f 100644 --- a/src/app/(dashboard)/planning/PlanningTable.jsx +++ b/src/app/(dashboard)/planning/PlanningTable.jsx @@ -20,7 +20,7 @@ const PlanningTable = ({ data, typePresences, onTypePresenceChange, selectedProj }; return ( -
+
Réglez Tout sur : {typePresences.map((typePresence) => ( diff --git a/src/app/(dashboard)/reporting/page.jsx b/src/app/(dashboard)/reporting/page.jsx index 524f1e8cd9d79386e1a36e0a0ac2995a56ede2fe..47058e4bce01ba403b2a2878ac147e39372cbd40 100644 --- a/src/app/(dashboard)/reporting/page.jsx +++ b/src/app/(dashboard)/reporting/page.jsx @@ -7,6 +7,10 @@ import fetchRequest from '@/app/lib/fetchRequest'; import Loader from '@/components/Loader/Loader'; import { useNotification } from '@/context/NotificationContext'; import { extractDate, getDateRange, subtractDays } from '@/app/lib/DateHelper'; +import UserIcon from "@/static/image/svg/user.svg" +import ProjectIcon from "@/static/image/svg/project.svg" +import StatisticsIcon from "@/static/image/svg/statistics.svg" +import DeskIcon from "@/static/image/svg/desk-1.svg" const Reporting = () => { @@ -14,8 +18,36 @@ const Reporting = () => { const [chartDataProject, setChartDataProject] = useState(null) const [isLoadingZone, setIsLoadingZone] = useState(false) const [isLoadingProject, setIsLoadingProject] = useState(false) + const [ countUsers, setCountUsers ] = useState(0) + const [ countProjects, setCountProjects ] = useState(0) + const [ countPlaces, setCountPlaces ] = useState(0) const { toggleNotification } = useNotification() const [dates, setDates] = useState({ fromDate: extractDate(subtractDays(new Date(), 4)), toDate: extractDate(new Date()) }) + + useEffect(() => { + const getStats= async () => { + const { data, errors, isSuccess } = await fetchRequest(`/statistics/`, { + method: "GET", + }) + if (isSuccess) { + setCountUsers(data.user_count) + setCountProjects(data.project_count) + setCountPlaces(data.place_count) + } else { + console.log(errors); + toggleNotification({ + type: "error", + message: "Internal Server Error", + visible: true + }) + } + } + getStats() + }, []) + console.log(countPlaces) + console.log(countProjects) + console.log(countUsers) + useEffect(() => { const getZonesPresenceStatistic = async () => { setIsLoadingZone(true) @@ -115,15 +147,47 @@ const Reporting = () => { }, [chartDataZone, axisX]) return (
-
-
- - +
+
+

Collaborateurs

+
+ {countUsers} +
+ + +
+
+
+
+

Projets

+
+ {countProjects} +
+ + +
+
+
+
+

Places

+
+ {countPlaces} +
+ + +
+
-
- - - {/* */} +
+
+ + +
+
+ + + {/* */} +
{(isLoadingZone || isLoadingProject) ?
diff --git a/src/app/no-access/page.jsx b/src/app/no-access/page.jsx index df868666c1e21c24fe3e5e04a536d78f87f145bb..62db6653d899d89755ef65932715652413d98c85 100644 --- a/src/app/no-access/page.jsx +++ b/src/app/no-access/page.jsx @@ -8,6 +8,8 @@ export default function NoAccess() { useEffect(() => { const interval = setInterval(() => { + // never allow countdown to go below 0 + if (countdown === 0) return; setCountdown(prevCountdown => prevCountdown - 1); }, 1000); diff --git a/src/app/ui/Header.jsx b/src/app/ui/Header.jsx index 4112e77a7e7f45f1b4649b876531e297915da56a..13bc0221faba899a5b28461da7c20f2c021567c4 100644 --- a/src/app/ui/Header.jsx +++ b/src/app/ui/Header.jsx @@ -4,6 +4,8 @@ import Link from 'next/link'; import isAuthenticatedSSR from "@/app/lib/isAuthenticatedSSR"; import LogoutButton from "@/app/ui/LogoutButton"; import Burger from './Burger'; +import Image from "next/image"; +import logo from "@/static/image/teamwill_logo.png"; const Header = async () => { @@ -11,23 +13,24 @@ const Header = async () => { console.log('isAuth', isAuth) console.log('sessionData', sessionData) return ( -
+
- -

TeamBook

+ + logo +

TeamBook