From f7937f7e82813d0ec133d948b589f4fdb3393f07 Mon Sep 17 00:00:00 2001
From: Benjamin Ramet
Date: Tue, 8 Oct 2024 09:59:01 +0200
Subject: [PATCH 1/2] feature : fetch families without account and provide them
in a table
---
server/controllers/statistics.ts | 3 +-
server/stats/villageStats.ts | 22 +++++
.../dashboard-statistics/CountryStats.tsx | 5 +-
.../dashboard-statistics/VillageStats.tsx | 19 ++--
.../charts/DashboardTable.tsx | 93 +++++++++++++------
types/statistics.type.ts | 11 +++
6 files changed, 112 insertions(+), 41 deletions(-)
diff --git a/server/controllers/statistics.ts b/server/controllers/statistics.ts
index aa57358f1..0b03bc8ab 100644
--- a/server/controllers/statistics.ts
+++ b/server/controllers/statistics.ts
@@ -16,7 +16,7 @@ import {
getMinConnections,
getMinDuration,
} from '../stats/sessionStats';
-import { getChildrenCodesCount, getFamilyAccountsCount, getConnectedFamiliesCount } from '../stats/villageStats';
+import { getChildrenCodesCount, getFamilyAccountsCount, getConnectedFamiliesCount, getFamiliesWithoutAccount } from '../stats/villageStats';
import { Controller } from './controller';
export const statisticsController = new Controller('/statistics');
@@ -51,5 +51,6 @@ statisticsController.get({ path: '/villages/:villageId' }, async (_req, res) =>
familyAccountsCount: await getFamilyAccountsCount(villageId),
childrenCodesCount: await getChildrenCodesCount(villageId),
connectedFamiliesCount: await getConnectedFamiliesCount(villageId),
+ familiesWithoutAccount: await getFamiliesWithoutAccount(villageId),
});
});
diff --git a/server/stats/villageStats.ts b/server/stats/villageStats.ts
index 76724b303..d3989d079 100644
--- a/server/stats/villageStats.ts
+++ b/server/stats/villageStats.ts
@@ -37,3 +37,25 @@ export const getConnectedFamiliesCount = async (villageId: number) => {
return connectedFamiliesCount;
};
+
+export const getFamiliesWithoutAccount = async (villageId: number) => {
+ const familiesWithoutAccount = await studentRepository
+ .createQueryBuilder('student')
+ .innerJoin('student.classroom', 'classroom')
+ .innerJoin('classroom.user', 'user')
+ .innerJoin('user.village', 'village')
+ .where('classroom.villageId = :villageId', { villageId })
+ .andWhere('student.numLinkedAccount < 1')
+ .select([
+ 'user.firstname AS user_firstname',
+ 'user.lastname AS user_lastname',
+ 'user.email AS user_email',
+ 'student.firstname AS student_firstname',
+ 'student.lastname AS student_lastname',
+ 'student.id AS student_id',
+ 'village.name AS village_name',
+ ])
+ .getRawMany();
+
+ return familiesWithoutAccount;
+};
diff --git a/src/components/admin/dashboard-statistics/CountryStats.tsx b/src/components/admin/dashboard-statistics/CountryStats.tsx
index 883802aeb..1213ddc5d 100644
--- a/src/components/admin/dashboard-statistics/CountryStats.tsx
+++ b/src/components/admin/dashboard-statistics/CountryStats.tsx
@@ -8,7 +8,6 @@ import AverageStatsCard from './cards/AverageStatsCard/AverageStatsCard';
import ClassesExchangesCard from './cards/ClassesExchangesCard/ClassesExchangesCard';
import StatsCard from './cards/StatsCard/StatsCard';
import BarCharts from './charts/BarCharts';
-import DashboardTable from './charts/DashboardTable';
import HorizontalBars from './charts/HorizontalChart';
import PieCharts from './charts/PieCharts';
import CountriesDropdown from './filters/CountriesDropdown';
@@ -99,9 +98,9 @@ const CountryStats = () => {
))}
- */}
Nombre de classes inscrites
Nombre de classes connectées
diff --git a/src/components/admin/dashboard-statistics/VillageStats.tsx b/src/components/admin/dashboard-statistics/VillageStats.tsx
index b1de79c27..b415908ff 100644
--- a/src/components/admin/dashboard-statistics/VillageStats.tsx
+++ b/src/components/admin/dashboard-statistics/VillageStats.tsx
@@ -6,6 +6,7 @@ import Tabs from '@mui/material/Tabs';
import Typography from '@mui/material/Typography';
import StatsCard from './cards/StatsCard/StatsCard';
+import DashboardTable from './charts/DashboardTable';
import CountriesDropdown from './filters/CountriesDropdown';
import VillageDropdown from './filters/VillageDropdown';
import { PelicoCard } from './pelico-card';
@@ -26,7 +27,6 @@ const VillageStats = () => {
const { villages } = useVillages(options);
const villagesStats = useGetVillagesStats(+selectedVillage);
-
React.useEffect(() => {
setOptions({
countryIsoCode: selectedCountry,
@@ -72,7 +72,6 @@ const VillageStats = () => {
);
}
-
return (
<>
{
-
+ {villagesStats.data?.familiesWithoutAccount.length ? (
+
+
+
+ ) : (
+ Merci de sélectionner un village-monde pour analyser ses statistiques.
+ )}
@@ -112,10 +115,10 @@ const VillageStats = () => {
sx={{
display: 'flex',
flexDirection: {
- xs: 'column', // Column direction for small devices
- md: 'row', // Row direction for medium and larger devices
+ xs: 'column',
+ md: 'row',
},
- gap: 2, // Adds spacing between the child elements
+ gap: 2,
}}
>
Nombre de profs ayant créé des comptes famille
diff --git a/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx b/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx
index 2a9f86b3d..d9290cc30 100644
--- a/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx
+++ b/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx
@@ -8,48 +8,83 @@ import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
-// function createData(classroom: string, vm: sting, prof: string, status: string) {
-// return { classroom, vm, prof, status };
-// }
-
-// const rows = [
-// createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
-// createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
-// createData('Eclair', 262, 16.0, 24, 6.0),
-// createData('Cupcake', 305, 3.7, 67, 4.3),
-// createData('Gingerbread', 356, 16.0, 49, 3.9),
-// ];
-
-export default function DashboardTable() {
+import type { FamiliesWithoutAccount } from 'types/statistics.type';
+
+function createRows(data: FamiliesWithoutAccount[]): FamiliesWithoutAccountRow[] {
+ return data.map((row) => {
+ return {
+ id: row.student_id,
+ student: `${row.student_firstname} ${row.student_lastname}`,
+ vm: row.village_name,
+ user: `${row.user_firstname} ${row.user_lastname}`,
+ status: 'Compte non créé',
+ };
+ });
+}
+
+/* const rows = [
+ createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
+ createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
+ createData('Eclair', 262, 16.0, 24, 6.0),
+ createData('Cupcake', 305, 3.7, 67, 4.3),
+ createData('Gingerbread', 356, 16.0, 49, 3.9),
+]; */
+
+/* const getHeaders = (data: []) => {
+ return Object.keys(data[0]);
+}; */
+/* const getRows = (data: []) => {
+ return data.map((row) => )
+}; */
+
+const FamiliesWithoutAccountHeaders = ['Enfant', 'Professeur', 'Village-Monde', 'Statut'];
+
+interface FamiliesWithoutAccountRow {
+ id: number;
+ student: string;
+ user: string;
+ vm: string;
+ status: string;
+}
+
+interface DashboardTableProps {
+ data: FamiliesWithoutAccount[] | undefined;
+}
+
+export default function DashboardTable({ data }: DashboardTableProps) {
+ const [rows, setRows] = React.useState([]);
+ React.useEffect(() => {
+ if (data) {
+ setRows([]);
+ setRows(createRows(data));
+ }
+ }, [data]);
return (
- A surveiller
+ À surveiller
- Classe
- Village-Monde
- Professeur
- Statut
+ {FamiliesWithoutAccountHeaders.map((header) => (
+ <>
+
+ {header}
+
+ >
+ ))}
- {/* {rows.map((row) => (
-
-
- {row.name}
-
- {row.classroom}
+ {rows.map((row) => (
+
+ {row.student}
+ {row.user}
{row.vm}
- {row.prof}
{row.status}
- ))} */}
+ ))}
diff --git a/types/statistics.type.ts b/types/statistics.type.ts
index 3f644e48a..1ecf3bc0c 100644
--- a/types/statistics.type.ts
+++ b/types/statistics.type.ts
@@ -30,4 +30,15 @@ export interface VillageStats {
childrenCodesCount: number;
familyAccountsCount: number;
connectedFamiliesCount: number;
+ familiesWithoutAccount: FamiliesWithoutAccount[];
+}
+
+export interface FamiliesWithoutAccount {
+ student_id: number;
+ student_firstname: string;
+ student_lastname: string;
+ village_name: string;
+ user_firstname: string;
+ user_lastname: string;
+ user_email: string;
}
From b8f0c690895b92a258a89e132ba9b6544c637521 Mon Sep 17 00:00:00 2001
From: Benjamin Ramet
Date: Thu, 10 Oct 2024 09:34:48 +0200
Subject: [PATCH 2/2] Renamed AdminTable into OneVillageTable for a more
greneric use, added a flag, review on the stats table for the family part
---
server/stats/villageStats.ts | 5 +-
src/components/admin/AdminTable.tsx | 164 ----------------
src/components/admin/OneVillageTable.tsx | 175 ++++++++++++++++++
.../dashboard-statistics/VillageStats.tsx | 85 ++++++---
.../charts/DashboardTable.tsx | 37 ++--
src/pages/admin/h5p/index.tsx | 5 +-
src/pages/admin/newportal/h5p/index.tsx | 5 +-
.../admin/newportal/manage/users/index.tsx | 5 +-
.../admin/newportal/manage/villages/index.tsx | 5 +-
src/pages/admin/users/index.tsx | 5 +-
src/pages/admin/villages/index.tsx | 5 +-
types/statistics.type.ts | 5 +-
12 files changed, 271 insertions(+), 230 deletions(-)
delete mode 100644 src/components/admin/AdminTable.tsx
create mode 100644 src/components/admin/OneVillageTable.tsx
diff --git a/server/stats/villageStats.ts b/server/stats/villageStats.ts
index d3989d079..7caf8b012 100644
--- a/server/stats/villageStats.ts
+++ b/server/stats/villageStats.ts
@@ -47,9 +47,8 @@ export const getFamiliesWithoutAccount = async (villageId: number) => {
.where('classroom.villageId = :villageId', { villageId })
.andWhere('student.numLinkedAccount < 1')
.select([
- 'user.firstname AS user_firstname',
- 'user.lastname AS user_lastname',
- 'user.email AS user_email',
+ 'classroom.name AS classroom_name',
+ 'classroom.countryCode as classroom_country',
'student.firstname AS student_firstname',
'student.lastname AS student_lastname',
'student.id AS student_id',
diff --git a/src/components/admin/AdminTable.tsx b/src/components/admin/AdminTable.tsx
deleted file mode 100644
index 26e0d773d..000000000
--- a/src/components/admin/AdminTable.tsx
+++ /dev/null
@@ -1,164 +0,0 @@
-import React from 'react';
-
-import NoSsr from '@mui/material/NoSsr';
-import Table from '@mui/material/Table';
-import TableBody from '@mui/material/TableBody';
-import TableCell from '@mui/material/TableCell';
-import TableHead from '@mui/material/TableHead';
-import TablePagination from '@mui/material/TablePagination';
-import TableRow from '@mui/material/TableRow';
-import TableSortLabel from '@mui/material/TableSortLabel';
-
-function paginate(array: T[], pageSize: number, pageNumber: number): T[] {
- // human-readable page numbers usually start with 1, so we reduce 1 in the first argument
- return array.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
-}
-
-interface TableOptions {
- limit?: number;
- page?: number;
- order?: string;
- sort?: 'asc' | 'desc';
- search?: string;
-}
-interface AdminTableProps {
- 'aria-label'?: string;
- emptyPlaceholder: React.ReactNode | React.ReactNodeArray;
- data: Array<{ id: string | number; [key: string]: string | boolean | number | React.ReactNode }>;
- columns: Array<{ key: string; label: string; sortable?: boolean }>;
- actions?(id: string | number, index: number): React.ReactNode | React.ReactNodeArray;
-}
-
-export const AdminTable = ({ 'aria-label': ariaLabel, emptyPlaceholder, data, columns, actions }: AdminTableProps) => {
- const [options, setTableOptions] = React.useState({
- page: 1,
- limit: 10,
- sort: 'asc',
- });
- const handleChangePage = (_event: unknown, newPage: number) => {
- setTableOptions({ ...options, page: newPage + 1 });
- };
- const handleChangeRowsPerPage = (event: React.ChangeEvent) => {
- setTableOptions({ ...options, page: 1, limit: parseInt(event.target.value, 10) });
- };
- const onSortBy = (name: string) => () => {
- if (options.order === name) {
- setTableOptions({ ...options, page: 1, sort: options.sort === 'asc' ? 'desc' : 'asc' });
- } else {
- setTableOptions({ ...options, page: 1, order: name });
- }
- };
-
- const usePagination = options.page !== undefined && options.limit !== undefined;
- const displayedData = React.useMemo(() => {
- const useSort = options.sort !== undefined && options.order !== undefined;
- const sortedData = useSort
- ? data.sort((a, b) => {
- return (a[options.order || 0] || 0) >= (b[options.order || 0] || 0) ? (options.sort === 'asc' ? 1 : -1) : options.sort === 'asc' ? -1 : 1;
- })
- : data;
- return usePagination ? paginate(sortedData, options.limit || 10, options.page || 1) : sortedData;
- }, [data, options.sort, options.order, options.limit, options.page, usePagination]);
-
- return (
-
-
- {data.length === 0 ? (
-
-
-
- {emptyPlaceholder || 'Cette liste est vide !'}
-
-
-
- ) : (
- <>
- theme.palette.secondary.main,
- color: 'white',
- fontWeight: 'bold',
- minHeight: 'unset',
- padding: '8px 8px 8px 16px',
- }}
- >
-
- {columns.map((c) => (
-
- {c.sortable ? (
-
- {c.label}
- {options.order === c.label ? (
-
- {options.sort === 'desc' ? 'sorted descending' : 'sorted ascending'}
-
- ) : null}
-
- ) : (
- c.label
- )}
-
- ))}
- {actions && (
-
- Actions
-
- )}
-
-
-
- {displayedData.map((d, index) => (
-
- {columns.map((c) => (
- {d[c.key] !== undefined ? d[c.key] : ''}
- ))}
- {actions && (
-
- {actions(d.id, index)}
-
- )}
-
- ))}
- {usePagination && (
-
-
-
- )}
-
- >
- )}
-
-
- );
-};
diff --git a/src/components/admin/OneVillageTable.tsx b/src/components/admin/OneVillageTable.tsx
new file mode 100644
index 000000000..24525eb5f
--- /dev/null
+++ b/src/components/admin/OneVillageTable.tsx
@@ -0,0 +1,175 @@
+import React from 'react';
+
+import RemoveRedEyeIcon from '@mui/icons-material/RemoveRedEye';
+import { Paper, TableContainer } from '@mui/material';
+import NoSsr from '@mui/material/NoSsr';
+import Table from '@mui/material/Table';
+import TableBody from '@mui/material/TableBody';
+import TableCell from '@mui/material/TableCell';
+import TableHead from '@mui/material/TableHead';
+import TablePagination from '@mui/material/TablePagination';
+import TableRow from '@mui/material/TableRow';
+import TableSortLabel from '@mui/material/TableSortLabel';
+import { useTheme } from '@mui/material/styles';
+
+function paginate(array: T[], pageSize: number, pageNumber: number): T[] {
+ // human-readable page numbers usually start with 1, so we reduce 1 in the first argument
+ return array.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
+}
+
+export interface TableOptions {
+ limit?: number;
+ page?: number;
+ order?: string;
+ sort?: 'asc' | 'desc';
+ search?: string;
+}
+interface OneVillageTableProps {
+ 'aria-label'?: string;
+ admin: boolean;
+ emptyPlaceholder: React.ReactNode | React.ReactNodeArray;
+ data: Array<{ id: string | number; [key: string]: string | boolean | number | React.ReactNode }>;
+ columns: Array<{ key: string; label: string; sortable?: boolean }>;
+ actions?(id: string | number, index: number): React.ReactNode | React.ReactNodeArray;
+ titleContent?: string;
+}
+
+export const OneVillageTable = ({ 'aria-label': ariaLabel, emptyPlaceholder, admin, data, columns, actions, titleContent }: OneVillageTableProps) => {
+ const theme = useTheme();
+ const color = admin ? 'white' : 'black';
+ const backgroundColor = admin ? theme.palette.secondary.main : 'white';
+ const [options, setTableOptions] = React.useState({
+ page: 1,
+ limit: 10,
+ sort: 'asc',
+ });
+ const handleChangePage = (_event: unknown, newPage: number) => {
+ setTableOptions({ ...options, page: newPage + 1 });
+ };
+ const handleChangeRowsPerPage = (event: React.ChangeEvent) => {
+ setTableOptions({ ...options, page: 1, limit: parseInt(event.target.value, 10) });
+ };
+ const onSortBy = (name: string) => () => {
+ if (options.order === name) {
+ setTableOptions({ ...options, page: 1, sort: options.sort === 'asc' ? 'desc' : 'asc' });
+ } else {
+ setTableOptions({ ...options, page: 1, order: name });
+ }
+ };
+
+ const usePagination = options.page !== undefined && options.limit !== undefined;
+ const displayedData = React.useMemo(() => {
+ const useSort = options.sort !== undefined && options.order !== undefined;
+ const sortedData = useSort
+ ? data.sort((a, b) => {
+ return (a[options.order || 0] || 0) >= (b[options.order || 0] || 0) ? (options.sort === 'asc' ? 1 : -1) : options.sort === 'asc' ? -1 : 1;
+ })
+ : data;
+ return usePagination ? paginate(sortedData, options.limit || 10, options.page || 1) : sortedData;
+ }, [data, options.sort, options.order, options.limit, options.page, usePagination]);
+
+ return (
+
+
+
+ {data.length === 0 ? (
+
+
+
+ {emptyPlaceholder || 'Cette liste est vide !'}
+
+
+
+ ) : (
+ <>
+
+ {titleContent && (
+
+
+ {titleContent}
+
+
+ )}
+
+ {columns.map((c) => (
+
+ {c.sortable ? (
+
+ {c.label}
+ {options.order === c.label ? (
+
+ {options.sort === 'desc' ? 'sorted descending' : 'sorted ascending'}
+
+ ) : null}
+
+ ) : (
+ c.label
+ )}
+
+ ))}
+ {actions && (
+
+ Actions
+
+ )}
+
+
+
+ {displayedData.map((d, index) => (
+
+ {columns.map((c) => {
+ return {d[c.key] !== undefined ? d[c.key] : ''};
+ })}
+ {actions && (
+
+ {actions(d.id, index)}
+
+ )}
+
+ ))}
+ {usePagination && (
+
+
+
+ )}
+
+ >
+ )}
+
+
+
+ );
+};
diff --git a/src/components/admin/dashboard-statistics/VillageStats.tsx b/src/components/admin/dashboard-statistics/VillageStats.tsx
index b415908ff..dd706e24a 100644
--- a/src/components/admin/dashboard-statistics/VillageStats.tsx
+++ b/src/components/admin/dashboard-statistics/VillageStats.tsx
@@ -5,8 +5,8 @@ import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
import Typography from '@mui/material/Typography';
+import { OneVillageTable } from '../OneVillageTable';
import StatsCard from './cards/StatsCard/StatsCard';
-import DashboardTable from './charts/DashboardTable';
import CountriesDropdown from './filters/CountriesDropdown';
import VillageDropdown from './filters/VillageDropdown';
import { PelicoCard } from './pelico-card';
@@ -33,6 +33,14 @@ const VillageStats = () => {
});
}, [selectedCountry]);
+ const [rows, setRows] = React.useState>([]);
+ React.useEffect(() => {
+ if (villagesStats.data?.familiesWithoutAccount) {
+ setRows([]);
+ setRows(createRows(villagesStats.data?.familiesWithoutAccount));
+ }
+ }, [villagesStats.data?.familiesWithoutAccount]);
+
const handleCountryChange = (country: string) => {
setSelectedCountry(country);
setSelectedVillage('');
@@ -58,7 +66,13 @@ const VillageStats = () => {
const handleTabChange = (_event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};
-
+ const FamiliesWithoutAccountHeaders = [
+ { key: 'student', label: 'Nom Prénom Enfant', sortable: true },
+ { key: 'vm', label: 'Village-Monde', sortable: true },
+ { key: 'classroom', label: 'Classe', sortable: true },
+ { key: 'country', label: 'Pays', sortable: true },
+ { key: 'creationDate', label: 'Date de création identifiant', sortable: true },
+ ];
function CustomTabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
@@ -72,6 +86,27 @@ const VillageStats = () => {
);
}
+ function createRows(
+ data: Array<{
+ student_id: string | number;
+ student_firstname: string;
+ student_lastname: string;
+ village_name: string;
+ classroom_name: string;
+ classroom_country: string;
+ }>,
+ ): Array<{ id: string | number; [key: string]: string | boolean | number | React.ReactNode }> {
+ return data.map((row) => {
+ return {
+ id: row.student_id, // id is string | number
+ student: `${row.student_firstname} ${row.student_lastname}`, // string
+ vm: row.village_name, // string
+ classroom: row.classroom_name, // string
+ country: row.classroom_country, // string
+ creationDate: 'À venir', // string
+ };
+ });
+ }
return (
<>
{
- {villagesStats.data?.familiesWithoutAccount.length ? (
-
-
-
- ) : (
- Merci de sélectionner un village-monde pour analyser ses statistiques.
- )}
@@ -110,21 +138,30 @@ const VillageStats = () => {
{!selectedVillage ? (
) : (
-
- Nombre de profs ayant créé des comptes famille
- Nombre de codes enfant créés
- Nombre de familles connectées
-
+ <>
+ {pelicoMessage}
}
+ data={rows}
+ columns={FamiliesWithoutAccountHeaders}
+ titleContent={`À surveiller : comptes non créés (${rows.length})`}
+ />
+
+ Nombre de profs ayant créé des comptes famille
+ Nombre de codes enfant créés
+ Nombre de familles connectées
+
+ >
)}
>
diff --git a/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx b/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx
index d9290cc30..f7b5ebb02 100644
--- a/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx
+++ b/src/components/admin/dashboard-statistics/charts/DashboardTable.tsx
@@ -1,5 +1,6 @@
import React from 'react';
+import { TableSortLabel } from '@mui/material';
import Paper from '@mui/material/Paper';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
@@ -16,35 +17,22 @@ function createRows(data: FamiliesWithoutAccount[]): FamiliesWithoutAccountRow[]
id: row.student_id,
student: `${row.student_firstname} ${row.student_lastname}`,
vm: row.village_name,
- user: `${row.user_firstname} ${row.user_lastname}`,
- status: 'Compte non créé',
+ classroom: row.classroom_name,
+ country: row.classroom_country,
+ creationDate: 'À venir',
};
});
}
-/* const rows = [
- createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
- createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
- createData('Eclair', 262, 16.0, 24, 6.0),
- createData('Cupcake', 305, 3.7, 67, 4.3),
- createData('Gingerbread', 356, 16.0, 49, 3.9),
-]; */
-
-/* const getHeaders = (data: []) => {
- return Object.keys(data[0]);
-}; */
-/* const getRows = (data: []) => {
- return data.map((row) => )
-}; */
-
-const FamiliesWithoutAccountHeaders = ['Enfant', 'Professeur', 'Village-Monde', 'Statut'];
+const FamiliesWithoutAccountHeaders = ['Nom Prénom Enfant', 'Village-Monde', 'Classe', 'Pays', 'Date de création identifiant'];
interface FamiliesWithoutAccountRow {
id: number;
student: string;
- user: string;
+ classroom: string;
vm: string;
- status: string;
+ country: string;
+ creationDate: string;
}
interface DashboardTableProps {
@@ -64,13 +52,13 @@ export default function DashboardTable({ data }: DashboardTableProps) {
- À surveiller
+ À surveiller : comptes non créés ({rows.length})
{FamiliesWithoutAccountHeaders.map((header) => (
<>
- {header}
+ {header}
>
))}
@@ -80,9 +68,10 @@ export default function DashboardTable({ data }: DashboardTableProps) {
{rows.map((row) => (
{row.student}
- {row.user}
{row.vm}
- {row.status}
+ {row.classroom}
+ {row.country}
+ {row.creationDate}
))}
diff --git a/src/pages/admin/h5p/index.tsx b/src/pages/admin/h5p/index.tsx
index de4626772..a2747fc23 100644
--- a/src/pages/admin/h5p/index.tsx
+++ b/src/pages/admin/h5p/index.tsx
@@ -13,8 +13,8 @@ import MaterialLink from '@mui/material/Link';
import { useDeleteH5pContentMutation } from 'src/api/h5p/h5p-content.delete';
import { useH5pContentList } from 'src/api/h5p/h5p-content.list';
import { Modal } from 'src/components/Modal';
-import { AdminTable } from 'src/components/admin/AdminTable';
import { AdminTile } from 'src/components/admin/AdminTile';
+import { OneVillageTable } from 'src/components/admin/OneVillageTable';
import { defaultContainedButtonStyle } from 'src/styles/variables.const';
const H5pList = () => {
@@ -74,7 +74,8 @@ const H5pList = () => {
}
>
-
{"Vous n'avez pas encore de contenu H5P ! "}
diff --git a/src/pages/admin/newportal/h5p/index.tsx b/src/pages/admin/newportal/h5p/index.tsx
index 5dc3f544c..a77f9ee5b 100644
--- a/src/pages/admin/newportal/h5p/index.tsx
+++ b/src/pages/admin/newportal/h5p/index.tsx
@@ -12,8 +12,8 @@ import { Button, NoSsr, IconButton, Tooltip } from '@mui/material';
import { useDeleteH5pContentMutation } from 'src/api/h5p/h5p-content.delete';
import { useH5pContentList } from 'src/api/h5p/h5p-content.list';
import { Modal } from 'src/components/Modal';
-import { AdminTable } from 'src/components/admin/AdminTable';
import { AdminTile } from 'src/components/admin/AdminTile';
+import { OneVillageTable } from 'src/components/admin/OneVillageTable';
import { defaultContainedButtonStyle } from 'src/styles/variables.const';
import BackArrow from 'src/svg/back-arrow.svg';
@@ -75,7 +75,8 @@ const H5pList = () => {
}
>
-
{"Vous n'avez pas encore de contenu H5P ! "}
diff --git a/src/pages/admin/newportal/manage/users/index.tsx b/src/pages/admin/newportal/manage/users/index.tsx
index 18e4da8eb..b92744209 100644
--- a/src/pages/admin/newportal/manage/users/index.tsx
+++ b/src/pages/admin/newportal/manage/users/index.tsx
@@ -16,8 +16,8 @@ import Tooltip from '@mui/material/Tooltip';
import { useUsers } from 'src/api/user/user.list';
import { Modal } from 'src/components/Modal';
-import { AdminTable } from 'src/components/admin/AdminTable';
import { AdminTile } from 'src/components/admin/AdminTile';
+import { OneVillageTable } from 'src/components/admin/OneVillageTable';
import { UserContext } from 'src/contexts/userContext';
import { useUserRequests } from 'src/services/useUsers';
import { useVillages } from 'src/services/useVillages';
@@ -222,7 +222,8 @@ const Users = () => {
- ({ ...data, position: null }))} // remove position attribute from data
columns={[
diff --git a/src/pages/admin/newportal/manage/villages/index.tsx b/src/pages/admin/newportal/manage/villages/index.tsx
index 2e3fdae6f..07dedea25 100644
--- a/src/pages/admin/newportal/manage/villages/index.tsx
+++ b/src/pages/admin/newportal/manage/villages/index.tsx
@@ -13,8 +13,8 @@ import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import { Modal } from 'src/components/Modal';
-import { AdminTable } from 'src/components/admin/AdminTable';
import { AdminTile } from 'src/components/admin/AdminTile';
+import { OneVillageTable } from 'src/components/admin/OneVillageTable';
import { useVillages, useVillageRequests } from 'src/services/useVillages';
import { defaultContainedButtonStyle } from 'src/styles/variables.const';
import BackArrow from 'src/svg/back-arrow.svg';
@@ -138,7 +138,8 @@ const Villages = () => {
/>
-
{"Vous n'avez pas encore de villages ! "}
diff --git a/src/pages/admin/users/index.tsx b/src/pages/admin/users/index.tsx
index ad8b73163..7f5ade037 100644
--- a/src/pages/admin/users/index.tsx
+++ b/src/pages/admin/users/index.tsx
@@ -17,8 +17,8 @@ import Tooltip from '@mui/material/Tooltip';
import { useUsers } from 'src/api/user/user.list';
import { Modal } from 'src/components/Modal';
-import { AdminTable } from 'src/components/admin/AdminTable';
import { AdminTile } from 'src/components/admin/AdminTile';
+import { OneVillageTable } from 'src/components/admin/OneVillageTable';
import { UserContext } from 'src/contexts/userContext';
import { useUserRequests } from 'src/services/useUsers';
import { useVillages } from 'src/services/useVillages';
@@ -220,7 +220,8 @@ const Users = () => {
Exporter en CSV
- ({ ...data, position: null }))} // remove position attribute from data
columns={[
diff --git a/src/pages/admin/villages/index.tsx b/src/pages/admin/villages/index.tsx
index 62edbcee1..6b6ea9914 100644
--- a/src/pages/admin/villages/index.tsx
+++ b/src/pages/admin/villages/index.tsx
@@ -14,8 +14,8 @@ import MaterialLink from '@mui/material/Link';
import Tooltip from '@mui/material/Tooltip';
import { Modal } from 'src/components/Modal';
-import { AdminTable } from 'src/components/admin/AdminTable';
import { AdminTile } from 'src/components/admin/AdminTile';
+import { OneVillageTable } from 'src/components/admin/OneVillageTable';
import { useVillages, useVillageRequests } from 'src/services/useVillages';
import { defaultContainedButtonStyle } from 'src/styles/variables.const';
import { countryToFlag } from 'src/utils';
@@ -128,7 +128,8 @@ const Villages = () => {
style={{ marginRight: '1rem' }}
/>
-
{"Vous n'avez pas encore de villages ! "}
diff --git a/types/statistics.type.ts b/types/statistics.type.ts
index 1ecf3bc0c..c5b36966a 100644
--- a/types/statistics.type.ts
+++ b/types/statistics.type.ts
@@ -38,7 +38,6 @@ export interface FamiliesWithoutAccount {
student_firstname: string;
student_lastname: string;
village_name: string;
- user_firstname: string;
- user_lastname: string;
- user_email: string;
+ classroom_name: string;
+ classroom_country: string;
}