diff --git a/.env b/.env new file mode 100644 index 0000000..50dcc6e --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VITE_API_URL=localhost:80 \ No newline at end of file diff --git a/.gitignore b/.gitignore index bd7187d..0fc3e15 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.env + # Logs logs *.log diff --git a/index.html b/index.html index 764759f..7ecd944 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,9 @@ - + - sae-front + Comité des fêtes de Beaupont
diff --git a/package-lock.json b/package-lock.json index 132710e..1ef73dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -439,7 +439,6 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -483,7 +482,6 @@ "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -529,278 +527,6 @@ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", "license": "MIT" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@esbuild/linux-x64": { "version": "0.25.10", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", @@ -818,159 +544,6 @@ "node": ">=18" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -1402,9 +975,9 @@ } }, "node_modules/@mui/material/node_modules/react-is": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", - "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.1.tgz", + "integrity": "sha512-L7BnWgRbMwzMAubQcS7sXdPdNLmKlucPlopgAzx7FtYbksWZgEWiuYM5x9T6UqS2Ne0rsgQTq5kY2SGqpzUkYA==", "license": "MIT" }, "node_modules/@mui/private-theming": { @@ -1556,9 +1129,9 @@ } }, "node_modules/@mui/utils/node_modules/react-is": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", - "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.1.tgz", + "integrity": "sha512-L7BnWgRbMwzMAubQcS7sXdPdNLmKlucPlopgAzx7FtYbksWZgEWiuYM5x9T6UqS2Ne0rsgQTq5kY2SGqpzUkYA==", "license": "MIT" }, "node_modules/@neoconfetti/react": { @@ -1629,7 +1202,6 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -1734,216 +1306,6 @@ } } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", - "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", - "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", - "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", - "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", - "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", - "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", - "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", - "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", - "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", - "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", - "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", - "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", - "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", - "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", - "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.52.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", @@ -1972,76 +1334,6 @@ "linux" ] }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", - "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", - "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", - "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", - "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.52.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", - "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@standard-schema/spec": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", @@ -2274,9 +1566,9 @@ } }, "node_modules/@swc/helpers": { - "version": "0.5.18", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", - "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" @@ -3120,9 +2412,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3502,6 +2794,16 @@ "csstype": "^3.0.2" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4014,21 +3316,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6442,6 +5729,24 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/public/bell.svg b/public/bell.svg index 54defaf..1e80c60 100644 --- a/public/bell.svg +++ b/public/bell.svg @@ -1,3 +1,3 @@ - + diff --git a/public/filter.svg b/public/filter.svg new file mode 100644 index 0000000..6096a31 --- /dev/null +++ b/public/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logoIcone.png b/public/logoIcone.png new file mode 100644 index 0000000..b8baa92 Binary files /dev/null and b/public/logoIcone.png differ diff --git a/public/sortByAntiAlpha.svg b/public/sortByAntiAlpha.svg index f74e5d8..adea5c6 100644 --- a/public/sortByAntiAlpha.svg +++ b/public/sortByAntiAlpha.svg @@ -1,4 +1,4 @@ - + diff --git a/src/components/Filter/Filter.jsx b/src/components/Filter/Filter.jsx index 6e70259..3dcf4ae 100644 --- a/src/components/Filter/Filter.jsx +++ b/src/components/Filter/Filter.jsx @@ -20,38 +20,28 @@ function Filter({isFilterVisible, filters, setFilters}){ Tri alphabétique croissant (A à Z) diff --git a/src/components/Filter/Filter.module.css b/src/components/Filter/Filter.module.css index 38902fc..030dbe5 100644 --- a/src/components/Filter/Filter.module.css +++ b/src/components/Filter/Filter.module.css @@ -35,31 +35,14 @@ .filterTag:focus { outline: none; } -.filterTag:focus-visible { - outline: 2px solid black; -} .filterTag:hover { cursor: pointer; - svg{ - fill: #019AFF; - } -} - - -.filterTag svg { - transform: scale(0.7); - color: black; } .active { - border: 1px solid #019AFF; -} - -.active svg { - fill: #019AFF; - transform: scale(0.8); + border: 2px solid #019AFF; } @media screen and (max-width: 768px){ diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx index 14043a7..873c250 100644 --- a/src/components/Header/Header.jsx +++ b/src/components/Header/Header.jsx @@ -1,15 +1,17 @@ import styles from "./Header.module.css" import { Link, NavLink } from "react-router"; -import { useEffect, useRef, useState } from "react"; +import {useContext, useEffect, useRef, useState} from "react"; import getUserNotifications from "../../utils/getUserNotifications.js"; +import {AuthContext} from "../../contexts/auth/AuthContext.js"; function Header() { const [notificationMenu, setnotificationMenu] = useState(false); const [unreadNotification, setunreadNotification] = useState(true); const [mobileMenu, setMobileMenu] = useState(false); - const [notifications, setNotifications] = useState([]); + const [notifications, setNotifications] = useState([{"content" : "ok"}, {"content" : "pourquoi pas antoine"}]); const notificationRef = useRef(null); + const { user } = useContext(AuthContext); useEffect(() => { @@ -41,7 +43,7 @@ function Header() { @@ -88,6 +87,7 @@ function Header() { isActive ? styles.activeLink : styles.link}> Bénévoles + @@ -109,7 +109,7 @@ function Header() { className={`${styles.notificationDiv} glassCard ${notificationMenu ? styles.activeNotificationDiv : ""}`} > {notifications.length === 0 ? ( -

Vous n'avez aucune notification !

+

Vous n'avez aucune notification !

) : ( notifications.map((notification, index) => (
@@ -118,9 +118,7 @@ function Header() { className={styles.closeBtn} onClick={() => setNotifications(prev => prev.filter((_, i) => i !== index))} > - - - + supprimer la notification
)) diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css index 4aba8b2..eac6e90 100644 --- a/src/components/Header/Header.module.css +++ b/src/components/Header/Header.module.css @@ -26,25 +26,16 @@ pointer-events: auto; } .inactiveHeaderContent{ - opacity: 0; - pointer-events: none; - transition: opacity 0.3s ease; - position: absolute; - top: 0.8rem; - left: 0.8rem; + display: none; } .inactiveMobileMenu{ - max-height: 0; - position: absolute; - top: 100%; - left: 0; + display: none; } .activeMobileMenu{ - transition: max-height 3s ease; - max-height: 500px; + height: fit-content; display: flex; flex-direction: column; align-items: start; @@ -105,10 +96,6 @@ border-bottom: 2px solid #019AFF; } -svg { - width: fit-content; -} - .bellBtn, .profileLink { display: flex; align-items: center; @@ -124,11 +111,12 @@ svg { position: relative; } -.bellBtn svg { +.notificationsImg { stroke: black; stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; + height: 28px; } .bellBtn:focus { @@ -141,33 +129,22 @@ svg { .activeBellBtn { transform: translateY(-4px); background: rgba(191, 191, 191, 0.5); - svg { - stroke: #019AFF; - } } + .bellBtn:hover { transform: translateY(-4px); background: rgba(191, 191, 191, 0.5); - svg { - stroke: #019AFF; - } } .profileLink:hover { transform: translateY(-4px); background: rgba(191, 191, 191, 0.5); - svg { - fill: #019AFF; - } } -.bellBtn svg { - height: 28px; -} -.profileLink svg { +.profileImg { height: 40px; } @@ -185,15 +162,15 @@ svg { .activeNotificationDiv { opacity: 1; transform: translateY(0); - z-index: 3; + z-index: 5; } - .notification{ - margin-bottom: 7%; + padding: 0.5em 1em; display: flex; justify-content: space-between; align-items: center; + border-radius: 15px; } .notificationBadge { @@ -233,6 +210,7 @@ svg { cursor: pointer; display: none; z-index: 10; + background: none; } .burgerBar { diff --git a/src/components/IncompleteEvent/IncompleteEvent.jsx b/src/components/IncompleteEvent/IncompleteEvent.jsx new file mode 100644 index 0000000..b8e3355 --- /dev/null +++ b/src/components/IncompleteEvent/IncompleteEvent.jsx @@ -0,0 +1,38 @@ +import React from "react"; +import styles from "./IncompleteEvent.module.css"; + +function IncompleteEvent() { + const incompleteEvents = [ + { title: "Événement A", tasks: ["Communication sur les réseaux", "Enormément de comm", "Toujours + de comm,Communication sur les réseaux", + "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm]"] }, + { title: "Événement B", tasks: ["Réservation de la salle", "Vérification du matériel"] }, + { title: "Événement C", tasks: ["Communication sur les réseaux", "Enormément de comm", "Toujours + de comm"] }, + { title: "Événement D", tasks: ["Communication sur les réseaux", "Enormément de comm", "Toujours + de comm"] }, + { title: "Événement E", tasks: ["Communication sur les réseaux", "Enormément de comm", "Toujours + de comm,Communication sur les réseaux", + "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm]"] }, + { title: "Événement F", tasks: ["Communication sur les réseaux", "Enormément de comm", "Toujours + de comm,Communication sur les réseaux", + "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm]"] }, + { title: "Événement G", tasks: ["Communication sur les réseaux", "Enormément de comm", "Toujours + de comm,Communication sur les réseaux", + "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm","Communication sur les réseaux", "Enormément de comm", "Toujours + de comm]"] }, +]; + + return ( +
+

Événements incomplets

+
+ {incompleteEvents.map((event, index) => ( +
+

{event.title}

+
    + {event.tasks.map((task, taskIndex) => ( +
  • {task}
  • + ))} +
+
+ ))} +
+
+ ); +} + +export default IncompleteEvent; diff --git a/src/components/IncompleteEvent/IncompleteEvent.module.css b/src/components/IncompleteEvent/IncompleteEvent.module.css new file mode 100644 index 0000000..b3f1d70 --- /dev/null +++ b/src/components/IncompleteEvent/IncompleteEvent.module.css @@ -0,0 +1,135 @@ +.rightBlock { + width: 100%; +} + +.rightBlock>h2 { + font-size: 29px; +} + +.eventsContainer { + display: flex; + flex-direction: row; + gap: 10px; + margin-top: 5px; + overflow-x: auto; + overflow-y: hidden; + padding-bottom: 10px; + scroll-behavior: smooth; +} + +.eventCard ul { + align-items: center; + margin-left: 8%; +} + +.eventCard ul li { + text-align: left; + list-style-type: circle; +} + +.eventsContainer::-webkit-scrollbar { + height: 8px; +} + +.eventsContainer::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 10px; +} + +.eventsContainer::-webkit-scrollbar-thumb { + background: rgba(30, 96, 249, 0.5); + border-radius: 10px; +} + +.eventsContainer::-webkit-scrollbar-thumb:hover { + background: rgba(30, 96, 249, 0.7); +} + +.eventCard { + min-width: calc((100% - 20px) / 3); + max-width: calc((100% - 20px) / 3); + min-height: 250px; + max-height: 250px; + overflow-y: auto; + padding: 10px; + text-align: center; + padding-bottom: 200px; + box-sizing: border-box; + opacity: 0; + transform: translateX(20px); + animation: slideInEvent 1s ease forwards; + + flex-shrink: 1; + padding: 10px; + text-align: center; + box-sizing: border-box; +} + +.eventCard:nth-child(1) { + animation-delay: 0s; +} + +.eventCard:nth-child(2) { + animation-delay: 0.1s; +} + +.eventCard:nth-child(3) { + animation-delay: 0.2s; +} + +.eventCard:nth-child(4) { + animation-delay: 0.3s; +} + +.eventCard:nth-child(5) { + animation-delay: 0.4s; +} + +.eventCard:nth-child(6) { + animation-delay: 0.5s; +} + +.eventCard>h3 { + font-size: 24px; +} + +@keyframes slideInEvent { + from { + opacity: 0; + transform: translateX(20px); + } + + to { + opacity: 1; + transform: translateX(0); + } +} + +@media screen and (max-width: 760px) { + .eventCard { + min-width: 100%; + min-height: 200px; + max-height: fit-content; + padding-bottom: 0px; + } + + .eventCard h3 { + font-size: 17px; + } + + .eventsContainer { + display: flex; + flex-direction: column; + gap: 10px; + max-height: 300px; + margin-top: 15px; + height: fit-content; + overflow-y: auto; + padding-bottom: 0px; + scroll-behavior: smooth; + } + + .rightBlock>h2 { + font-size: 18px; + } +} \ No newline at end of file diff --git a/src/components/PendingMembers/PendingMembers.jsx b/src/components/PendingMembers/PendingMembers.jsx new file mode 100644 index 0000000..27dace2 --- /dev/null +++ b/src/components/PendingMembers/PendingMembers.jsx @@ -0,0 +1,46 @@ +import React from "react"; +import Button from "../ui/button/button"; +import styles from "./PendingMembers.module.css"; + +function pendingMembers() { + const pendingMembers = [ + { name: "Antoine Ordonneau" }, + { name: "Giovanni Josserand" }, + { name: "Quentin T'Jampens" }, + { name: "Quentin T'Jampens" }, + { name: "Quentin T'Jampens" }, + { name: "Quentin T'Jampens" }, + { name: "Quentin T'Jampens" } + ]; + + const handleValidate = (name) => { + console.log(`Valider ${name}`); + }; + + const handleReject = (name) => { + console.log(`Refuser ${name}`); + }; + + return ( +
+

Membres en attente de validation

+
+ {pendingMembers.map((member, index) => ( +
+

{member.name}

+
+ + +
+
+ ))} +
+
+ ); +} + +export default pendingMembers; diff --git a/src/components/PendingMembers/PendingMembers.module.css b/src/components/PendingMembers/PendingMembers.module.css new file mode 100644 index 0000000..9eaef39 --- /dev/null +++ b/src/components/PendingMembers/PendingMembers.module.css @@ -0,0 +1,81 @@ +.rightBlock { + width: 100%; +} + +.rightBlock > h2 { + font-size: 29px; +} + +.membersContainer { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 20px; + max-height: 185px; + overflow-y: auto; + padding-right: 5px; + scroll-behavior: smooth; +} + + +.membersContainer::-webkit-scrollbar { + width: 8px; +} + +.membersContainer::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 10px; +} + +.membersContainer::-webkit-scrollbar-thumb { + background: rgba(255, 0, 0, 0.5); + border-radius: 10px; +} + +.membersContainer::-webkit-scrollbar-thumb:hover { + background: rgba(125, 249, 30, 0.7); +} + +.memberCard { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; + flex-shrink: 0; + opacity: 0; + transform: translateY(20px); + animation: slideInMember 0.5s ease forwards; +} + +.memberCard:nth-child(1) { animation-delay: 0s; } +.memberCard:nth-child(2) { animation-delay: 0.1s; } +.memberCard:nth-child(3) { animation-delay: 0.2s; } + +.memberCard p { + font-weight: bold; + font-size: 20px; +} + +.buttonGroup { + display: flex; + gap: 10px; + justify-content: right; +} + +@keyframes slideInMember { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +@media screen and (max-width: 760px) { + .membersContainer { + max-height: 200px; + } + .rightBlock > h2{ + font-size:18px; + } + + .memberCard p{ + font-size: 15px; + } +} diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx index d79dfde..d39f095 100644 --- a/src/components/SearchBar/SearchBar.jsx +++ b/src/components/SearchBar/SearchBar.jsx @@ -3,7 +3,7 @@ import {Link} from "react-router"; import {useEffect, useState} from "react"; import searchEvents from "../../utils/searchEvents.js"; import searchUsers from "../../utils/searchUsers.js"; -import { useLocation } from "react-router-dom"; +import { useLocation } from "react-router"; function SearchBar() { @@ -47,10 +47,7 @@ function SearchBar() { return (
element.preventDefault()}> - - - + Rechercher { @@ -36,23 +36,17 @@ function ToolBar({setFilters, filters}) {
) : null}
- - + - + {showCreate ? ( + + ) : null}
diff --git a/src/components/ToolBar/ToolBar.module.css b/src/components/ToolBar/ToolBar.module.css index 1b53950..270fb99 100644 --- a/src/components/ToolBar/ToolBar.module.css +++ b/src/components/ToolBar/ToolBar.module.css @@ -9,6 +9,7 @@ width: fit-content; height: fit-content; gap: 1rem; + z-index: 4; } @@ -16,6 +17,9 @@ padding: 0; border-radius: 30px; overflow: visible; + display: flex; + align-items: center; + flex-direction: column; } .filterMenu{ @@ -34,11 +38,6 @@ transition: all 0.5s ease; } -.createButton { - font-size: 2rem; - color: #019AFF; -} - .createButton:hover, .searchButton:hover, .mobileFilter:hover { transform: translateY(-5px); cursor: pointer; @@ -60,11 +59,6 @@ justify-content: center; } -.sortButton svg, .searchButton svg { - transform: scale(0.5); - fill: #019AFF; -} - .sortButton:focus, .searchButton:focus { outline: none; @@ -93,8 +87,8 @@ } .filterContainer{ - display: flex; width: fit-content; + flex-direction: row; } .filterMenu{ diff --git a/src/components/chart/ParticipationChart.jsx b/src/components/chart/ParticipationChart.jsx new file mode 100644 index 0000000..7ebd731 --- /dev/null +++ b/src/components/chart/ParticipationChart.jsx @@ -0,0 +1,90 @@ +import React, { useState } from "react"; +import { Doughnut } from "react-chartjs-2"; +import { Chart, ArcElement } from "chart.js"; +import { MenuItem, Select, FormControl } from "@mui/material"; +import styles from "./ParticipationChart.module.css"; + +Chart.register(ArcElement); + +function participationChart() { + const [selected, setSelected] = useState("3"); + const [participationRate, setParticipationRate] = useState(78); + + const chartData = { + labels: ["Progress", "Background"], + datasets: [ + { + data: [participationRate, 100 - participationRate], + backgroundColor: ["#1e60f9ff", "#ffffffff"], + borderWidth: 0, + weight: 10, + cutout: "93%", + circumference: 360, + rotation: -90, + }, + ], + }; + + const chartOptions = { + responsive: true, + plugins: { + legend: { display: false }, + tooltip: { enabled: false }, + }, + animation: { + animateScale: true, + animateRotate: true, + }, + }; + + return ( +
+
+
+ +
+ + + +
+
+
+
+
+ +
{participationRate}%
+
+
+
+ ); +} + +export default participationChart; diff --git a/src/components/chart/ParticipationChart.module.css b/src/components/chart/ParticipationChart.module.css new file mode 100644 index 0000000..7fa3515 --- /dev/null +++ b/src/components/chart/ParticipationChart.module.css @@ -0,0 +1,120 @@ +.leftBlock { + width: 40%; + display: flex; + flex-direction: column; + align-items: center; + height: calc(100vh - 260px); + /* Exemple: calc(100vh - 60px) */ + margin-bottom: auto; +} + +.participationHeader { + display: flex; + align-items: center; + width: 100%; +} + +.partiText { + display: flex; + width: 100%; + flex-direction: column; + align-items: center; + justify-content: center; + margin-bottom: 2%; + margin-top: 2%; + animation: slideInEvent 2s; +} + +.partiText label { + font-size: 20px; + text-align: right; + transition: all 0.3s ease; +} + +.chartContainer { + max-width: 80%; + width: 400px; + height: auto; + margin: 0 auto; + position: relative; + animation: slideEvent2 2s; +} + +.chartWrapper { + position: relative; + width: 100%; + height: 100%; + display: flex; + justify-content: center; +} + +.chartPercentage { + position: absolute; + top: 50%; + left: 50%; + text-align: center; + transform: translate(-50%, -50%); + font-size: 60px; + font-weight: bold; + color: #333; +} + +@keyframes slideEvent2 { + from { + opacity: 0; + transform: translateX(-20px); + } + + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideInEvent { + from { + opacity: 0; + transform: translateX(20px); + } + + to { + opacity: 1; + transform: translateX(0); + } +} + +.formControl { + display: flex; + justify-content: center; + width: 100%; +} + +.formDesign { + margin: 0 auto; + width: fit-content; +} + +@media screen and (max-width: 760px) { + .partiText { + flex-direction: column; + justify-content: center; + } + + .partiText label { + text-align: center; + } + + .leftBlock { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + height: fit-content; + margin-bottom: auto; + margin-top: 30px; + } + .chartContainer{ + height:fit-content; + } + +} \ No newline at end of file diff --git a/src/components/createEventBtn/CreateEventBtn.jsx b/src/components/createEventBtn/CreateEventBtn.jsx new file mode 100644 index 0000000..3e638db --- /dev/null +++ b/src/components/createEventBtn/CreateEventBtn.jsx @@ -0,0 +1,42 @@ +import styles from "./createEventBtn.module.css" +import { useState } from "react"; +import Modal from "../ui/modal/modal.jsx"; +import Button from "../ui/button/button.jsx"; +import TextInput from "../ui/input/input.jsx"; +import createEvent from "../../utils/event/createEvent.js" + + +export default function CreateEventBtn() { + + const [isOpen, setIsOpen] = useState(false); + const [name, setName] = useState(""); + const [description, setDescription] = useState(""); + + const handleCreateEvent = async () => { + + if(name !== "" || description !== "") await createEvent(name, description); + setIsOpen(false); + } + + return <> + + + setIsOpen(false)}> + +
+
+

Titre

+ setName(e.target.value)} /> +
+ +
+

