Skip to content

Commit

Permalink
main admin dashboard (#626)
Browse files Browse the repository at this point in the history
* main admin dashboard

* new piechart and stats updated

* new piechart and stats updated

* new piechart and stats updated

* ft-admin-dashboard-can-vieww-table-teams

* new piechart and stats updated

* Bar Chart changes according to teams workrate

* user Growth overtime chart

* user Growth overtime chart

* ft main admin dashboared

* ft(626): Admin Dashboard

* ft(626): testing Admin Dashboard

---------

Co-authored-by: Tuyisenge2 <[email protected]>
Co-authored-by: Bananayosostene <[email protected]>
Co-authored-by: shebz2023 <[email protected]>
Co-authored-by: JacquelineTuyisenge <[email protected]>
  • Loading branch information
5 people authored Dec 2, 2024
1 parent 0c9f0df commit 0cd551b
Show file tree
Hide file tree
Showing 74 changed files with 3,231 additions and 1,204 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"cloudinary-react": "^1.8.1",
"crypto-browserify": "^3.12.0",
"date-fns": "^2.30.0",
"dayjs": "^1.11.13",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"file-loader": "^6.2.0",
Expand Down
2 changes: 1 addition & 1 deletion public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -473,4 +473,4 @@
"Director": "Directeur",
"Andela": "Andela",
"University of Rwanda": "Université du Rwanda"
}
}
2 changes: 1 addition & 1 deletion public/locales/kn/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -462,4 +462,4 @@
"Director": "Umuyobozi mukuru",
"Andela": "Andela",
"University of Rwanda": "Kaminuza y' u Rwanda"
}
}
107 changes: 107 additions & 0 deletions src/Chart/BarChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react';
import { Bar } from 'react-chartjs-2';
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
import { useQuery } from '@apollo/client';
import { GET_ALL_TEAMS } from '../queries/team.queries';
import { FETCH_ALL_RATINGS } from '../queries/ratings.queries';

ChartJS.register(
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
);

interface Props {}

// eslint-disable-next-line react/function-component-definition
const BarChart: React.FC<Props> = () => {
const orgToken = localStorage.getItem('orgToken');
const { data, loading, error } = useQuery(GET_ALL_TEAMS, {
variables: {
orgToken,
},
fetchPolicy: 'network-only',
});

const {
data: ratingsData,
loading: ratingsLoading,
error: ratingsError,
} = useQuery(FETCH_ALL_RATINGS, {
variables: {
orgToken,
},
fetchPolicy: 'network-only',
});

if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;

if (ratingsLoading) return <p>Loading ratings...</p>;
if (ratingsError) return <p>Error loading ratings: {ratingsError.message}</p>;

const teamNames = data?.getAllTeams?.map(
(team: { name: string }) => team.name,
);
const ratingsArray = ratingsData?.fetchAllRatings || [];

const professionalismData = ratingsArray.map(
(rating: { professional_Skills: string }) =>
parseFloat(rating.professional_Skills),
);
const qualityData = ratingsArray.map((rating: { quality: string }) =>
parseFloat(rating.quality),
);
const quantityData = ratingsArray.map((rating: { quantity: string }) =>
parseFloat(rating.quantity),
);
if (!teamNames || teamNames.length === 0) {
return <p>No team data available.</p>;
}

const datas = {
labels: teamNames,
datasets: [
{
label: 'Professionalism',
data: professionalismData,
backgroundColor: '#5A6ACF',
borderRadius: 20,
barThickness: 14,
},
{
label: 'Quality',
data: qualityData,
backgroundColor: '#fcffa4',
borderRadius: 20,
barThickness: 14,
},
{
label: 'Quantity',
data: quantityData,
backgroundColor: '#9f5233',
borderRadius: 20,
barThickness: 14,
},
],
};

return (
<div className="w-full h-[300px]">
<Bar data={datas} options={{ responsive: true }} className="-ml-2" />
</div>
);
};

