feature(settingsPage): save links to localstorage
This commit is contained in:
parent
540e79fbff
commit
d36cec3d31
13 changed files with 252 additions and 71 deletions
|
@ -15,9 +15,11 @@
|
||||||
"@mui/icons-material": "^5.16.4",
|
"@mui/icons-material": "^5.16.4",
|
||||||
"@mui/material": "^5.16.4",
|
"@mui/material": "^5.16.4",
|
||||||
"@mui/styled-engine-sc": "6.0.0-alpha.18",
|
"@mui/styled-engine-sc": "6.0.0-alpha.18",
|
||||||
|
"@types/uuid": "^10.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"styled-components": "^6.1.12",
|
"styled-components": "^6.1.12",
|
||||||
|
"uuid": "^10.0.0",
|
||||||
"wouter": "^3.3.1"
|
"wouter": "^3.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -26,6 +26,9 @@ importers:
|
||||||
'@mui/styled-engine-sc':
|
'@mui/styled-engine-sc':
|
||||||
specifier: 6.0.0-alpha.18
|
specifier: 6.0.0-alpha.18
|
||||||
version: 6.0.0-alpha.18(styled-components@6.1.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
|
version: 6.0.0-alpha.18(styled-components@6.1.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
|
||||||
|
'@types/uuid':
|
||||||
|
specifier: ^10.0.0
|
||||||
|
version: 10.0.0
|
||||||
react:
|
react:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.3.1
|
version: 18.3.1
|
||||||
|
@ -35,6 +38,9 @@ importers:
|
||||||
styled-components:
|
styled-components:
|
||||||
specifier: ^6.1.12
|
specifier: ^6.1.12
|
||||||
version: 6.1.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 6.1.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
uuid:
|
||||||
|
specifier: ^10.0.0
|
||||||
|
version: 10.0.0
|
||||||
wouter:
|
wouter:
|
||||||
specifier: ^3.3.1
|
specifier: ^3.3.1
|
||||||
version: 3.3.1(react@18.3.1)
|
version: 3.3.1(react@18.3.1)
|
||||||
|
@ -651,6 +657,9 @@ packages:
|
||||||
'@types/stylis@4.2.5':
|
'@types/stylis@4.2.5':
|
||||||
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
|
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
|
||||||
|
|
||||||
|
'@types/uuid@10.0.0':
|
||||||
|
resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==}
|
||||||
|
|
||||||
'@types/webextension-polyfill@0.10.7':
|
'@types/webextension-polyfill@0.10.7':
|
||||||
resolution: {integrity: sha512-10ql7A0qzBmFB+F+qAke/nP1PIonS0TXZAOMVOxEUsm+lGSW6uwVcISFNa0I4Oyj0884TZVWGGMIWeXOVSNFHw==}
|
resolution: {integrity: sha512-10ql7A0qzBmFB+F+qAke/nP1PIonS0TXZAOMVOxEUsm+lGSW6uwVcISFNa0I4Oyj0884TZVWGGMIWeXOVSNFHw==}
|
||||||
|
|
||||||
|
@ -1682,6 +1691,10 @@ packages:
|
||||||
util-deprecate@1.0.2:
|
util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
|
uuid@10.0.0:
|
||||||
|
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
uuid@8.3.2:
|
uuid@8.3.2:
|
||||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -2361,6 +2374,8 @@ snapshots:
|
||||||
|
|
||||||
'@types/stylis@4.2.5': {}
|
'@types/stylis@4.2.5': {}
|
||||||
|
|
||||||
|
'@types/uuid@10.0.0': {}
|
||||||
|
|
||||||
'@types/webextension-polyfill@0.10.7': {}
|
'@types/webextension-polyfill@0.10.7': {}
|
||||||
|
|
||||||
'@vitejs/plugin-react@4.3.1(vite@5.3.4(@types/node@20.14.11))':
|
'@vitejs/plugin-react@4.3.1(vite@5.3.4(@types/node@20.14.11))':
|
||||||
|
@ -3385,6 +3400,8 @@ snapshots:
|
||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
|
uuid@10.0.0: {}
|
||||||
|
|
||||||
uuid@8.3.2: {}
|
uuid@8.3.2: {}
|
||||||
|
|
||||||
vite-plugin-web-extension@4.1.6(@types/node@20.14.11):
|
vite-plugin-web-extension@4.1.6(@types/node@20.14.11):
|
||||||
|
|
|
@ -11,6 +11,7 @@ import theme from './theme';
|
||||||
import { DrawerOpenContextProvider } from './shared/contexts/DrawerOpenContext';
|
import { DrawerOpenContextProvider } from './shared/contexts/DrawerOpenContext';
|
||||||
import { CurrentPageContextProvider } from './shared/contexts/CurrentPageContext';
|
import { CurrentPageContextProvider } from './shared/contexts/CurrentPageContext';
|
||||||
import { ConfigurableLinksContextProvider } from './shared/contexts/ConfiguarableLinksContext';
|
import { ConfigurableLinksContextProvider } from './shared/contexts/ConfiguarableLinksContext';
|
||||||
|
import { SnackBarValuesContextProvider } from './shared/contexts/SnackBarValuesConext';
|
||||||
|
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
|
@ -19,7 +20,9 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
<DrawerOpenContextProvider>
|
<DrawerOpenContextProvider>
|
||||||
<CurrentPageContextProvider>
|
<CurrentPageContextProvider>
|
||||||
<ConfigurableLinksContextProvider>
|
<ConfigurableLinksContextProvider>
|
||||||
|
<SnackBarValuesContextProvider>
|
||||||
<App />
|
<App />
|
||||||
|
</SnackBarValuesContextProvider>
|
||||||
</ConfigurableLinksContextProvider>
|
</ConfigurableLinksContextProvider>
|
||||||
</CurrentPageContextProvider>
|
</CurrentPageContextProvider>
|
||||||
</DrawerOpenContextProvider>
|
</DrawerOpenContextProvider>
|
||||||
|
|
16
src/shared/classes/HomeplageLink.ts
Normal file
16
src/shared/classes/HomeplageLink.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { IHomepageLink } from "../interfaces/IHomepageLink";
|
||||||
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
|
export class HomepageLink implements IHomepageLink {
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
hyperlink: string;
|
||||||
|
uuid: string
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.title = ""
|
||||||
|
this.subtitle = ""
|
||||||
|
this.hyperlink = ""
|
||||||
|
this.uuid = uuid.v4()
|
||||||
|
}
|
||||||
|
}
|
41
src/shared/components/AppSnackBar.tsx
Normal file
41
src/shared/components/AppSnackBar.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { useContext } from "react";
|
||||||
|
import { SnackBarValuesContext } from "../contexts/SnackBarValuesConext";
|
||||||
|
import { IconButton, Snackbar, SnackbarCloseReason } from "@mui/material";
|
||||||
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
|
||||||
|
export default function() {
|
||||||
|
const {snackBarValues, setSnackBarValues} = useContext(SnackBarValuesContext)
|
||||||
|
|
||||||
|
const handleClose = (
|
||||||
|
event: React.SyntheticEvent | Event,
|
||||||
|
reason?: SnackbarCloseReason
|
||||||
|
) => {
|
||||||
|
if (reason === 'clickaway') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setSnackBarValues({open: false, message: ""})
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = (
|
||||||
|
<>
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
aria-label="close"
|
||||||
|
color="inherit"
|
||||||
|
onClick={handleClose}
|
||||||
|
>
|
||||||
|
<CloseIcon fontSize="small"/>
|
||||||
|
</IconButton>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Snackbar
|
||||||
|
open={snackBarValues.open}
|
||||||
|
autoHideDuration={5000}
|
||||||
|
message={snackBarValues.message}
|
||||||
|
onClose={handleClose}
|
||||||
|
action={action}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
32
src/shared/components/LinkList.tsx
Normal file
32
src/shared/components/LinkList.tsx
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import Sites from '@Data/sites.json'
|
||||||
|
import { Grid } from "@mui/material";
|
||||||
|
import LinkCard from "./linkcard";
|
||||||
|
import { useContext } from 'react';
|
||||||
|
import { ConfigurableLinksContext } from '../contexts/ConfiguarableLinksContext';
|
||||||
|
|
||||||
|
export default function LinkList() {
|
||||||
|
const {configurableLinks, setConfigurableLinks} = useContext(ConfigurableLinksContext)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
{Sites.sites.map(site => (
|
||||||
|
<Grid item key={site.title}>
|
||||||
|
<LinkCard
|
||||||
|
title={site.title}
|
||||||
|
subtitle={site.subtitle}
|
||||||
|
hyperlink={site.hyperlink}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
{configurableLinks.map(link => (
|
||||||
|
<Grid item key={link.title}>
|
||||||
|
<LinkCard
|
||||||
|
title={link.title}
|
||||||
|
subtitle={link.subtitle}
|
||||||
|
hyperlink={link.hyperlink}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,69 +1,120 @@
|
||||||
import { Button, Grid, styled, TextField, Typography } from "@mui/material";
|
import { Button, Grid, styled, TextField, Typography } from "@mui/material";
|
||||||
import { useContext, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { HomepageLink } from "../interfaces/HomepageLink.interface";
|
import { IHomepageLink } from "../interfaces/IHomepageLink";
|
||||||
import { ConfigurableLinksContext } from "../contexts/ConfiguarableLinksContext";
|
import { HomepageLink } from "../classes/HomeplageLink";
|
||||||
|
import { SnackBarValuesContext } from "../contexts/SnackBarValuesConext";
|
||||||
const FormGrid = styled(Grid)(() => ({
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column'
|
|
||||||
}))
|
|
||||||
|
|
||||||
interface FormRowProps {
|
|
||||||
index: number
|
|
||||||
link: HomepageLink
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const {configurableLinks, setConfigurableLinks} = useContext(ConfigurableLinksContext)
|
const [configurableLinks, setConfigurableLinks] = useState<Array<HomepageLink>>(
|
||||||
|
JSON.parse(localStorage.getItem("configurableLinks") as string) as Array<HomepageLink> ??
|
||||||
|
new Array<HomepageLink>
|
||||||
|
)
|
||||||
|
const {snackBarValues, setSnackBarValues} = useContext(SnackBarValuesContext)
|
||||||
|
|
||||||
|
|
||||||
const handleChange = (index: number, event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
const handleChange = (index: number, event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||||
let newconfigurableLinks = [...configurableLinks]
|
let newconfigurableLinks = [...configurableLinks]
|
||||||
newconfigurableLinks[index][event.target.name as keyof HomepageLink] = event.target.value
|
newconfigurableLinks[index][event.target.name as keyof IHomepageLink] = event.target.value
|
||||||
setConfigurableLinks(newconfigurableLinks)
|
setConfigurableLinks(newconfigurableLinks)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addFields = () => {
|
const handleBlur = () => {
|
||||||
setConfigurableLinks([...configurableLinks, {} as HomepageLink])
|
if (LinkNotEmpty(configurableLinks[configurableLinks.length -1])) {
|
||||||
|
addFields()
|
||||||
|
}
|
||||||
|
if (configurableLinks.length > 1) {
|
||||||
|
if (LinkEmpty(configurableLinks[configurableLinks.length -2])) {
|
||||||
|
deleteFieldsAt(configurableLinks.length -2)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function LinkNotEmpty(link: IHomepageLink): Boolean {
|
||||||
|
return link.title != "" &&
|
||||||
|
link.subtitle != "" &&
|
||||||
|
link.hyperlink != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function LinkEmpty(link: IHomepageLink): Boolean {
|
||||||
|
return link.title == "" &&
|
||||||
|
link.subtitle == "" &&
|
||||||
|
link.hyperlink == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const addFields = () => {
|
||||||
|
setConfigurableLinks([...configurableLinks, new HomepageLink()])
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteFieldsAt = (index: number) => {
|
||||||
|
setConfigurableLinks(configurableLinks.filter((link) => {return link != configurableLinks[index]}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveToLocalStorage = () => {
|
||||||
|
localStorage.setItem("configurableLinks", JSON.stringify(configurableLinks.filter((link) => {return link != configurableLinks[configurableLinks.length -1]})))
|
||||||
|
setSnackBarValues({open: true, message: "Saved Links"})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
addFields()
|
||||||
|
return () => {
|
||||||
|
alert("Will close settings")
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={1} sx={{mt: 4, mb: 4}}>
|
<Grid container spacing={1}>
|
||||||
{configurableLinks.map((link, index) =>(
|
{configurableLinks.map((link, index) =>(
|
||||||
<>
|
<Grid container item spacing={3} key={link.uuid}>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={3}>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
required
|
required
|
||||||
label='Title'
|
label='Title'
|
||||||
name='title'
|
name='title'
|
||||||
value={link.title}
|
value={link.title}
|
||||||
|
key={`title${index}`}
|
||||||
onChange={e => handleChange(index, e)}
|
onChange={e => handleChange(index, e)}
|
||||||
|
onBlur={handleBlur}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={3}>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
required
|
required
|
||||||
label='Subtitle'
|
label='Subtitle'
|
||||||
name='subtitle'
|
name='subtitle'
|
||||||
value={link.subtitle}
|
value={link.subtitle}
|
||||||
|
key={`subtitle${index}`}
|
||||||
onChange={e => handleChange(index, e)}
|
onChange={e => handleChange(index, e)}
|
||||||
|
onBlur={handleBlur}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={3}>
|
||||||
<TextField
|
<TextField
|
||||||
fullWidth
|
fullWidth
|
||||||
required
|
required
|
||||||
label='Hyperlink'
|
label='Hyperlink'
|
||||||
name='hyperlink'
|
name='hyperlink'
|
||||||
value={link.hyperlink}
|
value={link.hyperlink}
|
||||||
|
key={`hyperlink${index}`}
|
||||||
onChange={e => handleChange(index, e)}
|
onChange={e => handleChange(index, e)}
|
||||||
|
onBlur={handleBlur}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</>
|
{(configurableLinks.length > 1 && index != configurableLinks.length -1)? (
|
||||||
|
<Grid item xs={2} display={"flex"} alignItems={"center"} justifyContent={"center"}>
|
||||||
|
<Button
|
||||||
|
onClick={() => deleteFieldsAt(index)}
|
||||||
|
variant="contained"
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
):null}
|
||||||
|
</Grid>
|
||||||
))}
|
))}
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button onClick={addFields}>Add field</Button>
|
<Button onClick={() => saveToLocalStorage()}>Save</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { createContext, Dispatch, SetStateAction, useState } from "react"
|
import { createContext, Dispatch, SetStateAction, useState } from "react"
|
||||||
import { HomepageLink } from "../interfaces/HomepageLink.interface"
|
import { IHomepageLink } from "../interfaces/IHomepageLink"
|
||||||
import { ContainerProps } from "@mui/material"
|
import { ContainerProps } from "@mui/material"
|
||||||
|
|
||||||
type ConfigurableLinksContextType = {
|
type ConfigurableLinksContextType = {
|
||||||
configurableLinks: Array<HomepageLink>,
|
configurableLinks: Array<IHomepageLink>,
|
||||||
setConfigurableLinks: Dispatch<SetStateAction<Array<HomepageLink>>>
|
setConfigurableLinks: Dispatch<SetStateAction<Array<IHomepageLink>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConfigurableLinksContext = createContext<ConfigurableLinksContextType>({
|
const ConfigurableLinksContext = createContext<ConfigurableLinksContextType>({
|
||||||
configurableLinks: new Array<HomepageLink>,
|
configurableLinks: new Array<IHomepageLink>,
|
||||||
setConfigurableLinks: () => {}
|
setConfigurableLinks: () => {}
|
||||||
})
|
})
|
||||||
|
|
||||||
const ConfigurableLinksContextProvider = (props: ContainerProps) => {
|
const ConfigurableLinksContextProvider = (props: ContainerProps) => {
|
||||||
const [configurableLinks, setConfigurableLinks] = useState(new Array<HomepageLink>)
|
const [configurableLinks, setConfigurableLinks] = useState(new Array<IHomepageLink>)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigurableLinksContext.Provider value={{configurableLinks, setConfigurableLinks}}>
|
<ConfigurableLinksContext.Provider value={{configurableLinks, setConfigurableLinks}}>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { ContainerProps } from "@mui/material";
|
import { ContainerProps } from "@mui/material";
|
||||||
import { createContext, Dispatch, SetStateAction, useState } from "react";
|
import { createContext, Dispatch, SetStateAction, useState } from "react";
|
||||||
|
|
||||||
|
|
25
src/shared/contexts/SnackBarValuesConext.tsx
Normal file
25
src/shared/contexts/SnackBarValuesConext.tsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { createContext, Dispatch, SetStateAction, useState } from "react"
|
||||||
|
import { ISnackBarValues } from "../interfaces/ISnackBarValues"
|
||||||
|
import { ContainerProps } from "@mui/material"
|
||||||
|
|
||||||
|
type SnackBarValuesContextType = {
|
||||||
|
snackBarValues: ISnackBarValues,
|
||||||
|
setSnackBarValues: Dispatch<SetStateAction<ISnackBarValues>>
|
||||||
|
}
|
||||||
|
|
||||||
|
const SnackBarValuesContext = createContext<SnackBarValuesContextType>({
|
||||||
|
snackBarValues: {open: false, message: ""} as ISnackBarValues,
|
||||||
|
setSnackBarValues: () => {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const SnackBarValuesContextProvider = (props: ContainerProps) => {
|
||||||
|
const [snackBarValues, setSnackBarValues] = useState<ISnackBarValues>({open: false, message: ""})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SnackBarValuesContext.Provider value={{snackBarValues, setSnackBarValues}}>
|
||||||
|
{props.children}
|
||||||
|
</SnackBarValuesContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {SnackBarValuesContext, SnackBarValuesContextProvider}
|
|
@ -1,4 +1,4 @@
|
||||||
export interface HomepageLink {
|
export interface IHomepageLink {
|
||||||
title: string
|
title: string
|
||||||
subtitle: string,
|
subtitle: string,
|
||||||
hyperlink: string
|
hyperlink: string
|
4
src/shared/interfaces/ISnackBarValues.ts
Normal file
4
src/shared/interfaces/ISnackBarValues.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export interface ISnackBarValues {
|
||||||
|
open: boolean
|
||||||
|
message: string
|
||||||
|
}
|
|
@ -3,10 +3,11 @@ import { Box, Button, debounce, FormLabel, Grid, OutlinedInput, styled, TextFiel
|
||||||
import React, { useContext, useState } from 'react'
|
import React, { useContext, useState } from 'react'
|
||||||
import MenuBar from '../shared/components/MenuBar'
|
import MenuBar from '../shared/components/MenuBar'
|
||||||
import LinkCard from '../shared/components/linkcard'
|
import LinkCard from '../shared/components/linkcard'
|
||||||
import { Link, Route } from 'wouter'
|
|
||||||
import MenuDrawer from '../shared/components/menudrawer'
|
import MenuDrawer from '../shared/components/menudrawer'
|
||||||
import { CurrentPageContext } from '../shared/contexts/CurrentPageContext'
|
import { CurrentPageContext } from '../shared/contexts/CurrentPageContext'
|
||||||
import SettingsPage from '../shared/components/settingsPage'
|
import SettingsPage from '../shared/components/settingsPage'
|
||||||
|
import LinkList from '../shared/components/LinkList'
|
||||||
|
import AppSnackBar from '../shared/components/AppSnackBar'
|
||||||
|
|
||||||
const useLocalStorage = (storageKey: string, fallbackState: any) => {
|
const useLocalStorage = (storageKey: string, fallbackState: any) => {
|
||||||
const [value, setValue] = React.useState(
|
const [value, setValue] = React.useState(
|
||||||
|
@ -21,7 +22,6 @@ const useLocalStorage = (storageKey: string, fallbackState: any) => {
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const {currentPage, setCurrentPage} = useContext(CurrentPageContext)
|
const {currentPage, setCurrentPage} = useContext(CurrentPageContext)
|
||||||
const [drawerOpen, setDrawerOpen] = useState(false)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -29,22 +29,13 @@ function App() {
|
||||||
<MenuDrawer />
|
<MenuDrawer />
|
||||||
<Box sx={{m: 4}} maxWidth="lg">
|
<Box sx={{m: 4}} maxWidth="lg">
|
||||||
{currentPage === 'home' ? (
|
{currentPage === 'home' ? (
|
||||||
<Grid container spacing={2}>
|
<LinkList />
|
||||||
{Sites.sites.map(site => (
|
|
||||||
<Grid item key={site.title}>
|
|
||||||
<LinkCard
|
|
||||||
title={site.title}
|
|
||||||
subtitle={site.subtitle}
|
|
||||||
hyperlink={site.hyperlink}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
): null}
|
): null}
|
||||||
{currentPage === 'edit' ? (
|
{currentPage === 'edit' ? (
|
||||||
<SettingsPage />
|
<SettingsPage />
|
||||||
): null}
|
): null}
|
||||||
</Box>
|
</Box>
|
||||||
|
<AppSnackBar />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue