diff --git a/frontend/package.json b/frontend/package.json index 9bb63faffbb6698dd2f749aa790493a80d4ff7fe..072ef7cfee39cd2d6d05330c7a6f83f995b2b3bd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "dependencies": { "@emotion/react": "^11.8.2", "@emotion/styled": "^11.8.1", + "@faker-js/faker": "^6.0.0", "@mui/icons-material": "^5.5.1", "@mui/material": "^5.5.2", "@testing-library/jest-dom": "^5.14.1", diff --git a/frontend/src/features/Catalog/Catalog.tsx b/frontend/src/features/Catalog/Catalog.tsx index 101b1ba17cd2b11d0784a84ae75be2034dc6449b..9ce34bf586db6a8ed9f8ddd91d665104a58d6302 100644 --- a/frontend/src/features/Catalog/Catalog.tsx +++ b/frontend/src/features/Catalog/Catalog.tsx @@ -1,34 +1,46 @@ import { Box, Button, + Collapse, Container, Grid, Paper, Stack, TextField, } from '@mui/material' -import { useEffect, useState } from 'react' import { CatalogDto } from '../../swagger/data-contracts' import CatalogTable from './CatalogTable' +import { faker } from '@faker-js/faker' +import { useState } from 'react' const Catalog = () => { + const [filterOpen, setFilterOpen] = useState(false) + const toggleFilter = () => { + setFilterOpen(!filterOpen) + } + + // Creates a generic row for the table const createRow = (): CatalogDto => ({ - name: 'Cell', - certainty: 100, - longitude: 1, - latitude: 2, - writtenForms: ['Written Form'], - bibliography: ['Bibliography'], - countries: ['Country'], - alternativeNames: ['Alternative Name'], + name: faker.commerce.product(), + certainty: faker.random.number({ min: 1, max: 1000 }), + longitude: faker.address.latitude() as unknown as number, + latitude: faker.address.longitude() as unknown as number, + writtenForms: [faker.name.firstName()], + bibliography: [faker.name.lastName()], + types: [faker.commerce.color()], + countries: [faker.address.country()], + alternativeNames: [faker.commerce.productName()], }) - const data: CatalogDto[] = Array(25).fill(createRow()) + const data: CatalogDto[] = Array(33) + .fill({}) + .map(() => createRow()) return ( <> <Paper sx={{ py: 2 }}> <Container sx={{ mt: 4 }}> - <Button variant="contained">Filter</Button> + <Button variant="contained" onClick={toggleFilter}>Filter</Button> + <Collapse in={filterOpen} timeout="auto" unmountOnExit> <Grid container spacing={1} alignItems="stretch"> <Grid item xs={6}> <Stack @@ -67,6 +79,7 @@ const Catalog = () => { </Stack> </Grid> </Grid> + </Collapse> <Box sx={{ mt: 4 }}> <CatalogTable data={data} /> diff --git a/frontend/src/features/Catalog/CatalogService.ts b/frontend/src/features/Catalog/CatalogService.ts deleted file mode 100644 index 87ef5f38ebec4dd74e4b59d1d8876b960361e437..0000000000000000000000000000000000000000 --- a/frontend/src/features/Catalog/CatalogService.ts +++ /dev/null @@ -1,15 +0,0 @@ -import axios from "../../api/axiosInstance" -import { CatalogDto } from "../../swagger/data-contracts" - -export const getCatalogItems = async (componentMounted: boolean, setCatalog: (catalogItems: CatalogDto[]) => void, ) => { - try { - const { data } = await axios.get('/catalog') - } - catch (err: any) { - - } -} - -export const getCatalogItem = (id: string) => { - -} diff --git a/frontend/src/features/Catalog/CatalogTable.tsx b/frontend/src/features/Catalog/CatalogTable.tsx index b39a3381120715d3cc25b167bdb9b5ba2aa67e54..d929b9b82d315f758645cb214f5b475a5fd7807f 100644 --- a/frontend/src/features/Catalog/CatalogTable.tsx +++ b/frontend/src/features/Catalog/CatalogTable.tsx @@ -2,15 +2,20 @@ import { useTheme } from '@mui/material/styles' import { Box, Paper, + Stack, Table, TableBody, TableCell, TableContainer, TableFooter, + TableHead, TablePagination, TableRow, + Typography, } from '@mui/material' -import TablePaginationActions, { TablePaginationActionsProps } from '@mui/material/TablePagination/TablePaginationActions' +import TablePaginationActions, { + TablePaginationActionsProps, +} from '@mui/material/TablePagination/TablePaginationActions' import { FunctionComponent, useState } from 'react' import IconButton from '@mui/material/IconButton' import FirstPageIcon from '@mui/icons-material/FirstPage' @@ -19,6 +24,7 @@ import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight' import LastPageIcon from '@mui/icons-material/LastPage' import { CatalogDto } from '../../swagger/data-contracts' +// Currently adapted from https://mui.com/components/tables/ const CatalogTableActions: FunctionComponent<TablePaginationActionsProps> = ({ count, @@ -122,7 +128,6 @@ const rows = [ createData('Oreo', 437, 18.0), ].sort((a, b) => (a.calories < b.calories ? -1 : 1)) - export interface CatalogTableProps { data: CatalogDto[] } @@ -149,9 +154,34 @@ const CatalogTable: FunctionComponent<CatalogTableProps> = ({ data }) => { setPage(0) } + // Table columns + const columns = [ + 'Name', + 'Alternative names', + 'Written form', + 'Type', + 'State or territory', + 'Coordinates', + 'Certainty', + ] + return ( - <TableContainer component={Paper}> - <Table sx={{ minWidth: 500 }} aria-label="custom pagination table"> + // TODO remove mb + <TableContainer component={Paper} sx={{mb: 16 }} > + <Table + sx={{ minWidth: 500 }} + aria-label="sticky table" + stickyHeader + > + <TableHead> + <TableRow> + {columns.map((col, idx) => ( + <TableCell key={idx} align="left"> + <Typography fontWeight="bold">{col}</Typography> + </TableCell> + ))} + </TableRow> + </TableHead> <TableBody> {(rowsPerPage > 0 ? data.slice( @@ -164,49 +194,51 @@ const CatalogTable: FunctionComponent<CatalogTableProps> = ({ data }) => { <TableCell component="th" scope="row"> {row.name} </TableCell> - <TableCell style={{ width: 160 }} align="right"> - {row?.alternativeNames ? row.alternativeNames.join(', ') : ''} + <TableCell> + {row?.alternativeNames + ? row.alternativeNames.join(', ') + : 'N/A'} + </TableCell> + <TableCell> + {row?.writtenForms + ? row.writtenForms.join(', ') + : 'N/A'} </TableCell> - <TableCell style={{ width: 160 }} align="right"> - {row?.writtenForms ? row.writtenForms.join(', ') : ''} + <TableCell> + {row?.types ? row.types.join(', ') : 'N/A'} </TableCell> - <TableCell style={{ width: 160 }} align="right"> - {row?.writtenForms ? row.writtenForms.join(', ') : ''} + <TableCell> + {/* Here should be State or Territory but not currently present in DTO */} + {row?.countries + ? row.countries.join(', ') + : 'N/A'} + </TableCell> + <TableCell> + {row?.latitude && row?.longitude + ? `${row.latitude}, ${row.longitude}` + : 'N/A'} + </TableCell> + <TableCell> + {row?.certainty ? row.certainty : 'N/A'} </TableCell> </TableRow> ))} - {emptyRows > 0 && ( + {/* {emptyRows > 0 && ( <TableRow style={{ height: 53 * emptyRows }}> <TableCell colSpan={6} /> </TableRow> - )} + )} */} </TableBody> - <TableFooter> - <TableRow> - <TablePagination - rowsPerPageOptions={[ - 5, - 10, - 25, - { label: 'All', value: -1 }, - ]} - colSpan={3} - count={rows.length} + </Table> + <TablePagination + rowsPerPageOptions={[5, 10, 25]} + component="div" + count={data.length} rowsPerPage={rowsPerPage} page={page} - SelectProps={{ - inputProps: { - 'aria-label': 'rows per page', - }, - native: true, - }} onPageChange={handleChangePage} onRowsPerPageChange={handleChangeRowsPerPage} - ActionsComponent={CatalogTableActions} /> - </TableRow> - </TableFooter> - </Table> </TableContainer> ) } diff --git a/frontend/src/features/Theme/themeReducer.ts b/frontend/src/features/Theme/themeReducer.ts index 8586ddd844efb3d118e64ea40ed69b2aac06ee51..504142aab89c012a89d1843c0066ef3a9f50b9a1 100644 --- a/frontend/src/features/Theme/themeReducer.ts +++ b/frontend/src/features/Theme/themeReducer.ts @@ -12,6 +12,20 @@ const statePersistName = 'theme' const initialTheme = createTheme({ palette: { mode: 'light' + }, + typography: { + fontFamily: [ + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(','), } }) const initialState: ThemeState = {