diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index 064822fb..797c5b80 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -464,6 +464,7 @@ "Sprint Ratings": "Sprint Notations", "Please wait to be added to a program or cohort": "Veuillez attendre d'être ajouté à un programme ou à une cohorte", "Select all the required information": "Entrez toutes les informations requises", + "Enter all the required information": "Entrez toutes les informations requises", "Are you sure you want to delete this user?": "Êtes-vous sûr de vouloir supprimer cet utilisateur ?", "Come shape the future together": "Venez former l'avenir ensemble", "Content1": "Je suis extrêmement impressionné par Pulse et leur plateforme de gestion de la performance. Depuis que nous utilisons leurs services, cela a été un véritable changement pour notre organisation. La plateforme est intuitive, facile à naviguer et riche en fonctionnalités puissantes", @@ -473,4 +474,4 @@ "Director": "Directeur", "Andela": "Andela", "University of Rwanda": "Université du Rwanda" -} \ No newline at end of file +} diff --git a/public/locales/kn/translation.json b/public/locales/kn/translation.json index 09f3c665..c70e0a32 100644 --- a/public/locales/kn/translation.json +++ b/public/locales/kn/translation.json @@ -453,6 +453,7 @@ "Sprint Ratings": "Amanota ya Sprint", "Please wait to be added to a program or cohort": "Tegereza tukongere muri porogarame cyangwa itsinda", "Select all the required information": "Shyiramo amakuru yose asabwa", + "Enter all the required information": "Shyiramo amakuru yose asabwa", "Are you sure you want to delete this user?": "urashaka kwemeza ikigikorwa cyo gusiba uyumuntu ?", "Come shape the future together": "Dufatanye kwubaka ejo Hazaza", "Content1": "Nshimishijwe cyane na Pulse n'ikoranabuhanga ryabo ryo gucunga imikorere. Kuva natangira gukoresha serivisi zabo, byabaye impinduka ikomeye mu kigo cyacu. iri koranabuhanga riroroshye kurikoresha, kandi ryubakanye ubuhanga n' ubushobozi buhanitse.", @@ -462,4 +463,4 @@ "Director": "Umuyobozi mukuru", "Andela": "Andela", "University of Rwanda": "Kaminuza y' u Rwanda" -} \ No newline at end of file +} diff --git a/src/Chart/BarChart.tsx b/src/Chart/BarChart.tsx new file mode 100644 index 00000000..895a544a --- /dev/null +++ b/src/Chart/BarChart.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { Bar } from 'react-chartjs-2'; +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + BarElement, + Title, + Tooltip, + Legend, +} from 'chart.js'; + +ChartJS.register( + CategoryScale, + LinearScale, + BarElement, + Title, + Tooltip, + Legend, +); + +interface Props {} + +// eslint-disable-next-line react/function-component-definition +const BarChart: React.FC = () => { + const data = { + labels: [ + '01', + '02', + '03', + '04', + '05', + '06', + '07', + '08', + '09', + '10', + '11', + '12', + ], + datasets: [ + { + label: 'Nova', + data: [12, 19, 3, 5, 2, 3, 12, 14, 5, 7, 9, 11], + backgroundColor: '#5A6ACF', + borderRadius: 0, + barThickness: 8, + }, + { + label: 'Fighters', + data: [10, 15, 5, 8, 6, 9, 13, 9, 6, 8, 7, 10], + backgroundColor: '#D1D5DB', + borderRadius: 0, + barThickness: 8, + }, + ], + }; + + const options = { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: 'bottom' as const, + labels: { + color: '#D1D5DB', + }, + }, + tooltip: { + enabled: true, + }, + }, + scales: { + x: { + grid: { + display: false, + }, + ticks: { + color: '#737B8B', + }, + }, + y: { + grid: { + borderDash: [5, 5], + color: '#ffffff', + }, + ticks: { + color: '#ffffff', + }, + }, + }, + }; + + return ( +
+ +
+ ); +}; + +export default BarChart; diff --git a/src/Chart/PieChart.tsx b/src/Chart/PieChart.tsx new file mode 100644 index 00000000..2ad039f2 --- /dev/null +++ b/src/Chart/PieChart.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { Doughnut } from 'react-chartjs-2'; +import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'; + +ChartJS.register(ArcElement, Tooltip, Legend); + +// eslint-disable-next-line react/function-component-definition +const PieChart: React.FC = () => { + const data = { + labels: ['new pie chart'], + datasets: [ + { + label: 'rates', + data: [30, 100], + backgroundColor: ['#4F46E5', '#A5B4FC'], + hoverOffset: 4, + }, + ], + }; + const data2 = { + labels: ['new pie chart'], + datasets: [ + { + label: 'rates', + data: [30, 70], + backgroundColor: ['#4F46E5', '#A5B4FC'], + hoverOffset: 4, + }, + ], + }; + const data3 = { + labels: ['new pie chart'], + datasets: [ + { + label: 'rates', + data: [60, 60], + backgroundColor: ['#4F46E5', '#A5B4FC'], + hoverOffset: 4, + }, + ], + }; + + const options = { + responsive: true, + cutout: '70%', + plugins: { + tooltip: { + callbacks: { + // eslint-disable-next-line func-names, object-shorthand + label: function (tooltipItem: any) { + return `${tooltipItem.label}: ${tooltipItem.raw}%`; + }, + }, + }, + legend: { + display: false, + }, + }, + }; + + return ( +
+
+
+ +
+
+

