feature(settingsPage): add input fields dynamically

This commit is contained in:
Nikurasu 2024-08-22 18:40:20 +02:00
parent c902bc9236
commit 540e79fbff
Signed by: Nikurasu
GPG key ID: 9E7F14C03EF1F271
31 changed files with 114 additions and 37 deletions

0
package.json Executable file → Normal file
View file

0
pnpm-lock.yaml Executable file → Normal file
View file

0
public/icon-with-shadow.svg Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

0
public/icon/128.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
public/icon/16.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 698 B

After

Width:  |  Height:  |  Size: 698 B

0
public/icon/32.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
public/icon/48.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
public/icon/96.png Executable file → Normal file
View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

0
src/background.ts Executable file → Normal file
View file

View file

@ -1,25 +0,0 @@
import { Grid, styled, TextField, Typography } from "@mui/material";
import { useState } from "react";
const FormGrid = styled(Grid)(() => ({
display: 'flex',
flexDirection: 'column'
}))
export default function SettingsPage() {
const [data, setData] = useState([{title: '', subtitle: '', hyperlink: ''}])
return (
<Grid container spacing={3} sx={{mt: 4, mb: 4}}>
<FormGrid item xs={12} md={6}>
<TextField
required
id='text'
label='text'
name='text'
onChange={e => console.log(e.target.name)}
/>
</FormGrid>
</Grid>
)
}

0
src/index.html Executable file → Normal file
View file

8
src/index.tsx Executable file → Normal file
View file

