Skip to content

Commit

Permalink
Refactor tabPanel component, and constants for table headers
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjyhy committed Oct 21, 2024
1 parent 65f4dfb commit 4fc28c2
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 131 deletions.
84 changes: 11 additions & 73 deletions src/components/admin/dashboard-statistics/GlobalStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,21 @@ import React from 'react';

import AccessTimeIcon from '@mui/icons-material/AccessTime';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { Box, Grid, Tab, Tabs, Typography } from '@mui/material';
import { Box, Grid, Tab, Tabs } from '@mui/material';

import { OneVillageTable } from '../OneVillageTable';
import TabPanel from './TabPanel';
import TeamComments from './TeamComments';
import AverageStatsCard from './cards/AverageStatsCard/AverageStatsCard';
import ClassesExchangesCard from './cards/ClassesExchangesCard/ClassesExchangesCard';
import StatsCard from './cards/StatsCard/StatsCard';
import DashboardWorldMap from './map/DashboardWorldMap/DashboardWorldMap';
import styles from './styles/charts.module.css';
import { createFamiliesWithoutAccountRows, createFloatingAccountsRows } from './utils/tableCreator';
import { FamiliesWithoutAccountHeaders, FloatingAccountsHeaders } from './utils/tableHeaders';
import { useGetOneVillageStats, useGetSessionsStats } from 'src/api/statistics/statistics.get';
import { formatDate } from 'src/utils';
import type { FamiliesWithoutAccount, FloatingAccount, OneVillageTableRow } from 'types/statistics.type';
import type { OneVillageTableRow } from 'types/statistics.type';