10

+
+
+

New Invitations & Registration

+
+
+ +
+
+

20

+
+
+

Upcoming Events

+
+
+ +
+
+

50

+
+
+

Active& Progressive Tickets

+
+
+
+ ); +}; + +export default PieChart; diff --git a/src/Chart/UsersChart.tsx b/src/Chart/UsersChart.tsx new file mode 100644 index 00000000..ee3ab2aa --- /dev/null +++ b/src/Chart/UsersChart.tsx @@ -0,0 +1,113 @@ +import React from 'react'; +import { Line } from 'react-chartjs-2'; +import { + Chart as ChartJS, + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, +} from 'chart.js'; + +ChartJS.register( + CategoryScale, + LinearScale, + PointElement, + LineElement, + Title, + Tooltip, + Legend, +); + +// eslint-disable-next-line react/function-component-definition +const usersChart: React.FC = () => { + const data = { + labels: [ + '01', + '02', + '03', + '04', + '05', + '06', + '07', + '08', + '09', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '20', + '21', + '22', + '23', + '24', + '25', + '26', + '27', + '28', + '29', + '30', + '31', + ], + datasets: [ + { + label: 'Andela', + data: [ + 1, 3, 0, 2, 1, 3, 2, 0, 2, 1, 3, 0, 2, 1, 4, 1, 2, 4, 7, 2, 3, 4, 4, + 3, 8, 0, 3, 5, 7, + ], + fill: false, + borderColor: '#4F46E5', + tension: 0.4, + }, + { + label: 'NESA', + data: [ + 2, 3, 6, 4, 3, 4, 2, 1, 2, 6, 2, 2, 3, 2, 3, 5, 7, 2, 1, 2, 4, 6, 6, + 1, 2, 3, 4, 5, 6.5, + ], + fill: false, + borderColor: '#8C8120', + tension: 0.4, + }, + ], + }; + + const options = { + responsive: true, + plugins: { + legend: { + position: 'bottom' as const, + }, + }, + scales: { + y: { + beginAtZero: true, + grid: { + color: '#D1D5DB', + }, + }, + x: { + grid: { + display: false, + }, + }, + }, + }; + + return ( +
+ +
+ ); +}; + +export default usersChart; diff --git a/src/components/AdminDashboardTable.tsx b/src/components/AdminDashboardTable.tsx new file mode 100644 index 00000000..71184b3c --- /dev/null +++ b/src/components/AdminDashboardTable.tsx @@ -0,0 +1,316 @@ +<<<<<<< HEAD +<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f99dac5 (new piechart and stats updated) +import React, { useState } from 'react'; +import { FaEye } from 'react-icons/fa'; +import TeamDetailsModal from './AdminTeamDetails'; + +interface TeamData { + ttlName?: string; + team?: string; + organization?: string; + program?: string; + phase?: string; + cohort?: string; + activeUsers?: number; + droppedUsers?: number; + rating?: number; + logins: string; + users: number; +} + +const DashboardTableDesign: React.FC = () => { + const [selectedTeam, setSelectedTeam] = useState(null); + const [isModalOpen, setIsModalOpen] = useState(false); + + const dummyData: TeamData[] = [ + { + team: 'Nova', + logins: '2.4k', + users: 45, + ttlName: 'Sostene', + organization: 'Tech Corp', +<<<<<<< HEAD + program: 'Atlp1', +======= + program: 'Web Development', +>>>>>>> f99dac5 (new piechart and stats updated) + phase: 'Phase 2', + cohort: 'Cohort 3', + activeUsers: 42, + droppedUsers: 3, + rating: 4.8 + }, + { + team: 'Fighters', + logins: '1.8k', + users: 32, +<<<<<<< HEAD + ttlName: 'Sostene', + organization: 'Andela', + program: 'Atlp1', +======= + ttlName: 'John Doe', + organization: 'Tech Corp', + program: 'Mobile Development', +>>>>>>> f99dac5 (new piechart and stats updated) + phase: 'Phase 1', + cohort: 'Cohort 2', + activeUsers: 30, + droppedUsers: 2, + rating: 4.5 + }, + { + team: 'Bitcrafters', + logins: '1.2k', + users: 28, +<<<<<<< HEAD + ttlName: 'Jacqueline', + organization: 'Irembo', +======= + ttlName: 'Jane Smith', + organization: 'Tech Corp', +>>>>>>> f99dac5 (new piechart and stats updated) + program: 'Data Science', + phase: 'Phase 3', + cohort: 'Cohort 1', + activeUsers: 25, + droppedUsers: 3, + rating: 4.6 + }, + { + team: 'Team1', + logins: '3.1k', + users: 52, +<<<<<<< HEAD + ttlName: 'Alice', +======= + ttlName: 'Alice Johnson', +>>>>>>> f99dac5 (new piechart and stats updated) + organization: 'Tech Corp', + program: 'Cloud Computing', + phase: 'Phase 2', + cohort: 'Cohort 4', + activeUsers: 48, + droppedUsers: 4, + rating: 4.7 + }, + { + team: 'Team2', + logins: '0.9k', + users: 19, +<<<<<<< HEAD + ttlName: 'Bob', + organization: 'Tech', +======= + ttlName: 'Bob Wilson', + organization: 'Tech Corp', +>>>>>>> f99dac5 (new piechart and stats updated) + program: 'DevOps', + phase: 'Phase 1', + cohort: 'Cohort 2', + activeUsers: 17, + droppedUsers: 2, + rating: 4.4 + } + ]; + + const handleViewClick = (team: TeamData) => { + setSelectedTeam(team); + setIsModalOpen(true); + }; + +<<<<<<< HEAD +======= +======= +import { useQuery } from '@apollo/client'; +>>>>>>> 6997c81 (ft-admin-dashboard-can-vieww-table-teams) +import React from 'react'; +import { FaEye } from 'react-icons/fa'; +import { useTranslation } from 'react-i18next'; +import DataTable from './DataTable'; +import { GET_TEAMS_CARDS } from './CoordinatorCard'; + +function DashboardTableDesign() { + const { t } = useTranslation(); + const { + data: TeamsData, + loading, + error, + refetch, + } = useQuery(GET_TEAMS_CARDS, { + variables: { + orgToken: localStorage.getItem('orgToken'), + }, + fetchPolicy: 'network-only', + }); + const TableData = TeamsData?.getAllTeams.map((items: any) => ({ + teams: items.name, + users: items.members.length, + logins: items.members.reduce( + (total: number, i: any) => total + i.profile.activity.length, + 0, + ), + })); + + const organizationColumns = [ + { Header: t('Teams'), accessor: 'teams' }, + { Header: t('Logins'), accessor: 'logins' }, + { Header: t('Users'), accessor: 'users' }, + { + Header: t('action'), + accessor: '', + Cell: () => ( + <> + + + ), + }, + ]; +<<<<<<< HEAD + +>>>>>>> a052325 (new piechart and stats updated) +======= +>>>>>>> f99dac5 (new piechart and stats updated) + return ( +
+
+

Team Analytics

+
+ +
+
+ +
+
+ + + + + + + + + + + {dummyData.map((row, index) => ( + + + + + + + ))} + +
+
+ Team Name +
+
+
+ Logins +
+
+
+ Users +
+
+
+ Actions +
+
+
+
+ {row.team} +
+
+
{row.logins}
+
+
+ {row.users} +
+
+<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f99dac5 (new piechart and stats updated) + +
+
+ +
+
+ Showing 5 of 12 teams +
+
+ + +
+
+
+<<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> f99dac5 (new piechart and stats updated) + + setIsModalOpen(false)} + teamData={selectedTeam} + /> +<<<<<<< HEAD +======= +>>>>>>> a052325 (new piechart and stats updated) +======= + return ( +
+ +>>>>>>> 6997c81 (ft-admin-dashboard-can-vieww-table-teams) +
+ ); +} + +export default DashboardTableDesign; +======= +
+ ); +}; + +export default DashboardTableDesign; +>>>>>>> f99dac5 (new piechart and stats updated) diff --git a/src/components/AdminTeamDetails.tsx b/src/components/AdminTeamDetails.tsx new file mode 100644 index 00000000..dfe5588c --- /dev/null +++ b/src/components/AdminTeamDetails.tsx @@ -0,0 +1,156 @@ +import React, { useState } from 'react'; +import { FaAngleDown } from "react-icons/fa6"; + +interface TeamData { + ttlName?: string; + team?: string; + organization?: string; + program?: string; + phase?: string; + cohort?: string; + activeUsers?: number; + droppedUsers?: number; + rating?: number; +} + +interface TeamDetailsModalProps { + isOpen: boolean; + onClose: () => void; + teamData: TeamData | null; +} + +const TeamDetailsModal: React.FC = ({ isOpen, onClose, teamData }) => { + if (!isOpen) return null; + + const [showAttendanceSummary, setShowAttendanceSummary] = useState(false); + + const handleAttendanceSummaryEnter = () => { + setShowAttendanceSummary(true); + }; + + const handleAttendanceSummaryLeave = () => { + setShowAttendanceSummary(false); + }; + + return ( +
+
+
+
+

+ Overview +

+

+ Logins +

+
+ +
+ +
+
+
+ +

{teamData?.ttlName || 'Sostene'}

+
+ +
+ +

{teamData?.team}

+
+ +
+ +

{teamData?.organization || 'Organization Name'}

+
+ +
+ +

{teamData?.program || 'Program Name'}

+
+ +
+ +

{teamData?.phase || 'Current Phase'}

+
+ +
+ +

{teamData?.cohort || 'Current Cohort'}

+
+
+ +
+
+ +
+
+

Active Members

+

+ {teamData?.activeUsers || '0'} +

+
+
+

Dropped Members

+

+ {teamData?.droppedUsers || '0'} +

+
+
+
+ +
+ + {showAttendanceSummary && ( +
+

Quality: 1.5

+

Quantity: 2.3

+

Professionalism: 3.1

+
+ )} +
+ +
+ +
+

+ {teamData?.rating || '4.5'} / 5.0 +

+
+
+
+
+
+
+ ); +}; + +export default TeamDetailsModal; \ No newline at end of file diff --git a/src/components/CoordinatorCard.tsx b/src/components/CoordinatorCard.tsx index d210223b..0596b78f 100644 --- a/src/components/CoordinatorCard.tsx +++ b/src/components/CoordinatorCard.tsx @@ -32,6 +32,17 @@ export const GET_TEAMS_CARDS = gql` name lastName firstName + address + activity { + date + city + IPv4 + state + latitude + longitude + postal + failed + } } status { status diff --git a/src/components/DataTable.tsx b/src/components/DataTable.tsx index f015f35e..1b222d9b 100644 --- a/src/components/DataTable.tsx +++ b/src/components/DataTable.tsx @@ -91,7 +91,7 @@ function DataTable({ data, columns, title, loading, className }: TableData) { > {headerGroups.map((headerGroup) => ( - + {headerGroup.headers.map((column) => ( -
+
} /> diff --git a/src/containers/admin-dashBoard/TtlsModal.tsx b/src/containers/admin-dashBoard/TtlsModal.tsx index ba962e70..b75af75b 100644 --- a/src/containers/admin-dashBoard/TtlsModal.tsx +++ b/src/containers/admin-dashBoard/TtlsModal.tsx @@ -81,8 +81,7 @@ export default function TtlsPage() { const [isLoaded, setIsLoaded] = useState(false); const [gitHubStatistics, setGitHubStatistics] = useState({}); const [dropTTLUser, { loading: dropLoading }] = useMutation(DROP_TTL_USER); - const [undropTTLUser, { loading: undropLoading }] = - useMutation(UNDROP_TTL_USER); + const [undropTTLUser, { loading: undropLoading }] = useMutation(UNDROP_TTL_USER); function PaperComponent(props: PaperProps) { return ( - + + )} +