diff --git a/packages/webapp/src/app.tsx b/packages/webapp/src/app.tsx index c33e216d..cbd5de82 100644 --- a/packages/webapp/src/app.tsx +++ b/packages/webapp/src/app.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { IntlProvider } from 'react-intl'; import { Route, Switch, Redirect, BrowserRouter as Router } from 'react-router-dom'; -import { GlobalStyle } from './theme/global-style'; +import { GlobalStyle } from './theme'; import RegistrationSuccessPage from './components/registration-success-page'; import ForgotPasswordSuccessPage from './components/forgot-password-success-page'; import RegistationPage from './components/registration-page'; @@ -13,6 +13,9 @@ import store from "./store"; import { ForgotPasswordPage } from './components/forgot-password-page'; import { Provider } from 'react-redux'; import { QueryClient, QueryClientProvider } from 'react-query'; +import { CssBaseline, ThemeProvider } from '@material-ui/core'; +import { theme } from './theme' + function loadLocaleData(language: string) { switch (language) { @@ -43,28 +46,31 @@ const App = () => { return messages ? ( + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/webapp/src/components/forgot-password-page/index.tsx b/packages/webapp/src/components/forgot-password-page/index.tsx index 92ecd83d..ff258a89 100644 --- a/packages/webapp/src/components/forgot-password-page/index.tsx +++ b/packages/webapp/src/components/forgot-password-page/index.tsx @@ -5,12 +5,14 @@ import { Service, ErrorInfo } from '../../services/Service' import Header from '../layout/header' import Footer from '../layout/footer' -import { PageContent } from '../../theme/global-style' +import { PageContent } from '../../theme' import { useSelector } from 'react-redux' import { useMutation } from 'react-query' import { activeInstance } from '../../reducers/serviceSlice' import Input from '../form/input' import GlobalError from '../form/global-error' +import SubmitButton from '../form/submit-button' +import { Typography } from '@material-ui/core' const ForgotPassword = () => { const [email, setEmail] = useState(''); @@ -36,8 +38,13 @@ const ForgotPassword = () => { return ( -

-

+ + + + + + + @@ -45,7 +52,7 @@ const ForgotPassword = () => { setEmail(e.target.value)} /> - +
); diff --git a/packages/webapp/src/components/forgot-password-success-page/index.tsx b/packages/webapp/src/components/forgot-password-success-page/index.tsx index af035446..ab1449c4 100644 --- a/packages/webapp/src/components/forgot-password-success-page/index.tsx +++ b/packages/webapp/src/components/forgot-password-success-page/index.tsx @@ -1,10 +1,11 @@ import React, { useEffect } from 'react' import { FormattedMessage } from 'react-intl' - -import { PageContent } from '../../theme/global-style'; - +import { PageContent } from '../../theme'; import Header, { SignInButton } from '../layout/header' import Footer from '../layout/footer' +import { Button, Typography } from '@material-ui/core'; +import { Link as RouterLink} from 'react-router-dom' + const ForgotPasswordSuccessPage = () => { useEffect(() => { @@ -15,14 +16,18 @@ const ForgotPasswordSuccessPage = () => {
-

+ -

-

- -

+ + + + + + + -
diff --git a/packages/webapp/src/components/form/input/index.tsx b/packages/webapp/src/components/form/input/index.tsx index 23015de5..2434768f 100644 --- a/packages/webapp/src/components/form/input/index.tsx +++ b/packages/webapp/src/components/form/input/index.tsx @@ -1,8 +1,7 @@ -import { FormControl, TextField } from "@material-ui/core"; +import { TextField } from "@material-ui/core"; import React, { ChangeEvent } from "react"; import { MessageDescriptor, useIntl } from "react-intl"; import { ErrorInfo } from "../../../services/Service"; -import { StyledTextField } from "./styles"; type InputProps = { name: string; @@ -28,7 +27,7 @@ const Input = (props: InputProps) => { const fullWidth = props.fullWidth != undefined ? props.required : true; return ( - diff --git a/packages/webapp/src/components/form/input/styles.ts b/packages/webapp/src/components/form/input/styles.ts deleted file mode 100644 index 207799f4..00000000 --- a/packages/webapp/src/components/form/input/styles.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { TextField, withStyles } from "@material-ui/core"; - -export const StyledTextField = withStyles({ - root: - { - '& label.Mui-focused': { - color: '#f9a826', - }, - '& .MuiOutlinedInput-root': { - height: '53px', - borderRadius: '9px', - fontSize: '16px', - '& fieldset': { - border: 'solid 1px #ffcb66', - }, - '&:hover fieldset': { - borderColor: '#f9a826', - }, - '&.Mui-focused fieldset': { - borderColor: '#f9a826' - }, - }, - }, -})(TextField); diff --git a/packages/webapp/src/components/form/submit-button/index.tsx b/packages/webapp/src/components/form/submit-button/index.tsx index e0e129b9..54e43c83 100644 --- a/packages/webapp/src/components/form/submit-button/index.tsx +++ b/packages/webapp/src/components/form/submit-button/index.tsx @@ -1,3 +1,4 @@ +import { Button } from '@material-ui/core'; import React, { useState, useEffect } from 'react' import { useIntl } from 'react-intl' @@ -15,7 +16,11 @@ const SubmitButton = (props: SubmitButton) => { } const [value, setValue] = useState(valueTxt); return ( - + ); } diff --git a/packages/webapp/src/components/layout/header/index.tsx b/packages/webapp/src/components/layout/header/index.tsx index 58783a8c..e468d77c 100644 --- a/packages/webapp/src/components/layout/header/index.tsx +++ b/packages/webapp/src/components/layout/header/index.tsx @@ -1,8 +1,9 @@ -import { StyledNav, StyledDiv,Logo } from './styled'; +import { StyledNav, StyledDiv, Logo } from './styled'; import React from 'react' import { FormattedMessage } from 'react-intl' import { Link } from 'react-router-dom' +import { Button } from '@material-ui/core'; const logo = require('../../../images/header-logo.png') @@ -49,23 +50,20 @@ class Header extends React.Component { } interface ButtonProps { - style?: 'style1' | 'style2' | 'style3'; className?: string; } const SignInButton = (props: ButtonProps) => { - const style = props.style ? props.style : 'style1'; return ( - - + + ); } const SignUpButton = (props: ButtonProps) => { - const style = props.style ? props.style : 'style1'; return ( - - + + ); } diff --git a/packages/webapp/src/components/login-page/index.tsx b/packages/webapp/src/components/login-page/index.tsx index 34638ade..170e36df 100644 --- a/packages/webapp/src/components/login-page/index.tsx +++ b/packages/webapp/src/components/login-page/index.tsx @@ -1,14 +1,14 @@ -import React, { useEffect } from 'react' -import { FormattedMessage, useIntl } from 'react-intl' -import { Link } from 'react-router-dom' +import React, { useEffect } from 'react'; +import { FormattedMessage, useIntl } from 'react-intl'; +import { Link as RouterLink} from 'react-router-dom' -import { PageContent } from '../../theme/global-style'; +import { PageContent } from '../../theme'; import Header from '../layout/header' import Footer from '../layout/footer' import SubmitButton from '../form/submit-button' import Input from '../form/input'; import GlobalError from '../form/global-error'; -import { FormControl } from '@material-ui/core'; +import { FormControl, Link, Typography } from '@material-ui/core'; const ConfigStatusMessage = (props: any) => { @@ -56,8 +56,13 @@ const LoginPage = () => {
-

-

+ + + + + + + @@ -73,7 +78,7 @@ const LoginPage = () => { - +
diff --git a/packages/webapp/src/components/login-page/styled.ts b/packages/webapp/src/components/login-page/styled.ts deleted file mode 100644 index a882f637..00000000 --- a/packages/webapp/src/components/login-page/styled.ts +++ /dev/null @@ -1,19 +0,0 @@ -import styled from 'styled-components'; - - -export const StyledNav = styled.div` -.db-warn-msg { - margin-top: 30px; - width: 100%; -} - -.db-warn-msg p { - margin: 0 auto; - width: 500px; - background-color: #e97450; - font-size: 15px; - color: white; - padding: 15px 30px; - border-radius: 10px; -}` - \ No newline at end of file diff --git a/packages/webapp/src/components/maps-page/action-chooser/index.tsx b/packages/webapp/src/components/maps-page/action-chooser/index.tsx index c26817cc..add511bf 100644 --- a/packages/webapp/src/components/maps-page/action-chooser/index.tsx +++ b/packages/webapp/src/components/maps-page/action-chooser/index.tsx @@ -9,7 +9,7 @@ import EditOutlinedIcon from '@material-ui/icons/EditOutlined'; import PublicOutlinedIcon from '@material-ui/icons/PublicOutlined'; import PrintOutlinedIcon from '@material-ui/icons/PrintOutlined'; import ShareOutlinedIcon from '@material-ui/icons/ShareOutlined'; -import { StyledMenuItem } from '../styled'; +import { StyledMenuItem } from '../maps-list/styled'; import { FormattedMessage } from 'react-intl'; export type ActionType = 'open' | 'share' | 'delete' | 'info' | 'duplicate' | 'export' | 'rename' | 'print' | 'info' | 'publish' | undefined; diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/index.tsx b/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/index.tsx index 83afc8e8..4635f654 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/index.tsx +++ b/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/index.tsx @@ -1,8 +1,8 @@ import React from "react"; -import { DialogActions, DialogContentText, DialogTitle } from "@material-ui/core"; +import { Button, DialogContentText, DialogTitle } from "@material-ui/core"; import { FormattedMessage, MessageDescriptor, useIntl } from "react-intl"; import { ErrorInfo } from "../../../../services/Service"; -import { ButtonStyled, StyledDialog, StyledDialogActions, StyledDialogContent, StyledDialogTitle } from "./style"; +import { StyledDialog, StyledDialogActions, StyledDialogContent, StyledDialogTitle } from "./style"; import GlobalError from "../../../form/global-error"; export type DialogProps = { @@ -44,14 +44,14 @@ const BaseDialog = (props: DialogProps) => { + {handleOnSubmit ? ( - + ) : null } - - {handleOnSubmit ? () : ()}; - diff --git a/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/style.ts b/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/style.ts index 4edeadd9..b62ad95c 100644 --- a/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/style.ts +++ b/packages/webapp/src/components/maps-page/action-dispatcher/action-dialog/style.ts @@ -1,4 +1,4 @@ -import { Button, Dialog, DialogActions, DialogContent, DialogTitle, TableCell, withStyles } from "@material-ui/core"; +import { Dialog, DialogActions, DialogContent, DialogTitle, withStyles } from "@material-ui/core"; export const StyledDialogContent = withStyles({ root: { @@ -18,39 +18,6 @@ export const StyledDialogActions = withStyles({ } })(DialogActions); -export const ButtonStyled = withStyles({ - root: { - textTransform: 'none', - fontSize: '15px', - fontWeight: 600, - width: '196px', - padding: '7px 64px 8px 64px', - '&:hover': { - border: '0' - }, - borderRadius: '9px' - }, - outlinedPrimary: { - border: '0', - background: '#ffa800', - color: 'white', - '&:hover': { - border: '0', - background: 'rgba(249, 168, 38, 0.91)' - } - }, - outlinedSecondary: { - background: '#white', - color: '#ffa800', - border: '1px solid #ffa800', - '&:hover': { - border: '1px solid rgba(249, 168, 38, 0.91)', - background: 'white' - } - } -})(Button) - - export const StyledDialog = withStyles({ root: { borderRadius: '9px' diff --git a/packages/webapp/src/components/maps-page/index.tsx b/packages/webapp/src/components/maps-page/index.tsx index 9b150fb0..9ddbc90d 100644 --- a/packages/webapp/src/components/maps-page/index.tsx +++ b/packages/webapp/src/components/maps-page/index.tsx @@ -1,439 +1,150 @@ -import React, { useEffect } from 'react' -import { PageContainer, MapsListArea, HeaderArea, StyledTableCell } from './styled'; - -import { createStyles, makeStyles, Theme, ThemeProvider } from '@material-ui/core/styles'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableContainer from '@material-ui/core/TableContainer'; -import TableHead from '@material-ui/core/TableHead'; -import TablePagination from '@material-ui/core/TablePagination'; -import TableRow from '@material-ui/core/TableRow'; -import TableSortLabel from '@material-ui/core/TableSortLabel'; +import React, { useEffect } from 'react'; +import clsx from 'clsx'; +import Drawer from '@material-ui/core/Drawer'; +import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; -import Typography from '@material-ui/core/Typography'; -import Paper from '@material-ui/core/Paper'; -import Checkbox from '@material-ui/core/Checkbox'; +import List from '@material-ui/core/List'; +import Divider from '@material-ui/core/Divider'; import IconButton from '@material-ui/core/IconButton'; -import Tooltip from '@material-ui/core/Tooltip'; -import DeleteIcon from '@material-ui/icons/Delete'; -import FilterListIcon from '@material-ui/icons/FilterList'; -import StarRateRoundedIcon from '@material-ui/icons/StarRateRounded'; -import MoreHorizIcon from '@material-ui/icons/MoreHoriz'; -import { CSSProperties } from 'react'; -import { useSelector } from 'react-redux'; -import { activeInstance } from '../../reducers/serviceSlice'; -import { useQuery } from 'react-query'; -import { ErrorInfo, MapInfo, Service } from '../../services/Service'; -import { theme } from '../../theme/global-style'; -import { CssBaseline } from '@material-ui/core'; -import ActionChooser, { ActionType } from './action-chooser'; -import ActionDispatcher from './action-dispatcher'; -import NavPanel from './nav-panel'; +import MenuIcon from '@material-ui/icons/Menu'; +import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemIcon from '@material-ui/core/ListItemIcon'; +import { MapsList } from './maps-list'; +import { ListItemTextStyled, useStyles } from './style'; +import { AddTwoTone, BlurCircular, DeleteOutlineTwoTone, LabelTwoTone, PublicTwoTone, ShareTwoTone, StarRateTwoTone } from '@material-ui/icons'; +import InboxTwoToneIcon from '@material-ui/icons/InboxTwoTone'; +import { Button, ListItemSecondaryAction } from '@material-ui/core'; +type FilterType = 'public' | 'all' | 'starred' | 'shared' | 'label' | 'owned' - -function descendingComparator(a: T, b: T, orderBy: keyof T) { - if (b[orderBy] < a[orderBy]) { - return -1; - } - if (b[orderBy] > a[orderBy]) { - return 1; - } - return 0; +interface Filter { + type: FilterType } -type Order = 'asc' | 'desc'; - -function getComparator( - order: Order, - orderBy: Key, -): (a: { [key in Key]: number | string | boolean | string[] | undefined }, b: { [key in Key]: number | string | string[] | boolean }) => number { - return order === 'desc' - ? (a, b) => descendingComparator(a, b, orderBy) - : (a, b) => -descendingComparator(a, b, orderBy); +interface LabelFinter extends Filter { + label: string } -function stableSort(array: T[], comparator: (a: T, b: T) => number) { - const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); - stabilizedThis.sort((a, b) => { - const order = comparator(a[0], b[0]); - if (order !== 0) return order; - return a[1] - b[1]; - }); - return stabilizedThis.map((el) => el[0]); -} +const MapsPage = (props: any) => { + const classes = useStyles(); + const [open, setOpen] = React.useState(true); -interface HeadCell { - disablePadding: boolean; - id: keyof MapInfo; - label: string; - numeric: boolean; - style: CSSProperties; -} - -const headCells: HeadCell[] = [ - { id: 'starred', numeric: false, disablePadding: false, label: '', style: { width: '20px', padding: '0px' } }, - { id: 'name', numeric: false, disablePadding: true, label: 'Name', style: {} }, - { id: 'labels', numeric: false, disablePadding: true, label: 'Labels', style: {} }, - { id: 'creator', numeric: false, disablePadding: false, label: 'Creator', style: {} }, - { id: 'modified', numeric: true, disablePadding: false, label: 'Modified', style: { width: '50px' } } -]; - -interface EnhancedTableProps { - classes: ReturnType; - numSelected: number; - onRequestSort: (event: React.MouseEvent, property: keyof MapInfo) => void; - onSelectAllClick: (event: React.ChangeEvent) => void; - order: Order; - orderBy: string; - rowCount: number; -} - -function EnhancedTableHead(props: EnhancedTableProps) { - const { classes, onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = props; - - const createSortHandler = (property: keyof MapInfo) => (event: React.MouseEvent) => { - onRequestSort(event, property); - }; - - return ( - - - - - 0 && numSelected < rowCount} - checked={rowCount > 0 && numSelected === rowCount} - onChange={onSelectAllClick} - size='small' - inputProps={{ 'aria-label': 'select all desserts' }} - /> - - - {headCells.map((headCell) => ( - - - {headCell.label} - {orderBy === headCell.id ? ( - - {order === 'desc' ? 'sorted descending' : 'sorted ascending'} - - ) : null} - - - ))} - - "" - - - - ); -} - -const useToolbarStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - paddingLeft: theme.spacing(2), - paddingRight: theme.spacing(1), - }, - title: { - flex: '1 1 100%', - }, - }), -); - -interface EnhancedTableToolbarProps { - numSelected: number; -} - -const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { - const classes = useToolbarStyles(); - const { numSelected } = props; - - return ( - - {numSelected > 0 ? ( - - {numSelected} selected - - ) : ( - - Nutrition - - )} - {numSelected > 0 ? ( - - - - - - ) : ( - - - - - - )} - - ); -}; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - width: '100%', - }, - paper: { - width: '100%', - marginBottom: theme.spacing(2), - }, - table: { - minWidth: 750, - border: 0, - }, - visuallyHidden: { - border: 0, - clip: 'rect(0 0 0 0)', - height: 1, - margin: -1, - overflow: 'hidden', - padding: 0, - position: 'absolute', - top: 20, - width: 1, - }, - }), -); - -type ActionPanelState = { - el: HTMLElement | undefined, - mapId: number -} - -const EnhancedTable = () => { - const classes = useStyles(); - const [order, setOrder] = React.useState('asc'); - const [orderBy, setOrderBy] = React.useState('modified'); - const [selected, setSelected] = React.useState([]); - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - const service: Service = useSelector(activeInstance); - - const { isLoading, error, data } = useQuery('maps', async () => { - - const result = await service.fetchAllMaps(); - return result; - }); - const mapsInfo: MapInfo[] = data ? data : []; - - - const [activeRowAction, setActiveRowAction] = React.useState(undefined); - type ActiveDialog = { - actionType: ActionType; - mapId: number - }; - - const [activeDialog, setActiveDialog] = React.useState(undefined); - const handleRequestSort = (event: React.MouseEvent, property: keyof MapInfo) => { - const isAsc = orderBy === property && order === 'asc'; - setOrder(isAsc ? 'desc' : 'asc'); - setOrderBy(property); - }; - - const handleSelectAllClick = (event: React.ChangeEvent): void => { - if (event.target.checked) { - const newSelecteds = mapsInfo.map((n) => n.id); - setSelected(newSelecteds); - return; - } - setSelected([]); - }; - - const handleRowClick = (event: React.MouseEvent, id: number): void => { - const selectedIndex = selected.indexOf(id); - let newSelected: number[] = []; - - if (selectedIndex === -1) { - newSelected = newSelected.concat(selected, id); - } else if (selectedIndex === 0) { - newSelected = newSelected.concat(selected.slice(1)); - } else if (selectedIndex === selected.length - 1) { - newSelected = newSelected.concat(selected.slice(0, -1)); - } else if (selectedIndex > 0) { - newSelected = newSelected.concat( - selected.slice(0, selectedIndex), - selected.slice(selectedIndex + 1), - ); - } - - setSelected(newSelected); - }; - - const handleChangePage = (event: unknown, newPage: number) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { - setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); - }; - - const handleActionClick = (mapId: number): ((event: any) => void) => { - return (event: any): void => { - setActiveRowAction( - { - mapId: mapId, - el: event.currentTarget - } - ); - event.stopPropagation(); + const handleDrawerOpen = () => { + setOpen(true); }; - }; - const handleActionMenuClose = (action: ActionType): void => { - if (action) { - const mapId = activeRowAction?.mapId; + const handleDrawerClose = () => { + setOpen(false); + }; - setActiveRowAction(undefined); - setActiveDialog({ - actionType: action as ActionType, - mapId: mapId as number - }); - } - }; + useEffect(() => { + document.title = 'Maps | WiseMapping'; + }, []); - const isSelected = (id: number) => selected.indexOf(id) !== -1; - const emptyRows = rowsPerPage - Math.min(rowsPerPage, mapsInfo.length - page * rowsPerPage); + return ( +
+ + + + + - return ( -
- - - - - - - {isLoading ? () : stableSort(mapsInfo, getComparator(order, orderBy)) - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map((row: MapInfo) => { - const isItemSelected = isSelected(row.id); - const labelId = row.id; + + + - return ( - handleRowClick(event, row.id)} - role="checkbox" - aria-checked={isItemSelected} - tabIndex={-1} - key={row.id} - selected={isItemSelected} - > + +
+ + {} + +
+ - - - + - - - { alert("") }}> - - - - + + + + + + - {row.name} - {row.labels} - {row.creator} - {row.modified} + + + + + + - - - - - - - - -
- ); - })} - {emptyRows > 0 && ( - - - - )} -
-
-
- -
+ + + + + + - {/* Action Dialog */} - setActiveDialog(undefined)} mapId={activeDialog ? activeDialog.mapId : -1} /> -
- ); + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ ); } - - -const MapsPage = () => { - - useEffect(() => { - document.title = 'Maps | WiseMapping'; - }, []); - - return ( - - - - - -

Header

-
- - - - -
-
- ); -} -export default MapsPage; - - +export default MapsPage; \ No newline at end of file diff --git a/packages/webapp/src/components/maps-page/maps-list/index.tsx b/packages/webapp/src/components/maps-page/maps-list/index.tsx new file mode 100644 index 00000000..56417edc --- /dev/null +++ b/packages/webapp/src/components/maps-page/maps-list/index.tsx @@ -0,0 +1,408 @@ +import React, { useEffect } from 'react' +import { StyledTableCell } from './styled'; + +import { createStyles, makeStyles, Theme, ThemeProvider } from '@material-ui/core/styles'; +import Table from '@material-ui/core/Table'; +import TableBody from '@material-ui/core/TableBody'; +import TableCell from '@material-ui/core/TableCell'; +import TableContainer from '@material-ui/core/TableContainer'; +import TableHead from '@material-ui/core/TableHead'; +import TablePagination from '@material-ui/core/TablePagination'; +import TableRow from '@material-ui/core/TableRow'; +import TableSortLabel from '@material-ui/core/TableSortLabel'; +import Toolbar from '@material-ui/core/Toolbar'; +import Typography from '@material-ui/core/Typography'; +import Paper from '@material-ui/core/Paper'; +import Checkbox from '@material-ui/core/Checkbox'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; +import DeleteIcon from '@material-ui/icons/Delete'; +import FilterListIcon from '@material-ui/icons/FilterList'; +import StarRateRoundedIcon from '@material-ui/icons/StarRateRounded'; +import MoreHorizIcon from '@material-ui/icons/MoreHoriz'; +import { CSSProperties } from 'react'; +import { useSelector } from 'react-redux'; +import { activeInstance } from '../../../reducers/serviceSlice'; +import { useQuery } from 'react-query'; +import { ErrorInfo, MapInfo, Service } from '../../../services/Service'; +import ActionChooser, { ActionType } from '../action-chooser'; +import ActionDispatcher from '../action-dispatcher'; + + + +function descendingComparator(a: T, b: T, orderBy: keyof T) { + if (b[orderBy] < a[orderBy]) { + return -1; + } + if (b[orderBy] > a[orderBy]) { + return 1; + } + return 0; +} + +type Order = 'asc' | 'desc'; + +function getComparator( + order: Order, + orderBy: Key, +): (a: { [key in Key]: number | string | boolean | string[] | undefined }, b: { [key in Key]: number | string | string[] | boolean }) => number { + return order === 'desc' + ? (a, b) => descendingComparator(a, b, orderBy) + : (a, b) => -descendingComparator(a, b, orderBy); +} + +function stableSort(array: T[], comparator: (a: T, b: T) => number) { + const stabilizedThis = array.map((el, index) => [el, index] as [T, number]); + stabilizedThis.sort((a, b) => { + const order = comparator(a[0], b[0]); + if (order !== 0) return order; + return a[1] - b[1]; + }); + return stabilizedThis.map((el) => el[0]); +} + +interface HeadCell { + disablePadding: boolean; + id: keyof MapInfo; + label: string; + numeric: boolean; + style: CSSProperties; +} + +const headCells: HeadCell[] = [ + { id: 'starred', numeric: false, disablePadding: false, label: '', style: { width: '20px', padding: '0px' } }, + { id: 'name', numeric: false, disablePadding: true, label: 'Name', style: {} }, + { id: 'labels', numeric: false, disablePadding: true, label: 'Labels', style: {} }, + { id: 'creator', numeric: false, disablePadding: false, label: 'Creator', style: {} }, + { id: 'modified', numeric: true, disablePadding: false, label: 'Modified', style: { width: '50px' } } +]; + +interface EnhancedTableProps { + classes: ReturnType; + numSelected: number; + onRequestSort: (event: React.MouseEvent, property: keyof MapInfo) => void; + onSelectAllClick: (event: React.ChangeEvent) => void; + order: Order; + orderBy: string; + rowCount: number; +} + +function EnhancedTableHead(props: EnhancedTableProps) { + const { classes, onSelectAllClick, order, orderBy, numSelected, rowCount, onRequestSort } = props; + + const createSortHandler = (property: keyof MapInfo) => (event: React.MouseEvent) => { + onRequestSort(event, property); + }; + + return ( + + + + + 0 && numSelected < rowCount} + checked={rowCount > 0 && numSelected === rowCount} + onChange={onSelectAllClick} + size='small' + inputProps={{ 'aria-label': 'select all desserts' }} + /> + + + {headCells.map((headCell) => ( + + + {headCell.label} + {orderBy === headCell.id ? ( + + {order === 'desc' ? 'sorted descending' : 'sorted ascending'} + + ) : null} + + + ))} + + "" + + + + ); +} + +const useToolbarStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(1), + }, + title: { + flex: '1 1 100%', + }, + }), +); + +interface EnhancedTableToolbarProps { + numSelected: number; +} + +const EnhancedTableToolbar = (props: EnhancedTableToolbarProps) => { + const classes = useToolbarStyles(); + const { numSelected } = props; + + return ( + + {numSelected > 0 ? ( + + {numSelected} selected + + ) : ( + + Nutrition + + )} + {numSelected > 0 ? ( + + + + + + ) : ( + + + + + + )} + + ); +}; + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + }, + paper: { + width: '100%', + marginBottom: theme.spacing(2), + }, + table: { + minWidth: 750, + border: 0, + }, + visuallyHidden: { + border: 0, + clip: 'rect(0 0 0 0)', + height: 1, + margin: -1, + overflow: 'hidden', + padding: 0, + position: 'absolute', + top: 20, + width: 1, + }, + }), +); + +type ActionPanelState = { + el: HTMLElement | undefined, + mapId: number +} + +export const MapsList = () => { + const classes = useStyles(); + const [order, setOrder] = React.useState('asc'); + const [orderBy, setOrderBy] = React.useState('modified'); + const [selected, setSelected] = React.useState([]); + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(5); + const service: Service = useSelector(activeInstance); + + const { isLoading, error, data } = useQuery('maps', async () => { + + const result = await service.fetchAllMaps(); + return result; + }); + const mapsInfo: MapInfo[] = data ? data : []; + + + const [activeRowAction, setActiveRowAction] = React.useState(undefined); + type ActiveDialog = { + actionType: ActionType; + mapId: number + }; + + const [activeDialog, setActiveDialog] = React.useState(undefined); + const handleRequestSort = (event: React.MouseEvent, property: keyof MapInfo) => { + const isAsc = orderBy === property && order === 'asc'; + setOrder(isAsc ? 'desc' : 'asc'); + setOrderBy(property); + }; + + const handleSelectAllClick = (event: React.ChangeEvent): void => { + if (event.target.checked) { + const newSelecteds = mapsInfo.map((n) => n.id); + setSelected(newSelecteds); + return; + } + setSelected([]); + }; + + const handleRowClick = (event: React.MouseEvent, id: number): void => { + const selectedIndex = selected.indexOf(id); + let newSelected: number[] = []; + + if (selectedIndex === -1) { + newSelected = newSelected.concat(selected, id); + } else if (selectedIndex === 0) { + newSelected = newSelected.concat(selected.slice(1)); + } else if (selectedIndex === selected.length - 1) { + newSelected = newSelected.concat(selected.slice(0, -1)); + } else if (selectedIndex > 0) { + newSelected = newSelected.concat( + selected.slice(0, selectedIndex), + selected.slice(selectedIndex + 1), + ); + } + + setSelected(newSelected); + }; + + const handleChangePage = (event: unknown, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + setRowsPerPage(parseInt(event.target.value, 10)); + setPage(0); + }; + + const handleActionClick = (mapId: number): ((event: any) => void) => { + return (event: any): void => { + setActiveRowAction( + { + mapId: mapId, + el: event.currentTarget + } + ); + event.stopPropagation(); + }; + }; + + const handleActionMenuClose = (action: ActionType): void => { + if (action) { + const mapId = activeRowAction?.mapId; + + setActiveRowAction(undefined); + setActiveDialog({ + actionType: action as ActionType, + mapId: mapId as number + }); + } + }; + + const isSelected = (id: number) => selected.indexOf(id) !== -1; + + const emptyRows = rowsPerPage - Math.min(rowsPerPage, mapsInfo.length - page * rowsPerPage); + + return ( +
+ + + + + + + {isLoading ? () : stableSort(mapsInfo, getComparator(order, orderBy)) + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row: MapInfo) => { + const isItemSelected = isSelected(row.id); + const labelId = row.id; + + return ( + handleRowClick(event, row.id)} + role="checkbox" + aria-checked={isItemSelected} + tabIndex={-1} + key={row.id} + selected={isItemSelected} + > + + + + + + + + { alert("") }}> + + + + + + {row.name} + {row.labels} + {row.creator} + {row.modified} + + + + + + + + + + + ); + })} + {emptyRows > 0 && ( + + + + )} + +
+
+ +
+ + {/* Action Dialog */} + setActiveDialog(undefined)} mapId={activeDialog ? activeDialog.mapId : -1} /> +
+ ); +} \ No newline at end of file diff --git a/packages/webapp/src/components/maps-page/maps-list/styled.ts b/packages/webapp/src/components/maps-page/maps-list/styled.ts new file mode 100644 index 00000000..60ba11d1 --- /dev/null +++ b/packages/webapp/src/components/maps-page/maps-list/styled.ts @@ -0,0 +1,18 @@ +import { MenuItem, TableCell } from '@material-ui/core'; +import { withStyles } from '@material-ui/core/styles'; + +export const StyledTableCell = withStyles({ + root: { + color: 'black', + padding: '0px', + cursor: 'pointer' + } +})(TableCell); + +export const StyledMenuItem = withStyles({ + root: { + width: '300px', + padding: '10px 20px', + marging: '0px 20px' + } +})(MenuItem) diff --git a/packages/webapp/src/components/maps-page/nav-panel/index.tsx b/packages/webapp/src/components/maps-page/nav-panel/index.tsx deleted file mode 100644 index 9e016de0..00000000 --- a/packages/webapp/src/components/maps-page/nav-panel/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; - -const NavPanel = (props: any) => { - - return (

nav

); - -} -export default NavPanel; \ No newline at end of file diff --git a/packages/webapp/src/components/maps-page/nav-panel/style.ts b/packages/webapp/src/components/maps-page/nav-panel/style.ts deleted file mode 100644 index 5bd635f5..00000000 --- a/packages/webapp/src/components/maps-page/nav-panel/style.ts +++ /dev/null @@ -1,7 +0,0 @@ -import styled from "styled-components"; - - -export const NavArea = styled.div` -grid-area: nav; -background-color: red; -` diff --git a/packages/webapp/src/components/maps-page/style.ts b/packages/webapp/src/components/maps-page/style.ts new file mode 100644 index 00000000..60d714b9 --- /dev/null +++ b/packages/webapp/src/components/maps-page/style.ts @@ -0,0 +1,80 @@ +import { createStyles, ListItemText, Theme, withStyles } from "@material-ui/core"; +import { makeStyles } from "@material-ui/core"; + +const drawerWidth = 300; + +export const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + display: 'flex', + }, + appBar: { + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + background: '#ffffff', + + }, + appBarShift: { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + menuButton: { + marginRight: 36, + }, + hide: { + display: 'none', + }, + drawer: { + width: drawerWidth, + flexShrink: 0, + whiteSpace: 'nowrap', + }, + drawerOpen: { + background: '#ffa800', + width: drawerWidth, + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + drawerClose: { + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + overflowX: 'hidden', + width: theme.spacing(7) + 1, + [theme.breakpoints.up('sm')]: { + width: theme.spacing(9) + 1, + }, + }, + toolbar: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + padding: theme.spacing(0, 1), + // necessary for content to be below app bar + ...theme.mixins.toolbar, + }, + content: { + flexGrow: 1, + padding: theme.spacing(3), + }, + listItemText: { + } + }), +); + +export const ListItemTextStyled = withStyles({ + root: + { + color: 'white', + } +})(ListItemText); diff --git a/packages/webapp/src/components/maps-page/styled.ts b/packages/webapp/src/components/maps-page/styled.ts deleted file mode 100644 index d2bab408..00000000 --- a/packages/webapp/src/components/maps-page/styled.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Button, Dialog, MenuItem, TableCell } from '@material-ui/core'; -import { withStyles } from '@material-ui/core/styles'; -import styled from 'styled-components'; - -export const PageContainer = styled.div` -display: grid; -height: 100vh; -width: 100vw; -grid-template-areas: "nav header header" - "nav main ads" - "nav main ads"; -grid-template-columns: 240px 1fr 240px; -grid-template-rows: 60px 1fr 30px; -` - -export const MapsListArea = styled.div` -grid-area: main; -background-color: #ffff64; -` - -export const HeaderArea = styled.div` -grid-area: header; -background-color: blue; -` - -export const StyledTableCell = withStyles({ - root: { - color: 'black', - padding: '0px', - cursor: 'pointer' - } -})(TableCell); - -export const StyledMenuItem = withStyles({ - root: { - width: '300px', - padding: '10px 20px', - marging: '0px 20px' - } -})(MenuItem) diff --git a/packages/webapp/src/components/registration-page/index.tsx b/packages/webapp/src/components/registration-page/index.tsx index a8ee646c..0b91b425 100644 --- a/packages/webapp/src/components/registration-page/index.tsx +++ b/packages/webapp/src/components/registration-page/index.tsx @@ -7,14 +7,14 @@ import { ErrorInfo, Service } from '../../services/Service'; import Header from '../layout/header'; import Footer from '../layout/footer'; -import { StyledReCAPTCHA } from './styled'; -import { PageContent, theme } from '../../theme/global-style'; -import { CssBaseline, FormControl, ThemeProvider } from '@material-ui/core'; +import { PageContent } from '../../theme'; +import { FormControl, Typography } from '@material-ui/core'; import { useSelector } from 'react-redux'; import { useMutation } from 'react-query'; import { activeInstance } from '../../reducers/serviceSlice'; import Input from '../form/input'; import GlobalError from '../form/global-error'; +import SubmitButton from '../form/submit-button'; export type Model = { email: string; @@ -58,8 +58,13 @@ const RegistrationForm = () => { return ( -

-

+ + + + + + + @@ -78,17 +83,17 @@ const RegistrationForm = () => { - +
{ model.recaptcha = value; setModel(model) }} /> - +
- +
diff --git a/packages/webapp/src/components/registration-page/styled.ts b/packages/webapp/src/components/registration-page/styled.ts deleted file mode 100644 index 0af9ce4e..00000000 --- a/packages/webapp/src/components/registration-page/styled.ts +++ /dev/null @@ -1,23 +0,0 @@ -import styled from 'styled-components'; - -export const StyledReCAPTCHA = styled.div` -font-size: 13px; -width: 300px; -margin: auto; -}`; - -export const StyledNav = styled.div` -.db-warn-msg { - margin-top: 30px; - width: 100%; -} - -.db-warn-msg p { - margin: 0 auto; - width: 500px; - background-color: #e97450; - font-size: 15px; - color: white; - padding: 15px 30px; - border-radius: 10px; -}`; diff --git a/packages/webapp/src/components/registration-success-page/index.tsx b/packages/webapp/src/components/registration-success-page/index.tsx index bb65eb0d..4d0de4b7 100644 --- a/packages/webapp/src/components/registration-success-page/index.tsx +++ b/packages/webapp/src/components/registration-success-page/index.tsx @@ -1,11 +1,10 @@ import React, { useEffect } from 'react' import { FormattedMessage } from 'react-intl' - -import {PageContent} from '../../theme/global-style'; - +import { PageContent } from '../../theme'; import Header, { SignInButton } from '../layout/header' import Footer from '../layout/footer' - +import { Button, Typography } from '@material-ui/core'; +import { Link as RouterLink } from 'react-router-dom' const RegistrationSuccessPage = () => { @@ -17,13 +16,19 @@ const RegistrationSuccessPage = () => {
-

+ -

-

+ + + -

- + + + + +
diff --git a/packages/webapp/src/images/logo-icon.svg b/packages/webapp/src/images/logo-icon.svg new file mode 100644 index 00000000..dfd4d38b --- /dev/null +++ b/packages/webapp/src/images/logo-icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/webapp/src/images/logo-text-black.svg b/packages/webapp/src/images/logo-text-black.svg new file mode 100644 index 00000000..5b042da3 --- /dev/null +++ b/packages/webapp/src/images/logo-text-black.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/webapp/src/theme/global-style.ts b/packages/webapp/src/theme/global-style.ts deleted file mode 100644 index 5dde5893..00000000 --- a/packages/webapp/src/theme/global-style.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { createMuiTheme, TextField, withStyles } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; -import styled, { createGlobalStyle } from 'styled-components'; - - -const GlobalStyle = createGlobalStyle` - -@import url('https://fonts.googleapis.com/css?family=Montserrat:100,300,400,700,900'); -* { - box-sizing: border-box; -} - -body { - font: 1.2em Montserrat, arial, sans-serif; - margin: 0px; -} - -a { - text-decoration: none; - transition: background-color 0.3s ease; -} - -/* Buttons */ - -.button-style1, -.button-style2, -.button-style3 { - font-size: 16px; - font-weight: 500; - font-stretch: normal; - font-style: normal; - letter-spacing: normal; - white-space: nowrap; - padding-top: 10px; -} - -.button-style1 a, -.button-style2 a, -.button-style3 a { - padding: 10px 30px 10px 30px; - transition: background-color 0.3s ease; - border-radius: 9px; -} - -.button-style1 a { - color: #f9a826; - background-color: white; - border: solid 1px #f9a826; -} - -.button-style1 a:hover { - color: white; - background-color: rgba(255, 168, 0, 0.6); - border: 0px; -} - -.button-style2 a { - color: #ffa800; - background-color: white; - border: solid 1px rgba(255, 168, 0, 0.6); -} - -.button-style2 a:hover { - color: white; - border: solid 1px white; - background-color: rgba(243, 220, 174, 0.6); -} - -.button-style3 a { - color: white; - background-color: #ffa800; - font-weight: 600; -} - -.button-style3 a:hover { - color: #ffa800; - background-color: white; - border: solid 1px #ffa800; - font-weight: 600; -} -`; - -const PageContent = styled.div` -max-width: 350px; -min-height: 350px; -margin: 10px auto; -text-align:center; -padding: 20px 10px 20px 10px; - -/* Form Styles Section */ - -& input[type=checkbox] { - border: solid 1px #f9a826; - background-color: #f9a826; -} - -& input[type=submit], -& input[type=button] { - width: 330px; - height: 53px; - padding: 0px 20px; - margin: 7px 0px; - font-size: 20px; - font-weight: 600; - border-radius: 9px; - border: 0px; - background-color: #ffa800; - color: white; -} - -& input[type=submit]:hover { - background-color: rgba(249, 168, 38, 0.91); - cursor: pointer -} - -& label { - font-size:15px; -} - -& input:placeholder { - color: grey; -} - -& h1, -& h2 { - font-stretch: normal; - font-style: normal; - line-height: 1.2; - letter-spacing: normal; -} - -& h1 { - font-size: 36px; - font-weight: bold; - font-stretch: normal; - font-style: normal; - line-height: normal; - letter-spacing: normal; - color: #f9a826; -} - -& a { - font-size: 15px; - color: #f9a826; -} -`; - -const theme = createMuiTheme({ - typography: { - fontFamily: [ - 'Montserrat' - ].join(','), - h6: { - fontSize: '25px', - fontWeight: 'bold' - }, - }, - palette: { - primary: { - main: '#ffffff', - light: '#ffffff', - dark: '#ffffff', - contrastText: '#ffffff' - }, - secondary: { - main: '#ffffff', - light: '#ffffff', - dark: '#ffffff', - contrastText: '#ffffff' - } - } -}); - -theme.palette.secondary -export { GlobalStyle, PageContent, theme }; - diff --git a/packages/webapp/src/theme/index.ts b/packages/webapp/src/theme/index.ts new file mode 100644 index 00000000..3491ba4d --- /dev/null +++ b/packages/webapp/src/theme/index.ts @@ -0,0 +1,92 @@ +import { createMuiTheme } from '@material-ui/core'; +import styled, { createGlobalStyle } from 'styled-components'; + + +const GlobalStyle = createGlobalStyle` + +@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;600&display=swap'); +* { + box-sizing: border-box; +} +`; + +const PageContent = styled.div` +max-width: 350px; +min-height: 350px; +margin: 10px auto; +text-align:center; +padding: 20px 10px 20px 10px; +`; + +const theme = createMuiTheme({ + overrides: { + MuiOutlinedInput: { + root: { + height: '53px', + borderRadius: '9px', + fontSize: '14px', + '& fieldset': { + border: 'solid 1px #ffcb66', + }, + '&:hover:not($disabled):not($focused):not($error) $notchedOutline': { + borderColor: '#f9a826', + } + }, + }, + MuiInputLabel: { + root: { + color: '#f9a826' + } + }, + MuiButton: { + root: { + fontSize: '15px', + fontWeight: 600, + whiteSpace: 'nowrap', + textTransform: 'none', + borderRadius: '9px', + padding: '6px 54px 6px 54px', + width: '136px' + }, + containedPrimary: { + color: 'white', + '&:hover': { + backgroundColor: 'rgba(249, 168, 38, 0.91)' + } + }, + textPrimary: { + } + } + }, + typography: { + fontFamily: [ + 'Montserrat' + ].join(','), + h4: { + color: '#ffa800', + fontWeight: 600 + }, + h6: { + fontSize: '25px', + fontWeight: 'bold' + }, + }, + palette: { + primary: { + light: '#ffa800', + main: '#ffa800', + dark: '#ffa800', + contrastText: '#FFFFFF', + }, + secondary: { + light: '#FFFFFF', + main: '#FFFFFF', + dark: '#FFFFFF', + contrastText: '#FFFFFF', + }, + + } +}); + +export { GlobalStyle, PageContent, theme }; +