function createFamiliesWithoutAccountRows(data: Array<FamiliesWithoutAccount>): Array<OneVillageTableRow> {
return data.map((row) => {
return {
id: row.student_id,
student: `${row.student_firstname} ${row.student_lastname}`,
vm: row.village_name,
classroom: row.classroom_name,
country: row.classroom_country,
creationDate: row.student_creation_date ? formatDate(row.student_creation_date) : 'Donnée non disponible',
};
});
}
function createFloatingAccountsRows(data: Array<FloatingAccount>): Array<OneVillageTableRow> {
return data.map((row) => {
return {
id: row.id,
family: `${row.firstname} ${row.lastname}`,
language: row.language,
email: row.email,
creationDate: row.createdAt ? formatDate(row.createdAt) : 'Donnée non disponible',
};
});
}
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 },
];
const FloatingAccountsHeaders = [
{ key: 'family', label: 'Nom Prénom Famille', sortable: true },
{ key: 'language', label: 'Langue', sortable: true },
{ key: 'email', label: 'Mail', sortable: true },
{ key: 'creationDate', label: 'Date de création compte', sortable: true },
];
const GlobalStats = () => {
const [value, setValue] = React.useState(0);
const sessionsStats = useGetSessionsStats(null);
Expand All @@ -70,48 +36,20 @@ const GlobalStats = () => {

if (sessionsStats.isError) return <p>Error!</p>;
if (sessionsStats.isLoading || sessionsStats.isIdle) return <p>Loading...</p>;
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
function CustomTabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;

return (
<div role="tabpanel" hidden={value !== index} id={`simple-tabpanel-${index}`} aria-labelledby={`simple-tab-${index}`} {...other}>
{value === index && (
<Box sx={{ p: 0 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}

function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}

const handleTabChange = (_event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};

// eslint-disable-next-line no-console
console.log('Sessions stats', sessionsStats.data);

return (
<>
<TeamComments />
<DashboardWorldMap />
<Tabs value={value} onChange={handleTabChange} aria-label="basic tabs example" sx={{ py: 3 }}>
<Tab label="En classe" {...a11yProps(0)} />
<Tab label="En famille" {...a11yProps(1)} />
<Tab label="En classe" />
<Tab label="En famille" />
</Tabs>
<CustomTabPanel value={value} index={0}>
<TabPanel value={value} index={0}>
<Grid container spacing={4} direction={{ xs: 'column', md: 'row' }}>
<Grid item xs={12} lg={4}>
<StatsCard data={10}>
Expand Down Expand Up @@ -187,8 +125,8 @@ const GlobalStats = () => {
/>
</div> */}
</Grid>
</CustomTabPanel>
<CustomTabPanel value={value} index={1}>
</TabPanel>
<TabPanel value={value} index={1}>
<>
<OneVillageTable
admin={false}
Expand Down Expand Up @@ -220,7 +158,7 @@ const GlobalStats = () => {
<StatsCard data={oneVillageStats.data?.connectedFamiliesCount}>Nombre de familles connectées</StatsCard>
</Box>
</>
</CustomTabPanel>
</TabPanel>
</>
);
};
Expand Down
23 changes: 23 additions & 0 deletions src/components/admin/dashboard-statistics/TabPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';

import { Box, Typography } from '@mui/material';

interface TabPanelProps {
children?: React.ReactNode;
value: number;
index: number;
}

const TabPanel = ({ children, value, index, ...other }: TabPanelProps) => {
return (
<div role="tabpanel" hidden={value !== index} id={`tabpanel-${index}`} aria-labelledby={`tab-${index}`} {...other}>
{value === index && (
<Box sx={{ p: 0 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
};

export default TabPanel;
72 changes: 14 additions & 58 deletions src/components/admin/dashboard-statistics/VillageStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,27 @@ import React, { useState } from 'react';
import Box from '@mui/material/Box';
import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
import Typography from '@mui/material/Typography';

import { OneVillageTable } from '../OneVillageTable';
import TabPanel from './TabPanel';
import StatsCard from './cards/StatsCard/StatsCard';
import CountriesDropdown from './filters/CountriesDropdown';
import VillageDropdown from './filters/VillageDropdown';
import { PelicoCard } from './pelico-card';
import styles from './styles/charts.module.css';
import { createFamiliesWithoutAccountRows } from './utils/tableCreator';
import { FamiliesWithoutAccountHeaders } from './utils/tableHeaders';
import { useGetVillagesStats } from 'src/api/statistics/statistics.get';
import { useCountries } from 'src/services/useCountries';
import { useVillages } from 'src/services/useVillages';
import { formatDate } from 'src/utils';
import type { FamiliesWithoutAccount, OneVillageTableRow } from 'types/statistics.type';
import type { OneVillageTableRow } from 'types/statistics.type';
import type { VillageFilter } from 'types/village.type';

const VillageStats = () => {
const [selectedCountry, setSelectedCountry] = useState<string>('');
const [selectedVillage, setSelectedVillage] = useState<string>('');
const [options, setOptions] = useState<VillageFilter>({ countryIsoCode: '' });

const pelicoMessage = 'Merci de sélectionner un village-monde pour analyser ses statistiques ';
const noDataFoundMessage = 'Pas de données pour le Village-Monde sélectionné';
const [value, setValue] = React.useState(0);

const { countries } = useCountries();

Expand All @@ -39,10 +38,9 @@ const VillageStats = () => {
const [familiesWithoutAccountRows, setFamiliesWithoutAccountRows] = React.useState<Array<OneVillageTableRow>>([]);
React.useEffect(() => {
if (villagesStats.data?.familiesWithoutAccount) {
setFamiliesWithoutAccountRows([]);
setFamiliesWithoutAccountRows(createFamiliesWithoutAccountRows(villagesStats.data?.familiesWithoutAccount));
}
}, [villagesStats.data?.familiesWithoutAccount, villagesStats.data?.floatingAccounts]);
}, [villagesStats.data?.familiesWithoutAccount]);

const handleCountryChange = (country: string) => {
setSelectedCountry(country);
Expand All @@ -53,54 +51,12 @@ const VillageStats = () => {
setSelectedVillage(village);
};

interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}

function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
const [value, setValue] = React.useState(0);
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;

return (
<div role="tabpanel" hidden={value !== index} id={`simple-tabpanel-${index}`} aria-labelledby={`simple-tab-${index}`} {...other}>
{value === index && (
<Box sx={{ p: 0 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
function createFamiliesWithoutAccountRows(data: Array<FamiliesWithoutAccount>): Array<OneVillageTableRow> {
return data.map((row) => {
return {
id: row.student_id,
student: `${row.student_firstname} ${row.student_lastname}`,
vm: row.village_name,
classroom: row.classroom_name,
country: row.classroom_country,
creationDate: row.student_creation_date ? formatDate(row.student_creation_date) : 'Donnée non disponible',
};
});
}
const pelicoMessage = 'Merci de sélectionner un village-monde pour analyser ses statistiques ';
const noDataFoundMessage = 'Pas de données pour le Village-Monde sélectionné';
return (
<>
<Box
Expand All @@ -122,13 +78,13 @@ const VillageStats = () => {
</div>
</Box>
<Tabs value={value} onChange={handleTabChange} aria-label="basic tabs example" sx={{ py: 3 }}>
<Tab label="En classe" {...a11yProps(0)} />
<Tab label="En famille" {...a11yProps(1)} />
<Tab label="En classe" />
<Tab label="En famille" />
</Tabs>
<CustomTabPanel value={value} index={0}>
<TabPanel value={value} index={0}>
<p>Statistiques - En classe</p>
</CustomTabPanel>
<CustomTabPanel value={value} index={1}>
</TabPanel>
<TabPanel value={value} index={1}>
{!selectedVillage ? (
<PelicoCard message={pelicoMessage} />
) : (
Expand Down Expand Up @@ -157,7 +113,7 @@ const VillageStats = () => {
</Box>
</>
)}
</CustomTabPanel>
</TabPanel>
</>
);
};
Expand Down
23 changes: 23 additions & 0 deletions src/components/admin/dashboard-statistics/utils/tableCreator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { formatDate } from 'src/utils';
import type { FamiliesWithoutAccount, FloatingAccount, OneVillageTableRow } from 'types/statistics.type';

export function createFamiliesWithoutAccountRows(data: FamiliesWithoutAccount[]): OneVillageTableRow[] {
return data.map((row) => ({
id: row.student_id,
student: `${row.student_firstname} ${row.student_lastname}`,
vm: row.village_name,
classroom: row.classroom_name,
country: row.classroom_country,
creationDate: row.student_creation_date ? formatDate(row.student_creation_date) : 'Donnée non disponible',
}));
}

export function createFloatingAccountsRows(data: FloatingAccount[]): OneVillageTableRow[] {
return data.map((row) => ({
id: row.id,
family: `${row.firstname} ${row.lastname}`,
language: row.language,
email: row.email,
creationDate: row.createdAt ? formatDate(row.createdAt) : 'Donnée non disponible',
}));
}
14 changes: 14 additions & 0 deletions src/components/admin/dashboard-statistics/utils/tableHeaders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export 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 },
];

export const FloatingAccountsHeaders = [
{ key: 'family', label: 'Nom Prénom Famille', sortable: true },
{ key: 'language', label: 'Langue', sortable: true },
{ key: 'email', label: 'Mail', sortable: true },
{ key: 'creationDate', label: 'Date de création compte', sortable: true },
];

0 comments on commit 4fc28c2

Please sign in to comment.