export default BarChart;
197 changes: 197 additions & 0 deletions src/Chart/LineChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import { useQuery } from '@apollo/client';
import React, { useEffect, useState } from 'react';
import {
LineChart,
Line,
CartesianGrid,
XAxis,
YAxis,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts';
import dayjs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';
import GET_ROLE_QUERY from '../containers/admin-dashBoard/GetRolesQuery';

dayjs.extend(isoWeek);

function UserGrowth() {
const [orgToken, setOrgToken] = useState<string | null>(null);
const [period, setPeriod] = useState<'daily' | 'weekly' | 'monthly'>('daily');
const [selectedYear, setSelectedYear] = useState<string>(
dayjs().year().toString(),
);

useEffect(() => {
const token = localStorage.getItem('orgToken');
setOrgToken(token);
}, []);

const { data, loading, error } = useQuery(GET_ROLE_QUERY, {
variables: { orgToken },
skip: !orgToken,
});

if (loading) {
return <p>Loading...</p>;
}

if (error) {
return <p>Error: {error.message}</p>;
}

const users = data?.getAllUsers || [];

const userGrowth = (users: any[]) => {
const growthData: { [key: string]: number } = {};

users.forEach((user: any) => {
const timestamp = user.createdAt || user.updatedAt;
if (timestamp) {
const date = dayjs(parseInt(timestamp, 10));
const year = date.year().toString();

if (year === selectedYear) {
let periodKey = '';
if (period === 'daily') {
periodKey = date.format('YYYY-MM-DD');
} else if (period === 'weekly') {
periodKey = `${date.year()}-W${date.isoWeek()}`;
} else if (period === 'monthly') {
periodKey = date.format('YYYY-MM');
}

growthData[periodKey] = (growthData[periodKey] || 0) + 1;
}
}
});

const allMonths = Array.from({ length: 12 }, (_, i) =>
dayjs().month(i).format('YYYY-MM'),
);
allMonths.forEach((month) => {
if (!growthData[month]) {
growthData[month] = 0;
}
});

return Object.entries(growthData).map(([date, count]) => ({ date, count }));
};

const growthData = userGrowth(users);

return (
<div className="px-9 py-10 bg-tertiary dark:bg-dark-bg">
<h3 className="text-3xl text-center text-grey-600 font-bold">
User Growth
</h3>

<div className="flex flex-wrap flex-row justify-between">
<div>
<label
htmlFor="year"
style={{ color: '#bdbdbd', marginRight: '10px' }}
>
Year:
</label>
<select
id="year"
value={selectedYear}
onChange={(e) => setSelectedYear(e.target.value)}
style={{
padding: '5px 10px',
borderColor: '#ccc',
borderRadius: '4px',
color: '#bdbdbd',
}}
>
{Array.from({ length: 5 }).map((_, index) => {
const year = dayjs().year() - index;
return (
<option key={year} value={year.toString()}>
{year}
</option>
);
})}
</select>
</div>

<div>
<label
htmlFor="period"
style={{ color: '#bdbdbd', marginRight: '10px' }}
>
Period:
</label>
<select
id="period"
value={period}
onChange={(e) =>
setPeriod(e.target.value as 'daily' | 'weekly' | 'monthly')
}
style={{
padding: '5px 10px',
borderColor: '#ccc',
borderRadius: '4px',
color: '#bdbdbd',
}}
>
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
</select>
</div>
</div>

{growthData.length === 0 ? (
<p>No data available</p>
) : (
<div>
<ResponsiveContainer width="100%" height={400}>
<LineChart
data={growthData}
margin={{ top: 20, right: 30, left: 20, bottom: 20 }}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="date"
tickFormatter={(str) => {
if (period === 'daily') {
return dayjs(str).format('MMM DD');
}
if (period === 'weekly') {
return str.split('-')[1];
}
if (period === 'monthly') {
return dayjs(str).format('MMM YYYY');
}
return str;
}}
/>
<YAxis
label={{
value: 'USERS',
angle: -90,
position: 'insideLeft',
style: { fontSize: 14, fill: '#bdbdbd' },
}}
/>
<Tooltip />
<Legend />
<Line
type="monotone"
dataKey="count"
stroke="#8884d8"
name="User(s)"
dot={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
)}
</div>
);
}

export default UserGrowth;
Loading

0 comments on commit 0cd551b

Please sign in to comment.