mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-18 07:26:03 +01:00
feat(wip): add dashboard
This commit is contained in:
21
src/components/Dash/DescriptionInput/index.tsx
Normal file
21
src/components/Dash/DescriptionInput/index.tsx
Normal 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
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
20
src/components/Dash/NameInput/index.tsx
Normal file
20
src/components/Dash/NameInput/index.tsx
Normal 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
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
108
src/components/Dash/index.tsx
Normal file
108
src/components/Dash/index.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
26
src/components/Dash/styles.ts
Normal file
26
src/components/Dash/styles.ts
Normal 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
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user