@ -1,7 +1,6 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './site/App'
import MenuBar from './components/MenuBar';
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
@ -9,8 +8,9 @@ import '@fontsource/roboto/700.css';
import { ThemeProvider } from '@mui/material/styles';
import { CssBaseline } from '@mui/material';
import theme from './theme';
import { DrawerOpenContextProvider } from './contexts/DrawerOpenContext';
import { CurrentPageContextProvider } from './contexts/CurrentPageContext';
import { DrawerOpenContextProvider } from './shared/contexts/DrawerOpenContext';
import { CurrentPageContextProvider } from './shared/contexts/CurrentPageContext';
import { ConfigurableLinksContextProvider } from './shared/contexts/ConfiguarableLinksContext';
ReactDOM.createRoot(document.getElementById('root')!).render(
@ -18,7 +18,9 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
<CssBaseline>
<DrawerOpenContextProvider>
<CurrentPageContextProvider>
<ConfigurableLinksContextProvider>
<App />
</ConfigurableLinksContextProvider>
</CurrentPageContextProvider>
</DrawerOpenContextProvider>
</CssBaseline>

0
src/manifest.json Executable file → Normal file
View file

0
src/popup.tsx Executable file → Normal file
View file

0
src/popup/Popup.css Executable file → Normal file
View file

2
src/popup/Popup.tsx Executable file → Normal file
View file

@ -1,6 +1,6 @@
import { useEffect } from 'react';
import "./Popup.css";
import Sites from "@Data/sites.json"
import Sites from '@Data/sites.json'
import React from 'react';
export default function() {

View file

View file

View file

@ -0,0 +1,70 @@
import { Button, Grid, styled, TextField, Typography } from "@mui/material";
import { useContext, useState } from "react";
import { HomepageLink } from "../interfaces/HomepageLink.interface";
import { ConfigurableLinksContext } from "../contexts/ConfiguarableLinksContext";
const FormGrid = styled(Grid)(() => ({
display: 'flex',
flexDirection: 'column'
}))
interface FormRowProps {
index: number
link: HomepageLink
}
export default function SettingsPage() {
const {configurableLinks, setConfigurableLinks} = useContext(ConfigurableLinksContext)
const handleChange = (index: number, event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
let newconfigurableLinks = [...configurableLinks]
newconfigurableLinks[index][event.target.name as keyof HomepageLink] = event.target.value
setConfigurableLinks(newconfigurableLinks)
}
const addFields = () => {
setConfigurableLinks([...configurableLinks, {} as HomepageLink])
}
return (
<Grid container spacing={1} sx={{mt: 4, mb: 4}}>
{configurableLinks.map((link, index) =>(
<>
<Grid item xs={4}>
<TextField
fullWidth
required
label='Title'
name='title'
value={link.title}
onChange={e => handleChange(index, e)}
/>
</Grid>
<Grid item xs={4}>
<TextField
fullWidth
required
label='Subtitle'
name='subtitle'
value={link.subtitle}
onChange={e => handleChange(index, e)}
/>
</Grid>
<Grid item xs={4}>
<TextField
fullWidth
required
label='Hyperlink'
name='hyperlink'
value={link.hyperlink}
onChange={e => handleChange(index, e)}
/>
</Grid>
</>
))}
<Grid>
<Button onClick={addFields}>Add field</Button>
</Grid>
</Grid>
)
}

View file

@ -0,0 +1,25 @@
import { createContext, Dispatch, SetStateAction, useState } from "react"
import { HomepageLink } from "../interfaces/HomepageLink.interface"
import { ContainerProps } from "@mui/material"
type ConfigurableLinksContextType = {
configurableLinks: Array<HomepageLink>,
setConfigurableLinks: Dispatch<SetStateAction<Array<HomepageLink>>>
}
const ConfigurableLinksContext = createContext<ConfigurableLinksContextType>({
configurableLinks: new Array<HomepageLink>,
setConfigurableLinks: () => {}
})
const ConfigurableLinksContextProvider = (props: ContainerProps) => {
const [configurableLinks, setConfigurableLinks] = useState(new Array<HomepageLink>)
return (
<ConfigurableLinksContext.Provider value={{configurableLinks, setConfigurableLinks}}>
{props.children}
</ConfigurableLinksContext.Provider>
)
}
export {ConfigurableLinksContext, ConfigurableLinksContextProvider}

0
src/data/sites.json → src/shared/data/sites.json Executable file → Normal file
View file

View file

@ -0,0 +1,5 @@
export interface HomepageLink {
title: string
subtitle: string,
hyperlink: string
}

10
src/site/App.tsx Executable file → Normal file
View file

@ -1,12 +1,12 @@
import Sites from '@Data/sites.json'
import { Box, Button, debounce, FormLabel, Grid, OutlinedInput, styled, TextField, Typography } from '@mui/material'
import React, { useContext, useState } from 'react'
import MenuBar from '../components/MenuBar'
import LinkCard from '../components/linkcard'
import MenuBar from '../shared/components/MenuBar'
import LinkCard from '../shared/components/linkcard'
import { Link, Route } from 'wouter'
import MenuDrawer from '../components/menudrawer'
import { CurrentPageContext } from '../contexts/CurrentPageContext'
import SettingsPage from '../components/settingsPage'
import MenuDrawer from '../shared/components/menudrawer'
import { CurrentPageContext } from '../shared/contexts/CurrentPageContext'
import SettingsPage from '../shared/components/settingsPage'
const useLocalStorage = (storageKey: string, fallbackState: any) => {
const [value, setValue] = React.useState(

0
src/theme.ts Executable file → Normal file
View file

0
src/vite-env.d.ts vendored Executable file → Normal file
View file

2
tsconfig.json Executable file → Normal file
View file

@ -17,7 +17,7 @@
"jsx": "react-jsx",
"paths": {
"@Data/*": [
"./src/data/*"
"./src/shared/data/*"
],
}
},

0
tsconfig.node.json Executable file → Normal file
View file

2
vite.config.ts Executable file → Normal file
View file

@ -25,7 +25,7 @@ export default defineConfig({
],
resolve: {
alias: {
"@Data": path.resolve(__dirname, './src/data')
"@Data": path.resolve(__dirname, './src/shared/data')
}
}
});