Description

+ setDescription(e.target.value)} /> +
+ + + +
+
+ +} \ No newline at end of file diff --git a/src/components/createEventBtn/createEventBtn.module.css b/src/components/createEventBtn/createEventBtn.module.css new file mode 100644 index 0000000..5676052 --- /dev/null +++ b/src/components/createEventBtn/createEventBtn.module.css @@ -0,0 +1,41 @@ +.createButton { + font-size: 1.5rem; + color: black; +} + +.createButton { + display: flex; + align-items: center; + justify-content: center; + border: none; + border-radius: 50% !important; + width: 55px !important; + height: 55px !important; + transition: all 0.5s ease; +} + +.createButton:hover { + transform: translateY(-5px); + cursor: pointer; +} + +.inputContainer { + + h2 { + margin-bottom: 0.5rem; + } + + margin: 1em; +} + +.create { + align-self: center; +} + +.section { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 15px; + margin-bottom: 15px; +} \ No newline at end of file diff --git a/src/components/loginform/loginForm.jsx b/src/components/loginform/loginForm.jsx index 7562cba..74eb1ee 100644 --- a/src/components/loginform/loginForm.jsx +++ b/src/components/loginform/loginForm.jsx @@ -2,20 +2,25 @@ import { useState, useContext } from "react"; import styles from "./loginForm.module.css"; import Button from "../ui/button/button.jsx"; import Input from "../ui/input/input.jsx"; +import Modal from "../ui/modal/modal.jsx"; import { useNavigate } from "react-router"; import { AuthContext } from "../../contexts/auth/AuthContext.js"; function LoginForm({ className }) { + + + const navigate = useNavigate(); + const { login } = useContext(AuthContext); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); - let navigate = useNavigate(); - const { login } = useContext(AuthContext); + const [open , setOpen] = useState(false); + + async function handleSubmit() { + const res = await login(email, password); + if (res.status === 401 || res.status === 422) setOpen(true); + else navigate("/"); - async function handleSubmit(e) { - e.preventDefault(); - await login(email, password); - navigate("/"); } return ( @@ -37,6 +42,10 @@ function LoginForm({ className }) {
+ + setOpen(false)}> +

L'Email ou le mot de passe est incorrect

+
); } diff --git a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx index a3aa96f..ef3ffc6 100644 --- a/src/components/ui/themeSwitcher/ThemeSwitcher.jsx +++ b/src/components/ui/themeSwitcher/ThemeSwitcher.jsx @@ -26,7 +26,7 @@ export default function ThemeSwitcher() { }; return } \ No newline at end of file diff --git a/src/contexts/auth/authProvider.jsx b/src/contexts/auth/authProvider.jsx index 850c3a2..666338f 100644 --- a/src/contexts/auth/authProvider.jsx +++ b/src/contexts/auth/authProvider.jsx @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import loginFunction from "../../utils/login.js"; +import loginFunction from "../../utils/auth/login.js"; import getUser from "../../utils/getUser.js"; import { AuthContext } from "./AuthContext"; import logoutFunction from "../../utils/auth/logout.js" @@ -19,12 +19,12 @@ export function AuthProvider({ children }) { const login = async (email, password) => { const res = await loginFunction(email, password); - if (!res || res.status !== 200) throw new Error("Login error"); - const u = await getUser(); - setUser(u); + const u = res.status === 200 ? await getUser() : null; + if (u) setUser(u); return res; }; + const logout = async () => { await logoutFunction(); setUser(null); diff --git a/src/index.css b/src/index.css index ce69093..a4fe9a0 100644 --- a/src/index.css +++ b/src/index.css @@ -27,9 +27,13 @@ html { .content { - padding: 1.5rem; - z-index: 1; - width: 100%; + padding: 1.5rem; + z-index: 1; + width: 100%; + min-height: 100vh; + display: flex; + flex-direction: column; + justify-content: space-between; } a { @@ -48,7 +52,7 @@ body { } -.glassCard { +/*.glassCard { width: 100%; height: fit-content; background: rgba(255, 255, 255, 0.65); @@ -63,21 +67,18 @@ body { inset 0 0 8px 4px rgba(255, 255, 255, 0.4); position: relative; overflow: hidden; -} +}*/ -.glassBorder{ - border-radius: 20px; - padding: 15px; - margin-top: 16px; - border: none; - background: rgb(255, 255, 255, 0.25); - box-shadow: - inset 1.25px 1.25px 1px rgba(255, 255, 255, 1), - inset -1.25px -1.25px 1px rgba(255, 255, 255, 1), - inset -0.25px 0.25px 1px rgba(0, 0, 0, 0.2), - inset 0.25px -0.25px 1px rgba(0, 0, 0, 0.2); -} +/* style a montrer a giovanni prcq il est + bo */ +.glassCard { + background: rgba(255, 255, 255, 0.2); + backdrop-filter: blur(10px); + border-radius: 20px; + padding: 15px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + border: 1px solid rgba(255, 255, 255, 0.3); +} h1 { font-size: 3.2em; line-height: 1.1; diff --git a/src/layout.jsx b/src/layout.jsx index 4689a4e..2bfae90 100644 --- a/src/layout.jsx +++ b/src/layout.jsx @@ -11,8 +11,9 @@ function Layout(){ const { user, loading } = useContext(AuthContext); - if (loading) return

Loading

; + /* if (loading) return

Loading

; if (!user) return ; + if(user && user.validate === 0) return ;*/ return (
diff --git a/src/pages/Admin/AdminPage.jsx b/src/pages/Admin/AdminPage.jsx new file mode 100644 index 0000000..7682bb1 --- /dev/null +++ b/src/pages/Admin/AdminPage.jsx @@ -0,0 +1,35 @@ +import { useState, useContext } from "react"; +import styles from "./AdminPage.module.css"; +import ParticipationChart from "../../components/chart/ParticipationChart.jsx"; +import IncompleteEvents from "../../components/IncompleteEvent/IncompleteEvent.jsx"; +import PendingMembers from "../../components/PendingMembers/PendingMembers.jsx"; +import { AuthContext } from "../../contexts/auth/AuthContext.js"; +import { useNavigate } from "react-router"; + + +function AdminPage() { + + const { user } = useContext(AuthContext); + const navigate = useNavigate(); + + const [selected, setSelected] = useState("3"); + const [participationRate, setParticipationRate] = useState(89); + + /*if(!user.isAdmin) navigate("/");*/ + + return ( +
+ +
+ + +
+
+ ); +} + +export default AdminPage; diff --git a/src/pages/Admin/AdminPage.module.css b/src/pages/Admin/AdminPage.module.css new file mode 100644 index 0000000..ced6cdf --- /dev/null +++ b/src/pages/Admin/AdminPage.module.css @@ -0,0 +1,29 @@ +.container { + display: flex; + flex-direction: row; + width: 100%; + padding: 20px; + box-sizing: border-box; + gap: 20px; +} + +.rightSection { + width: 60%; + display: flex; + flex-direction: column; + gap: 20px; +} + +@media screen and (max-width: 760px) { + .container { + flex-direction: column; + width: 100%; + padding: 0; + } + + .rightSection { + width: 100%; + margin: 0; + margin-bottom: 15px; + } +} diff --git a/src/pages/PageNotFound/PageNotFound.jsx b/src/pages/PageNotFound/PageNotFound.jsx new file mode 100644 index 0000000..27b8630 --- /dev/null +++ b/src/pages/PageNotFound/PageNotFound.jsx @@ -0,0 +1,24 @@ +import Background from "../../components/background/background.jsx"; +import styles from "./PageNotFound.module.css" +import { useNavigate } from "react-router"; + +export default function PageNotFound() { + + const navigate = useNavigate(); + + return +
+

Page non trouvée

+
+

+ Désolé, la page que vous recherchez n’existe pas ou n’est plus disponible.
+ Vous pouvez :
+ - Vérifier l’URL pour une éventuelle erreur de saisie.
+ - Revenir à l’accueil navigate("/")} className={styles.redirectSpan}>ici.
+ +

+

Contact : contact@example.com

+
+
+
+} \ No newline at end of file diff --git a/src/pages/PageNotFound/PageNotFound.module.css b/src/pages/PageNotFound/PageNotFound.module.css new file mode 100644 index 0000000..70e36f9 --- /dev/null +++ b/src/pages/PageNotFound/PageNotFound.module.css @@ -0,0 +1,33 @@ +.title { + color: white; + font-size: xx-large; + margin-bottom: 20px; +} + +.content { + display: flex; + flex-direction: column; + z-index: 2; + padding: 10px; +} + +.container { + padding: 20px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 15px; + + p { + font-size: large; + } +} +.redirectSpan { + color: blue; + text-decoration: underline; +} + +.redirectSpan:hover { + cursor: pointer; +} \ No newline at end of file diff --git a/src/pages/Profile/ProfilePage.jsx b/src/pages/Profile/ProfilePage.jsx index aaa1338..a47e87c 100644 --- a/src/pages/Profile/ProfilePage.jsx +++ b/src/pages/Profile/ProfilePage.jsx @@ -8,7 +8,6 @@ import SettingsModal from "../../components/SettingsModal/SettingsModal.jsx"; function ProfilePage() { const { user } = useContext(AuthContext); - return (
@@ -31,12 +30,12 @@ function ProfilePage() {

Mail : {user.email}

-

Téléphone : {user.phone}

+

Téléphone : {user.phone === null ? "Pas de numéro enregistré" : user.phone}

-

Vos Événements :

+

Tâches :

{user.tasks && user.tasks.length > 0 ? ( user.tasks.map((task, index) => ( diff --git a/src/pages/Stat/StatPage.jsx b/src/pages/Stat/StatPage.jsx deleted file mode 100644 index cd75918..0000000 --- a/src/pages/Stat/StatPage.jsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { useState } from "react"; -import { Doughnut } from "react-chartjs-2"; -import { Chart, ArcElement } from "chart.js"; -import styles from "./StatPage.module.css"; -import Button from "./../../components/ui/button/button"; - -// Enregistrer les éléments nécessaires -Chart.register(ArcElement); - -function StatPage() { - const [months, setMonths] = useState(3); - - const [participationRate, setParticipationRate] = useState(89); - - const incompleteEvents = [ - { title: "Événement A", tasks: "Préparation des flyers" }, - { title: "Événement B", tasks: "Réservation de la salle" }, - { title: "Événement C", tasks: "Communication sur les réseaux" }, - ]; - - const pendingMembers = [ - { name: "Antoine Ordonneau" }, - { name: "Giovanni Josserand" }, - { name: "Quentin T'Jampens" }, - ]; - - const handleValidate = (name) => { - console.log(`Valider ${name}`); - }; - - const handleReject = (name) => { - console.log(`Refuser ${name}`); - }; - - const chartData = { - labels: ["Progress", "Background"], - datasets: [ - { - data: [participationRate, 100 - participationRate], - backgroundColor: ["#1e60f9ff", "#ffffffff"], - borderWidth: 0, - weight:10, - cutout: "90%", - circumference: 360, - rotation: -90, - }, - ], - }; - - const chartOptions = { - responsive: true, - plugins: { - legend: { - display: false, - }, - tooltip: { - enabled: false, - }, - }, - animation: { - animateScale: true, - animateRotate: true, - }, - }; - - return ( -
-
-
-
- - - - -
- -
-
-
- -
- {participationRate}% -
-
-
-
-
-
-

Événements incomplets

-
- {incompleteEvents.map((event, index) => ( -
-

{event.title}

-

{event.tasks}

-
- ))} -
-
-
-

Membres en attente de validation

-
- {pendingMembers.map((member, index) => ( -
-

{member.name}

-
- - -
-
- ))} -
-
-
-
- ); -} - -export default StatPage; diff --git a/src/pages/Stat/StatPage.module.css b/src/pages/Stat/StatPage.module.css deleted file mode 100644 index 666a610..0000000 --- a/src/pages/Stat/StatPage.module.css +++ /dev/null @@ -1,194 +0,0 @@ -.container { - display: flex; - flex-direction: row; - width: 100%; - padding: 20px; - box-sizing: border-box; - gap: 20px; -} -/* style a montrer a giovanni prcq il est + bo */ -/*.glassCard { - background: rgba(255, 255, 255, 0.2); - backdrop-filter: blur(10px); - border-radius: 10px; - padding: 15px; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); - border: 1px solid rgba(255, 255, 255, 0.3); -}*/ - -.block { - border-radius: 10px; - padding: 15px; - box-sizing: border-box; -} - -.leftBlock { - width: 40%; - display: flex; - flex-direction: column; - align-items: center; - height:fit-content; -} - -.participationHeader { - display: flex; - align-items: center; - margin-bottom: 20px; - width: 100%; -} -.partiText{ - display: flex; - flex-direction: column; - width: 100%; -} -.participationHeader label{ - font-size:20px; - text-align: center; -} - -.monthsDropdown { - width:25%; - border-radius: 5px; - opacity: 1; - background-color: transparent; - border:none; -} - - -.chartContainer { - - max-width: 80%; - margin: 0 auto; - position: relative; -} - - -.circularProgress { - width: 100%; - height: 100%; -} - -.progressBackground { - opacity: 0.3; -} - -.progressBar { - transition: stroke-dasharray 0.5s ease; - stroke-linecap: round; -} - -.progressText { - font-weight: bold; - font-family: Arial, sans-serif; -} - - -.rightSection { - width: 60%; - display: flex; - flex-direction: column; - gap: 20px; -} - -.rightBlock { - width: 100%; -} -.rightBlock>h2{ - font-size:29px; -} - -.eventsContainer { - display: flex; - flex-direction: row; - gap: 10px; - margin-top: 15px; -} - - -.eventCard { - flex: 1; - padding: 10px; - text-align: center; - padding-bottom:200px; -} -.eventCard>h3{ - font-size: 24px; -} -.membersContainer { - display: flex; - flex-direction: column; - gap: 10px; - margin-top: 15px; -} - -.memberCard { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px; -} -.memberCard p{ - font-weight: bold; - font-size: 20px; -} - - -.buttonGroup { - display: flex; - gap: 10px; - justify-content: right; -} - - - - -@media screen and (max-width: 760px) { - .container { - flex-direction: column; - padding: 10px; - } - - .leftBlock { - width: 100%; - margin-bottom: 20px; - height:fit-content; - } - - .rightSection { - width: 100%; - } - - .eventsContainer { - flex-direction: column; - } - - .eventCard { - width: 100%; - } - - .donutChart { - width: 120px; - height: 120px; - } - - .memberCard { - flex-direction: column; - align-items: flex-start; - gap: 10px; - - } - - .buttonGroup { - width: 100%; - justify-content: space-between; - } - - .validateButton, - .rejectButton { - flex: 1; - text-align: center; - padding: 8px; - } -} - - diff --git a/src/pages/VolunteerProfile/VolunteerProfilePage.jsx b/src/pages/VolunteerProfile/VolunteerProfilePage.jsx new file mode 100644 index 0000000..1f18805 --- /dev/null +++ b/src/pages/VolunteerProfile/VolunteerProfilePage.jsx @@ -0,0 +1,69 @@ +import styles from "./VolunteerProfilePage.module.css" +import { useParams } from "react-router"; +import { useEffect, useState } from "react"; +import getUserById from "../../utils/users/getUserById.js"; +import formatDate from "../../utils/date/formatDate.js"; +import Task from "../../components/Task/Task.jsx"; +import { useNavigate } from "react-router"; + +export default function VolunteerProfilePage() { + + const params = useParams(); + const id = params.id; + + const navigate = useNavigate(); + + const [user, setUser] = useState({}); + + useEffect(() => { + (async () => { + const result = await getUserById(id); + if (result?.error === 'not_found') { + navigate("/404"); + } else { + setUser(result); + } + })(); + }, [id]); + + + + return
+
+
+
+ Photo de profil +
+
+
+

{user.name} {user.lastname}

+
+
+
+

Role : {user.role}

+

Membre depuis : {formatDate(user.created_at)}

+
+
+

Mail : {user.email}

+

Téléphone : {user.phone === null ? "Pas de numéro enregistré" : user.phone}

+
+
+ +

Tâches :

+ {user.tasks && user.tasks.length > 0 ? ( + user.tasks.map((task, index) => ( + + )) + ) : ( +

Aucune tâche pour le moment.

+ )} + +
+
+
+
+} \ No newline at end of file diff --git a/src/pages/VolunteerProfile/VolunteerProfilePage.module.css b/src/pages/VolunteerProfile/VolunteerProfilePage.module.css new file mode 100644 index 0000000..e9861dc --- /dev/null +++ b/src/pages/VolunteerProfile/VolunteerProfilePage.module.css @@ -0,0 +1,164 @@ +.container { + width: 100%; + padding: 10px; + box-sizing: border-box; +} + +.profileboard { + width: 100%; + padding: 15px; + border-radius: 20px; + box-sizing: border-box; +} + +.contentWrapper { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; +} + +.profilePictureContainer { + width: 120px; + height: 120px; + margin-bottom: 15px; +} + +.profilePicture { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; +} + +.description { + width: 100%; + text-align: left; + margin-left:4%; +} + +.topDescription { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + margin-bottom: 15px; +} + +.infoBlock { + width: 100%; + background: rgba(255, 255, 255, 0.1); + padding: 10px; + border-radius: 5px; +} + +.eventTasks { + max-height: 0; + overflow: hidden; + transition: max-height 0.3s ease-out, opacity 0.2s ease; + opacity: 0; + padding-left: 20px; +} + +.eventTasks.expanded { + max-height: 500px; + opacity: 1; + margin-top: 10px; +} +.description h2{ + font-size:30px; + +} +.profilePicture{ + width:90%; +} + +.settingsBtns { + display: flex; + gap: 5px; + justify-content: right; +} + +@media screen and (min-width: 768px) { + .contentWrapper { + flex-direction: row; + justify-content: flex-start; + align-items: flex-start; + } + + .profilePictureContainer { + width: 150px; + height: 150px; + margin-right: 20px; + margin-bottom: 0; + } + + .description { + width: calc(100% - 170px); + margin-left:4%; + } + + .topDescription { + flex-direction: row; + justify-content: space-between; + } + + .infoBlock { + width: 48%; + } + + .event { + padding: 15px; + } + .description h2{ + font-size:30px; + } + .profilePicture{ + width:90%; + } +} +.description button{ + width:50px; + height:50px; + +} + +.headerProfile { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + +/* Desktop (1024px et plus) */ +@media screen and (min-width: 1024px) { + .container { + max-width: 100%; + margin: 0 auto; + padding: 20px; + } + + .profileboard { + padding: 25px; + } + + .profilePictureContainer { + width: 30%; + height:auto; + } + .profilePicture{ + width:90%; + } + .description { + width: calc(100% - 200px); + margin-left:4%; + } + + .event { + padding: 18px; + } + .description h2{ + font-size:30px; + } +} diff --git a/src/pages/Volunteers/VolunteerCard.jsx b/src/pages/Volunteers/VolunteerCard.jsx index fe1cf00..fb58440 100644 --- a/src/pages/Volunteers/VolunteerCard.jsx +++ b/src/pages/Volunteers/VolunteerCard.jsx @@ -58,7 +58,7 @@ export default function VolunteerCard({ user }) { {isExpanded && (
+
+
+ +} \ No newline at end of file diff --git a/src/pages/waitValidationPage/validationErrorPage.module.css b/src/pages/waitValidationPage/validationErrorPage.module.css new file mode 100644 index 0000000..e4a398d --- /dev/null +++ b/src/pages/waitValidationPage/validationErrorPage.module.css @@ -0,0 +1,25 @@ +.title { + color: white; + font-size: xx-large; + margin-bottom: 20px; +} + +.content { + display: flex; + flex-direction: column; + z-index: 2; + padding: 10px; +} + +.container { + padding: 20px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 15px; + + p { + font-size: large; + } +} \ No newline at end of file diff --git a/src/router.js b/src/router.js index f3fdef6..73e049e 100644 --- a/src/router.js +++ b/src/router.js @@ -2,11 +2,14 @@ import { createBrowserRouter } from "react-router"; import Layout from "./layout.jsx"; import HomePage from "./pages/Home/HomePage"; import LoginPage from "./pages/Login/LoginPage"; -import StatPage from "./pages/Stat/StatPage"; import RegisterPage from "./pages/Register/RegisterPage.jsx"; import VolunteersPage from "./pages/Volunteers/VolunteersPage"; import ProfilePage from "./pages/Profile/ProfilePage"; import EventsPage from "./pages/Events/EventsPage.jsx"; +import AdminPage from "./pages/Admin/AdminPage.jsx"; +import ValidationErrorPage from "./pages/waitValidationPage/ValidationErrorPage.jsx"; +import VolunteerProfilePage from "./pages/VolunteerProfile/VolunteerProfilePage.jsx"; +import PageNotFound from "./pages/PageNotFound/PageNotFound.jsx"; const router = createBrowserRouter([ { @@ -17,6 +20,18 @@ const router = createBrowserRouter([ path: "/register", Component: RegisterPage, }, + { + path: "/error/validation", + Component: ValidationErrorPage + }, + { + path: "/*", + Component: PageNotFound, + }, + { + path: "/404", + Component: PageNotFound, + }, { path: "/", Component: Layout, @@ -27,7 +42,7 @@ const router = createBrowserRouter([ }, { path: "/admin", - Component:StatPage, + Component:AdminPage, }, { path:"/profile", @@ -40,6 +55,10 @@ const router = createBrowserRouter([ { path: "/volunteers", Component: VolunteersPage, + }, + { + path: "/profile/:id", + Component: VolunteerProfilePage, } ] } diff --git a/src/stories/ThemeSwitcher.stories.jsx b/src/stories/ThemeSwitcher.stories.jsx new file mode 100644 index 0000000..f285b15 --- /dev/null +++ b/src/stories/ThemeSwitcher.stories.jsx @@ -0,0 +1,20 @@ +import ThemeSwitcher from "../components/ui/themeSwitcher/ThemeSwitcher.jsx"; +import Background from "../components/background/background.jsx"; + +export default { + title: 'UI/ThemeSwitcher', + component: ThemeSwitcher, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +}; + +const ThemeSwitcherRender = () => { + return + + +}; + +export const Default = () => ; + diff --git a/src/utils/login.js b/src/utils/auth/login.js similarity index 72% rename from src/utils/login.js rename to src/utils/auth/login.js index 161268c..c925521 100644 --- a/src/utils/login.js +++ b/src/utils/auth/login.js @@ -1,4 +1,4 @@ -import getXSRFToken from "./getXSRF.js"; +import getXSRFToken from "../getXSRF.js"; export default async function login(email, password) { const csrfToken = await getXSRFToken(); @@ -15,17 +15,18 @@ export default async function login(email, password) { body: JSON.stringify({ email, password }) }); - console.log('Code HTTP :', response.status); + const data = await response.json(); if (!response.ok) { - throw new Error(`Erreur HTTP ${response.status}`); + return { + status: response.status, + errors: data.errors || data.message + }; } - const data = await response.json(); - console.log('Connexion réussie ! Données utilisateur :', data); - return { status: response.status, data }; + } catch (error) { - return error; + return { status: 500, error }; } } diff --git a/src/utils/auth/login.test.js b/src/utils/auth/login.test.js new file mode 100644 index 0000000..aa20121 --- /dev/null +++ b/src/utils/auth/login.test.js @@ -0,0 +1,69 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import login from './login'; + +vi.mock('../getXSRF.js', () => ({ + default: vi.fn(() => Promise.resolve('fake-csrf-token')) +})); + +describe('login()', () => { + + beforeEach(() => { + vi.clearAllMocks(); + global.fetch = vi.fn(); + }); + + it('envoie la requête de login et retourne les données utilisateur', async () => { + global.fetch.mockResolvedValue({ + ok: true, + status: 200, + json: async () => ({ id: 1, name: 'John Doe' }) + }); + + const result = await login('test@example.com', 'secret'); + + expect(global.fetch).toHaveBeenCalledOnce(); + expect(global.fetch).toHaveBeenCalledWith( + `http://${import.meta.env.VITE_API_URL}/api/users/login`, + { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'X-XSRF-TOKEN': 'fake-csrf-token', + 'Accept': 'application/json' + }, + body: JSON.stringify({ email: 'test@example.com', password: 'secret' }) + } + ); + + expect(result).toEqual({ + status: 200, + data: { id: 1, name: 'John Doe' } + }); + }); + + it('retourne un objet avec status et erreurs quand la réponse HTTP est mauvaise', async () => { + global.fetch.mockResolvedValue({ + ok: false, + status: 401, + json: async () => ({ message: 'Unauthorized' }) + }); + + const result = await login('x', 'y'); + + expect(result).toEqual({ + status: 401, + errors: 'Unauthorized' + }); + }); + + it('retourne un objet avec status 500 en cas d’exception', async () => { + global.fetch.mockImplementation(() => { throw new Error('Network Error') }); + + const result = await login('x', 'y'); + + expect(result.status).toBe(500); + expect(result.error).toBeInstanceOf(Error); + expect(result.error.message).toBe('Network Error'); + }); +}); diff --git a/src/utils/auth/logout.test.js b/src/utils/auth/logout.test.js new file mode 100644 index 0000000..f553e2e --- /dev/null +++ b/src/utils/auth/logout.test.js @@ -0,0 +1,53 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import logout from './logout'; + +vi.mock('../getXSRF.js', () => { + return { + default: vi.fn(() => Promise.resolve('fake-csrf-token')) + }; +}); + +describe('logout()', () => { + + beforeEach(() => { + vi.clearAllMocks(); + global.fetch = vi.fn(); + }); + + it('envoie bien la requête de logout', async () => { + global.fetch.mockResolvedValue({ + ok: true, + status: 200 + }); + + const result = await logout(); + + expect(global.fetch).toHaveBeenCalledOnce(); + expect(global.fetch).toHaveBeenCalledWith( + `http://${import.meta.env.VITE_API_URL}/api/users/logout`, + { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'X-XSRF-TOKEN': 'fake-csrf-token' + }, + } + ); + + expect(result).toEqual({ status: 200 }); + }); + + it('renvoie une erreur quand la réponse HTTP est mauvaise', async () => { + global.fetch.mockResolvedValue({ + ok: false, + status: 500 + }); + + const result = await logout(); + + expect(result).toBeInstanceOf(Error); + expect(result.message).toBe('Erreur HTTP 500'); + }); +}); diff --git a/src/utils/event/createEvent.js b/src/utils/event/createEvent.js new file mode 100644 index 0000000..4098dd7 --- /dev/null +++ b/src/utils/event/createEvent.js @@ -0,0 +1,36 @@ +import getXSRFToken from "../getXSRF.js"; + +export default async function createEvent(name, description) { + const csrfToken = await getXSRFToken(); + + try { + const response = await fetch(`http://${import.meta.env.VITE_API_URL}/api/events/create`, { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + 'X-XSRF-TOKEN': csrfToken, + 'Accept': 'application/json' + }, + body: JSON.stringify({ name, description }), + }); + + const data = await response.json(); + + if (!response.ok) { + if (response.status === 422) { + return { + status: 422, + errors: data.errors + }; + } + + throw new Error(`Erreur HTTP ${response.status}`); + } + + return { status: response.status, data }; + + } catch (error) { + return { status: "error", error }; + } +} diff --git a/src/utils/users/getUserById.js b/src/utils/users/getUserById.js index 59af94a..1fad659 100644 --- a/src/utils/users/getUserById.js +++ b/src/utils/users/getUserById.js @@ -1,4 +1,4 @@ -export default async function getUserById (id) { +export default async function getUserById(id) { try { const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/${id}`, { method: 'GET', @@ -9,12 +9,15 @@ export default async function getUserById (id) { }); if (!res.ok) { + if (res.status === 404) { + return { error: 'not_found' }; + } throw new Error(`Erreur serveur : ${res.status}`); } return await res.json(); } catch (err) { console.error('Erreur :', err); - return null; + return { error: 'server_error' }; } -} \ No newline at end of file +}