feat(wip): add dashboard

This commit is contained in:
Daniel Soares
2021-12-13 00:36:38 -03:00
parent 7b7e6b9cbd
commit c7dc121d9e
10 changed files with 208 additions and 3 deletions

View File

@@ -0,0 +1,21 @@
import { useData } from '../../../contexts/DataContext'
export function DescriptionInput() {
const { data, setData } = useData()
return (
<textarea
style={{ height: '200px', width: '100%' }}
value={data.settings.description}
onChange={e =>
setData({
...data,
settings: {
...data.settings,
description: e.target.value
}
})
}
/>
)
}

View File

@@ -0,0 +1,20 @@
import { useData } from '../../../contexts/DataContext'
export function NameInput() {
const { data, setData } = useData()
return (
<input
value={data.settings.name}
onChange={e =>
setData({
...data,
settings: {
...data.settings,
name: e.target.value
}
})
}
/>
)
}

View File

@@ -0,0 +1,108 @@
import { isEqual } from 'lodash'
import { useEffect, useState } from 'react'
import { useData } from '../../contexts/DataContext'
import { theme } from '../../styles/stitches.config'
import {
getLocalStorageData,
removeLocalStorageData,
setLocalStorageData
} from '../../utils/localStorage'
import { Home } from '../Home'
import { DescriptionInput } from './DescriptionInput'
import { NameInput } from './NameInput'
import { Content, Preview, Wrapper } from './styles'
export function Dash() {
const { initialData, data, setData } = useData()
const [isLoading, setIsLoading] = useState(true)
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
useEffect(() => {
const storageData = getLocalStorageData()
if (storageData && isLoading) {
setData(storageData)
}
setIsLoading(false)
}, [isLoading, setData])
useEffect(() => {
if (!isEqual(initialData, data)) {
setHasUnsavedChanges(true)
setLocalStorageData(data)
} else {
setHasUnsavedChanges(false)
removeLocalStorageData()
}
}, [data, initialData])
const handleChangeBackground = (background: string) => {
setData({
...data,
settings: { ...data.settings, colors: { ...data.settings.colors, background } }
})
}
const handleChangeButtonsSchema = (schema: string) => {
setData({ ...data, settings: { ...data.settings, buttonsSchema: schema } })
}
const handleChangeOutline = (outline: boolean) => {
setData({ ...data, settings: { ...data.settings, outline } })
}
const handleChangeFont = (font: string) => {
setData({ ...data, settings: { ...data.settings, font } })
}
if (isLoading) {
return <div>Loading...</div>
}
return (
<Wrapper>
<Content>
<h1>Dash {hasUnsavedChanges && '- has unsaved changes'}</h1>
<NameInput />
<DescriptionInput />
<select value={data.settings.font} onChange={e => handleChangeFont(e.target.value)}>
<option value="square">Baloo</option>
<option value="montserrat">Montserrat</option>
<option value="roboto">Roboto</option>
</select>
<select
value={data.settings.colors.background}
onChange={e => handleChangeBackground(e.target.value)}
>
{Object.keys(theme.colors).map(color => (
<option key={color} value={color}>
{color}
</option>
))}
</select>
<select
value={data.settings.buttonsSchema}
onChange={e => handleChangeButtonsSchema(e.target.value)}
>
<option value="square">Square</option>
<option value="rounded">Rounded</option>
<option value="pill">Pill</option>
</select>
<input
type="checkbox"
defaultChecked={data.settings.outline}
onChange={() => handleChangeOutline(!data.settings.outline)}
/>
</Content>
<Preview>
<Home />
</Preview>
</Wrapper>
)
}

View File

@@ -0,0 +1,26 @@
import { styled, theme } from '../../styles/stitches.config'
export const Wrapper = styled('main', {
display: 'grid',
gridTemplateColumns: '1fr 1fr'
})
export const Content = styled('div', {
display: 'flex',
flexDirection: 'column',
gap: '1rem',
fontFamily: theme.fonts.roboto
})
export const Preview = styled('div', {
position: 'relative',
'&::after': {
content: '',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0
}
})

View File

@@ -13,7 +13,8 @@ export const Home = () => {
<Wrapper
css={{
background: theme.colors[colors.background as keyof typeof theme.colors],
color: theme.colors[colors.texts as keyof typeof theme.colors]
color: theme.colors[colors.texts as keyof typeof theme.colors],
fontFamily: theme.fonts[font as keyof typeof theme.fonts]
}}
>
<Content>

View File

@@ -5,6 +5,7 @@ import initialData from '../../data/data.json'
type DataType = typeof initialData
type DataContextType = {
initialData: DataType
data: DataType
setData: Dispatch<SetStateAction<DataType>>
}
@@ -18,7 +19,9 @@ const DataContext = createContext({} as DataContextType)
export const DataProvider = ({ children }: DataProviderProps) => {
const [data, setData] = useState<DataType>(initialData)
return <DataContext.Provider value={{ data, setData }}>{children}</DataContext.Provider>
return (
<DataContext.Provider value={{ initialData, data, setData }}>{children}</DataContext.Provider>
)
}
export const useData = () => useContext(DataContext)

5
src/pages/dash.tsx Normal file
View File

@@ -0,0 +1,5 @@
import { Dash } from '../components/Dash'
export default function DashPage() {
return <Dash />
}

14
src/utils/localStorage.ts Normal file
View File

@@ -0,0 +1,14 @@
const KEY = 'link-free-data'
export function getLocalStorageData() {
const data = process.browser && localStorage.getItem(KEY)
return data ? JSON.parse(data) : null
}
export function setLocalStorageData(data = {}) {
localStorage.setItem(KEY, JSON.stringify(data))
}
export function removeLocalStorageData() {
localStorage.removeItem(KEY)
}