diff --git a/frontend/app/admin/page.tsx b/frontend/app/admin/page.tsx index 04bea74b..27295dd2 100644 --- a/frontend/app/admin/page.tsx +++ b/frontend/app/admin/page.tsx @@ -14,7 +14,7 @@ import { HttpCodes } from "@/types/HttpCodes"; import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, useDisclosure } from "@nextui-org/modal"; import { set } from "react-hook-form"; import { Input } from "@nextui-org/input"; -import { DonutChart } from "@tremor/react"; +import { DonutChart, Legend, CustomTooltipProps } from "@tremor/react"; axios.defaults.withCredentials = true; @@ -175,6 +175,95 @@ const AdminHomepage = () => { } } + var dataPostsDonut = [{ + Status: "Pending ", + Posts: posts.filter(post => post.status == "open").length + }, + { + Status: "Closed ", + Posts: posts.filter(post => post.status == "closed").length + }, + { + Status: "Completed ", + Posts: posts.filter(post => post.status == "completed").length + }]; + + var dataReportsDonut = [{ + Status: "Open ", + Reports: reports.filter(reports => reports.status == "open").length + }, + { + Status: "Closed ", + Reports: reports.filter(reports => reports.status == "closed").length + }]; + + //Donut chart colors + const reportsDonutCol = ['orange-500', 'blue-600'] + const postsDonutCol = ['teal-500', 'blue-600', 'orange-500'] + const usersDonutCol = ['lime-500', 'violet-600', 'orange-500'] + + var dataUsersDonut = [{ + Role: "Default", + Users: users.filter(user => user.role == "user").length + }, + { + Role: "Admin", + Users: users.filter(user => user.role == "admin").length + }, + { + Role: "Banned", + Users: users.filter(user => user.role == "banned").length + }] + + + const valueFormatterPosts = (number: number,) => { + const total = dataPostsDonut.reduce( + (accumulator, currentValue) => accumulator + currentValue.Posts, + 0, + ) + const percentage = Math.round((number / total) * 100) + return `\n${percentage}% Posts` + } + + const valueFormatterReports = (number: number,) => { + const total = dataReportsDonut.reduce( + (accumulator, currentValue) => accumulator + currentValue.Reports, + 0, + ) + const percentage = Math.round((number / total) * 100) + return `\n${percentage}% Posts` + } + + const valueFormatterUsers = (number: number,) => { + const total = dataUsersDonut.reduce( + (accumulator, currentValue) => accumulator + currentValue.Users, + 0, + ) + const percentage = Math.round((number / total) * 100) + return `\n${percentage}% Users` + } + + const customTooltip = (props: CustomTooltipProps) => { + const { payload, active } = props; + if (!active || !payload) return null; + const categoryPayload = payload?.[0]; if (!categoryPayload) return null; + return (
+
+
+
+
+

+ {categoryPayload.name}

+

+ {categoryPayload.value} +

+
+
+
+
); + }; + return (

Admin Home

@@ -286,57 +375,60 @@ const AdminHomepage = () => {
-
- - post.status == "open").length - }, - { - Status: "Closed ", - Posts: posts.filter(post => post.status == "closed").length - }, - { - Status: "Completed ", - Posts: posts.filter(post => post.status == "completed").length - }] - } - index="Status" - category="Posts" + + +
+ + {/* Users Donut chart */} + + + - - user.role == "user").length - }, - { - Role: "Admin", - Users: users.filter(user => user.role == "admin").length - }, - { - Role: "Banned", - Users: users.filter(user => user.role == "banned").length - }] - } - index="Role" - category="Users" + + {/* Reports Donut chart */} + + + + {/* Posts Donut chart */} + + + +
{/* User Summary */} {message &&

{message}

} diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 8e575518..71cacccb 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -1,4 +1,5 @@ import {nextui} from '@nextui-org/theme' +const colors = require('tailwindcss/colors'); /** @type {import('tailwindcss').Config} */ module.exports = { @@ -9,8 +10,128 @@ module.exports = { './node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}' ], theme: { - extend: {}, + transparent: 'transparent', + current: 'currentColor', + extend: { + colors: { + // light mode + tremor: { + brand: { + faint: colors.blue[50], + muted: colors.blue[200], + subtle: colors.blue[400], + DEFAULT: colors.blue[500], + emphasis: colors.blue[700], + inverted: colors.white, + }, + background: { + muted: colors.gray[50], + subtle: colors.gray[100], + DEFAULT: colors.white, + emphasis: colors.gray[700], + }, + border: { + DEFAULT: colors.gray[200], + }, + ring: { + DEFAULT: colors.gray[200], + }, + content: { + subtle: colors.gray[400], + DEFAULT: colors.gray[500], + emphasis: colors.gray[700], + strong: colors.gray[900], + inverted: colors.white, + }, + }, + // dark mode + 'dark-tremor': { + brand: { + faint: '#0B1229', + muted: colors.blue[950], + subtle: colors.blue[800], + DEFAULT: colors.blue[500], + emphasis: colors.blue[400], + inverted: colors.blue[950], + }, + background: { + muted: '#131A2B', + subtle: colors.gray[800], + DEFAULT: colors.gray[900], + emphasis: colors.gray[300], + }, + border: { + DEFAULT: colors.gray[800], + }, + ring: { + DEFAULT: colors.gray[800], + }, + content: { + subtle: colors.gray[600], + DEFAULT: colors.gray[500], + emphasis: colors.gray[200], + strong: colors.gray[50], + inverted: colors.gray[950], + }, + }, + }, + boxShadow: { + // light + 'tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)', + 'tremor-card': + '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', + 'tremor-dropdown': + '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', + // dark + 'dark-tremor-input': '0 1px 2px 0 rgb(0 0 0 / 0.05)', + 'dark-tremor-card': + '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)', + 'dark-tremor-dropdown': + '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)', + }, + borderRadius: { + 'tremor-small': '0.375rem', + 'tremor-default': '0.5rem', + 'tremor-full': '9999px', + }, + fontSize: { + 'tremor-label': ['0.75rem', { lineHeight: '1rem' }], + 'tremor-default': ['0.875rem', { lineHeight: '1.25rem' }], + 'tremor-title': ['1.125rem', { lineHeight: '1.75rem' }], + 'tremor-metric': ['1.875rem', { lineHeight: '2.25rem' }], + }, + }, }, + safelist: [ + { + pattern: + /^(bg-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + variants: ['hover', 'ui-selected'], + }, + { + pattern: + /^(text-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + variants: ['hover', 'ui-selected'], + }, + { + pattern: + /^(border-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + variants: ['hover', 'ui-selected'], + }, + { + pattern: + /^(ring-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + }, + { + pattern: + /^(stroke-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + }, + { + pattern: + /^(fill-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)-(?:50|100|200|300|400|500|600|700|800|900|950))$/, + }, + ], + plugins: [require('@headlessui/tailwindcss')], darkMode: "class", plugins: [nextui()], }