import React, { ErrorInfo, ReactElement, useEffect } from 'react'; import clsx from 'clsx'; import Drawer from '@mui/material/Drawer'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import List from '@mui/material/List'; import IconButton from '@mui/material/IconButton'; import { useStyles } from './style'; import { MapsList } from './maps-list'; import { createIntl, createIntlCache, FormattedMessage, IntlProvider } from 'react-intl'; import { useQuery, useMutation, useQueryClient } from 'react-query'; import { activeInstance } from '../../redux/clientSlice'; import { useSelector } from 'react-redux'; import Client, { Label } from '../../classes/client'; import ActionDispatcher from './action-dispatcher'; import { ActionType } from './action-chooser'; import AccountMenu from './account-menu'; import HelpMenu from './help-menu'; import LanguageMenu from './language-menu'; import AppI18n, { Locales } from '../../classes/app-i18n'; import ListItemIcon from '@mui/material/ListItemIcon'; import AddCircleTwoTone from '@mui/icons-material/AddCircleTwoTone'; import CloudUploadTwoTone from '@mui/icons-material/CloudUploadTwoTone'; import DeleteOutlineTwoTone from '@mui/icons-material/DeleteOutlineTwoTone'; import LabelTwoTone from '@mui/icons-material/LabelTwoTone'; import PersonOutlineTwoTone from '@mui/icons-material/PersonOutlineTwoTone'; import PublicTwoTone from '@mui/icons-material/PublicTwoTone'; import ScatterPlotTwoTone from '@mui/icons-material/ScatterPlotTwoTone'; import ShareTwoTone from '@mui/icons-material/ShareTwoTone'; import StarTwoTone from '@mui/icons-material/StarTwoTone'; import Tooltip from '@mui/material/Tooltip'; import Button from '@mui/material/Button'; import Link from '@mui/material/Link'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; import logoIcon from './logo-small.svg'; import poweredByIcon from './pwrdby-white.svg'; import LabelDeleteConfirm from './maps-list/label-delete-confirm'; import ReactGA from 'react-ga4'; import { withStyles } from '@mui/styles'; export type Filter = GenericFilter | LabelFilter; export interface GenericFilter { type: 'public' | 'all' | 'starred' | 'shared' | 'label' | 'owned'; } export interface LabelFilter { type: 'label'; label: Label; } interface ToolbarButtonInfo { filter: GenericFilter | LabelFilter; label: string; icon: React.ReactElement; } const MapsPage = (): ReactElement => { const classes = useStyles(); const [filter, setFilter] = React.useState({ type: 'all' }); const client: Client = useSelector(activeInstance); const queryClient = useQueryClient(); const [activeDialog, setActiveDialog] = React.useState(undefined); const [labelToDelete, setLabelToDelete] = React.useState(null); // Reload based on user preference ... const userLocale = AppI18n.getUserLocale(); const cache = createIntlCache(); const intl = createIntl({ defaultLocale: userLocale.code, locale: Locales.EN.code, messages: userLocale.message }, cache) useEffect(() => { document.title = intl.formatMessage({ id: 'maps.page-title', defaultMessage: 'My Maps | WiseMapping', }); ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'Maps List' }); }, []); const mutation = useMutation((id: number) => client.deleteLabel(id), { onSuccess: () => { queryClient.invalidateQueries('labels'); queryClient.invalidateQueries('maps'); }, onError: (error) => { console.error(`Unexpected error ${error}`); }, }); const handleMenuClick = (filter: Filter) => { queryClient.invalidateQueries('maps'); setFilter(filter); }; const handleLabelDelete = (id: number) => { mutation.mutate(id); }; const { data } = useQuery('labels', () => { return client.fetchLabels(); }); const labels: Label[] = data ? data : []; const filterButtons: ToolbarButtonInfo[] = [ { filter: { type: 'all' }, label: intl.formatMessage({ id: 'maps.nav-all', defaultMessage: 'All' }), icon: , }, { filter: { type: 'owned' }, label: intl.formatMessage({ id: 'maps.nav-onwned', defaultMessage: 'Owned' }), icon: , }, { filter: { type: 'starred' }, label: intl.formatMessage({ id: 'maps.nav-starred', defaultMessage: 'Starred' }), icon: , }, { filter: { type: 'shared' }, label: intl.formatMessage({ id: 'maps.nav-shared', defaultMessage: 'Shared with me' }), icon: , }, { filter: { type: 'public' }, label: intl.formatMessage({ id: 'maps.nav-public', defaultMessage: 'Public' }), icon: , }, ]; labels.forEach((l) => filterButtons.push({ filter: { type: 'label', label: l }, label: l.title, icon: , }) ); return (
setActiveDialog(undefined)} mapsId={[]} fromEditor />
logo
{filterButtons.map((buttonInfo) => { return ( ); })}
Powered By WiseMapping
{labelToDelete && setLabelToDelete(null)} onConfirm={() => { handleLabelDelete(labelToDelete); setLabelToDelete(null); }} label={labels.find(l => l.id === labelToDelete)} />}
); }; interface ListItemProps { icon: React.ReactElement; label: string; filter: Filter; active?: Filter; onClick: (filter: Filter) => void; onDelete?: (id: number) => void; } // https://stackoverflow.com/questions/61486061/how-to-set-selected-and-hover-color-of-listitem-in-mui const CustomListItem = withStyles({ root: { "&$selected": { backgroundColor: "rgb(210, 140, 5)", color: "white", "& .MuiListItemIcon-root": { color: "white" } }, "&$selected:hover": { backgroundColor: "rgb(210, 140, 5)", color: "white", "& .MuiListItemIcon-root": { color: "white" } }, }, selected: {} })(ListItemButton); const StyleListItem = (props: ListItemProps) => { const icon = props.icon; const label = props.label; const filter = props.filter; const activeFilter = props.active; const onClick = props.onClick; const onDeleteLabel = props.onDelete; const isSelected = activeFilter && activeFilter.type == filter.type && (activeFilter.type != 'label' || (activeFilter as LabelFilter).label == (filter as LabelFilter).label); const handleOnClick = (event: React.MouseEvent, filter: Filter) => { event.stopPropagation(); onClick(filter); }; const handleOnDelete = ( event: React.MouseEvent, filter: Filter ) => { event.stopPropagation(); if (!onDeleteLabel) { throw 'Illegal state exeption'; } onDeleteLabel((filter as LabelFilter).label.id); }; return ( handleOnClick(e, filter)}> {icon} {filter.type == 'label' && ( handleOnDelete(e, filter)} size="large"> )} ); }; export default MapsPage;