diff options
Diffstat (limited to 'src/settings/MaintenancesPage.jsx')
-rw-r--r-- | src/settings/MaintenancesPage.jsx | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/settings/MaintenancesPage.jsx b/src/settings/MaintenancesPage.jsx new file mode 100644 index 00000000..9241eb3e --- /dev/null +++ b/src/settings/MaintenancesPage.jsx @@ -0,0 +1,100 @@ +import React, { useState } from 'react'; +import dayjs from 'dayjs'; +import { + Table, TableRow, TableCell, TableHead, TableBody, +} from '@mui/material'; +import { useEffectAsync } from '../reactHelper'; +import usePositionAttributes from '../common/attributes/usePositionAttributes'; +import { formatDistance, formatSpeed } from '../common/util/formatter'; +import { useAttributePreference } from '../common/util/preferences'; +import { useTranslation } from '../common/components/LocalizationProvider'; +import PageLayout from '../common/components/PageLayout'; +import SettingsMenu from './components/SettingsMenu'; +import CollectionFab from './components/CollectionFab'; +import CollectionActions from './components/CollectionActions'; +import TableShimmer from '../common/components/TableShimmer'; +import SearchHeader, { filterByKeyword } from './components/SearchHeader'; +import useSettingsStyles from './common/useSettingsStyles'; + +const MaintenacesPage = () => { + const classes = useSettingsStyles(); + const t = useTranslation(); + + const positionAttributes = usePositionAttributes(t); + + const [timestamp, setTimestamp] = useState(Date.now()); + const [items, setItems] = useState([]); + const [searchKeyword, setSearchKeyword] = useState(''); + const [loading, setLoading] = useState(false); + const speedUnit = useAttributePreference('speedUnit'); + const distanceUnit = useAttributePreference('distanceUnit'); + + useEffectAsync(async () => { + setLoading(true); + try { + const response = await fetch('/api/maintenance'); + if (response.ok) { + setItems(await response.json()); + } else { + throw Error(await response.text()); + } + } finally { + setLoading(false); + } + }, [timestamp]); + + const convertAttribute = (key, start, value) => { + const attribute = positionAttributes[key]; + if (key.endsWith('Time')) { + if (start) { + return dayjs(value).locale('en').format('YYYY-MM-DD'); + } + return `${value / 86400000} ${t('sharedDays')}`; + } + if (attribute && attribute.dataType) { + switch (attribute.dataType) { + case 'speed': + return formatSpeed(value, speedUnit, t); + case 'distance': + return formatDistance(value, distanceUnit, t); + default: + return value; + } + } + + return value; + }; + + return ( + <PageLayout menu={<SettingsMenu />} breadcrumbs={['settingsTitle', 'sharedMaintenance']}> + <SearchHeader keyword={searchKeyword} setKeyword={setSearchKeyword} /> + <Table className={classes.table}> + <TableHead> + <TableRow> + <TableCell>{t('sharedName')}</TableCell> + <TableCell>{t('sharedType')}</TableCell> + <TableCell>{t('maintenanceStart')}</TableCell> + <TableCell>{t('maintenancePeriod')}</TableCell> + <TableCell className={classes.columnAction} /> + </TableRow> + </TableHead> + <TableBody> + {!loading ? items.filter(filterByKeyword(searchKeyword)).map((item) => ( + <TableRow key={item.id}> + <TableCell>{item.name}</TableCell> + <TableCell>{item.type}</TableCell> + <TableCell>{convertAttribute(item.type, true, item.start)}</TableCell> + <TableCell>{convertAttribute(item.type, false, item.period)}</TableCell> + <TableCell className={classes.columnAction} padding="none"> + <CollectionActions itemId={item.id} editPath="/settings/maintenance" endpoint="maintenance" setTimestamp={setTimestamp} /> + </TableCell> + </TableRow> + )) : (<TableShimmer columns={5} endAction />)} + </TableBody> + </Table> + <CollectionFab editPath="/settings/maintenance" /> + </PageLayout> + ); +}; + +export default MaintenacesPage; |