mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-17 23:16:03 +01:00
fix: some details
This commit is contained in:
25
src/components/Dash/ButtonsStyleSelect/index.tsx
Normal file
25
src/components/Dash/ButtonsStyleSelect/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import type { ButtonVariantProps } from '../../Button'
|
||||
|
||||
export function ButtonsStyleSelect() {
|
||||
const { data, setData } = useData()
|
||||
|
||||
return (
|
||||
<select
|
||||
value={data.settings.buttonsSchema as string}
|
||||
onChange={e =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
buttonsSchema: e.target.value as ButtonVariantProps['styleSchema']
|
||||
}
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="square">Square</option>
|
||||
<option value="rounded">Rounded</option>
|
||||
<option value="pill">Pill</option>
|
||||
</select>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import type { Colors } from '../../../styles/stitches.config'
|
||||
@@ -11,7 +11,11 @@ type ColorSelectProps = {
|
||||
|
||||
export function ColorSelect({ prop }: ColorSelectProps) {
|
||||
const { data, setData } = useData()
|
||||
const [activeColor, setActiveColor] = useState<string>(data.settings.colors[prop] as string)
|
||||
const [activeColor, setActiveColor] = useState(data.settings.colors[prop] as string)
|
||||
|
||||
useEffect(() => {
|
||||
setActiveColor(data.settings.colors[prop] as string)
|
||||
}, [data, prop])
|
||||
|
||||
const allColors = Object.keys(theme.colors) as Colors[]
|
||||
const colorsSchema = [
|
||||
|
||||
@@ -10,10 +10,11 @@ export const SelectButton = styled('button', {
|
||||
width: '100%',
|
||||
height: '3rem',
|
||||
padding: '0.25rem',
|
||||
borderRadius: '0.25rem',
|
||||
borderRadius: '0.2rem',
|
||||
borderWidth: '3px',
|
||||
borderStyle: 'solid',
|
||||
borderColor: theme.colors.slate200,
|
||||
background: 'transparent',
|
||||
cursor: 'pointer',
|
||||
|
||||
variants: {
|
||||
|
||||
19
src/components/Dash/ColorsSettings/index.tsx
Normal file
19
src/components/Dash/ColorsSettings/index.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { ColorSelect } from '../ColorSelect'
|
||||
|
||||
export function ColorsSettings() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Texts</h1>
|
||||
<ColorSelect prop="texts" />
|
||||
|
||||
<h1>Icons</h1>
|
||||
<ColorSelect prop="socialLinks" />
|
||||
|
||||
<h1>Buttons</h1>
|
||||
<ColorSelect prop="buttonLinks" />
|
||||
|
||||
<h1>Background</h1>
|
||||
<ColorSelect prop="background" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
17
src/components/Dash/DataSettings/index.tsx
Normal file
17
src/components/Dash/DataSettings/index.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { ButtonsStyleSelect } from '../ButtonsStyleSelect'
|
||||
import { DescriptionInput } from '../DescriptionInput'
|
||||
import { FontsSelect } from '../FontsSelect'
|
||||
import { NameInput } from '../NameInput'
|
||||
import { OutlineCheckbox } from '../OutlineCheckbox'
|
||||
|
||||
export function DataSettings() {
|
||||
return (
|
||||
<div>
|
||||
<NameInput />
|
||||
<DescriptionInput />
|
||||
<FontsSelect />
|
||||
<ButtonsStyleSelect />
|
||||
<OutlineCheckbox />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export function DescriptionInput() {
|
||||
|
||||
return (
|
||||
<textarea
|
||||
style={{ height: '200px', width: '100%' }}
|
||||
style={{ height: '200px !important', width: '100% !important' }}
|
||||
value={data.settings.description}
|
||||
onChange={e =>
|
||||
setData({
|
||||
|
||||
25
src/components/Dash/FontsSelect/index.tsx
Normal file
25
src/components/Dash/FontsSelect/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import type { Fonts } from '../../../styles/stitches.config'
|
||||
|
||||
export function FontsSelect() {
|
||||
const { data, setData } = useData()
|
||||
|
||||
return (
|
||||
<select
|
||||
value={data.settings.font}
|
||||
onChange={e =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
font: e.target.value as Fonts
|
||||
}
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="baloo">Baloo</option>
|
||||
<option value="montserrat">Montserrat</option>
|
||||
<option value="roboto">Roboto</option>
|
||||
</select>
|
||||
)
|
||||
}
|
||||
21
src/components/Dash/OutlineCheckbox/index.tsx
Normal file
21
src/components/Dash/OutlineCheckbox/index.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { useData } from '../../../hooks/useData'
|
||||
|
||||
export function OutlineCheckbox() {
|
||||
const { data, setData } = useData()
|
||||
|
||||
return (
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={data.settings.outline}
|
||||
onChange={() =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
outline: !data.settings.outline
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
62
src/components/Dash/SaveChangesAlert/index.tsx
Normal file
62
src/components/Dash/SaveChangesAlert/index.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import type { Dispatch, SetStateAction } from 'react'
|
||||
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import { api } from '../../../services/api'
|
||||
import type { Data } from '../../../types/Data'
|
||||
import { removeLocalStorageData } from '../../../utils/localStorage'
|
||||
import { Button } from '../../Button'
|
||||
import { ButtonsGroup, Wrapper } from './styles'
|
||||
|
||||
type SaveChangesAlertProps = {
|
||||
hasUnsavedChanges: boolean
|
||||
setHasUnsavedChanges: Dispatch<SetStateAction<boolean>>
|
||||
initialData: Data
|
||||
}
|
||||
|
||||
export function SaveChangesAlert({
|
||||
hasUnsavedChanges,
|
||||
setHasUnsavedChanges,
|
||||
initialData
|
||||
}: SaveChangesAlertProps) {
|
||||
const { push } = useRouter()
|
||||
const { data, setData } = useData()
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
await api.put('data', { data })
|
||||
removeLocalStorageData()
|
||||
setHasUnsavedChanges(false)
|
||||
setData(data)
|
||||
push('/')
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
setHasUnsavedChanges(false)
|
||||
removeLocalStorageData()
|
||||
setData(initialData)
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper show={hasUnsavedChanges}>
|
||||
You have unsaved changes.
|
||||
<ButtonsGroup>
|
||||
<Button
|
||||
size="small"
|
||||
styleSchema="square"
|
||||
colorSchema="rose"
|
||||
outline
|
||||
onClick={() => handleCancel()}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size="small" styleSchema="square" colorSchema="slate" onClick={() => handleSave()}>
|
||||
Save
|
||||
</Button>
|
||||
</ButtonsGroup>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
38
src/components/Dash/SaveChangesAlert/styles.ts
Normal file
38
src/components/Dash/SaveChangesAlert/styles.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { styled, theme } from '../../../styles/stitches.config'
|
||||
|
||||
export const Wrapper = styled('div', {
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '50%',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
padding: '1rem',
|
||||
background: theme.colors.sky200,
|
||||
color: theme.colors.slate700,
|
||||
fontFamily: theme.fonts.roboto,
|
||||
fontSize: '0.875rem',
|
||||
lineHeight: 1,
|
||||
transition: 'all 0.25s ease-in-out',
|
||||
|
||||
variants: {
|
||||
show: {
|
||||
true: {
|
||||
opacity: 1
|
||||
},
|
||||
false: {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
defaultVariant: {
|
||||
show: false
|
||||
}
|
||||
})
|
||||
|
||||
export const ButtonsGroup = styled('div', {
|
||||
display: 'flex',
|
||||
gap: '1rem'
|
||||
})
|
||||
@@ -1,21 +1,13 @@
|
||||
import { isEqual } from 'lodash'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { useData } from '../../hooks/useData'
|
||||
import { api } from '../../services/api'
|
||||
import type { Fonts } from '../../styles/stitches.config'
|
||||
import type { Data } from '../../types/Data'
|
||||
import {
|
||||
getLocalStorageData,
|
||||
removeLocalStorageData,
|
||||
setLocalStorageData
|
||||
} from '../../utils/localStorage'
|
||||
import { ButtonVariantProps } from '../Button'
|
||||
import { getLocalStorageData, setLocalStorageData } from '../../utils/localStorage'
|
||||
import { Home } from '../Home'
|
||||
import { ColorSelect } from './ColorSelect'
|
||||
import { DescriptionInput } from './DescriptionInput'
|
||||
import { NameInput } from './NameInput'
|
||||
import { ColorsSettings } from './ColorsSettings'
|
||||
import { DataSettings } from './DataSettings'
|
||||
import { SaveChangesAlert } from './SaveChangesAlert'
|
||||
import { Content, Preview, Wrapper } from './styles'
|
||||
|
||||
type DashProps = {
|
||||
@@ -23,10 +15,10 @@ type DashProps = {
|
||||
}
|
||||
|
||||
export function Dash({ initialData }: DashProps) {
|
||||
const { push } = useRouter()
|
||||
const { data, setData } = useData()
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
||||
const [activeTab, setActiveTab] = useState<'data' | 'colors'>('data')
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) {
|
||||
@@ -45,75 +37,29 @@ export function Dash({ initialData }: DashProps) {
|
||||
}
|
||||
}, [data, initialData, isLoading, setData])
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
await api.put('data', { data })
|
||||
removeLocalStorageData()
|
||||
setHasUnsavedChanges(false)
|
||||
push('/')
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleChangeButtonsSchema = (schema: ButtonVariantProps['styleSchema']) => {
|
||||
setData({ ...data, settings: { ...data.settings, buttonsSchema: schema } })
|
||||
}
|
||||
|
||||
const handleChangeOutline = (outline: ButtonVariantProps['outline']) => {
|
||||
setData({ ...data, settings: { ...data.settings, outline } })
|
||||
}
|
||||
|
||||
const handleChangeFont = (font: Fonts) => {
|
||||
setData({ ...data, settings: { ...data.settings, font } })
|
||||
}
|
||||
const tabs = [
|
||||
{ label: 'Data', value: 'data' },
|
||||
{ label: 'Colors', value: 'colors' }
|
||||
]
|
||||
const body = { data: <DataSettings />, colors: <ColorsSettings /> }
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<Content>
|
||||
<h1>
|
||||
Dash{' '}
|
||||
{hasUnsavedChanges && (
|
||||
<>
|
||||
- has unsaved changes <button onClick={() => handleSave()}>save</button>
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
<NameInput />
|
||||
<DescriptionInput />
|
||||
|
||||
<select
|
||||
value={data.settings.font}
|
||||
onChange={e => handleChangeFont(e.target.value as Fonts)}
|
||||
>
|
||||
<option value="square">Baloo</option>
|
||||
<option value="montserrat">Montserrat</option>
|
||||
<option value="roboto">Roboto</option>
|
||||
</select>
|
||||
|
||||
<ColorSelect prop="texts" />
|
||||
<ColorSelect prop="socialLinks" />
|
||||
<ColorSelect prop="buttonLinks" />
|
||||
<ColorSelect prop="background" />
|
||||
|
||||
<select
|
||||
value={data.settings.buttonsSchema as string}
|
||||
onChange={e =>
|
||||
handleChangeButtonsSchema(e.target.value as ButtonVariantProps['styleSchema'])
|
||||
}
|
||||
>
|
||||
<option value="square">Square</option>
|
||||
<option value="rounded">Rounded</option>
|
||||
<option value="pill">Pill</option>
|
||||
</select>
|
||||
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={data.settings.outline as boolean}
|
||||
onChange={() =>
|
||||
handleChangeOutline(!data.settings.outline as ButtonVariantProps['outline'])
|
||||
}
|
||||
<SaveChangesAlert
|
||||
hasUnsavedChanges={hasUnsavedChanges}
|
||||
setHasUnsavedChanges={setHasUnsavedChanges}
|
||||
initialData={initialData}
|
||||
/>
|
||||
<h1>Dash </h1>
|
||||
|
||||
{tabs.map(tab => (
|
||||
<button key={tab.value} onClick={() => setActiveTab(tab.value as 'data' | 'colors')}>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
|
||||
{body[activeTab]}
|
||||
</Content>
|
||||
<Preview>
|
||||
<Home />
|
||||
|
||||
@@ -2,25 +2,29 @@ import { styled, theme } from '../../styles/stitches.config'
|
||||
|
||||
export const Wrapper = styled('main', {
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr'
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
position: 'fixed',
|
||||
inset: 0
|
||||
})
|
||||
|
||||
export const Content = styled('div', {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
fontFamily: theme.fonts.roboto
|
||||
padding: '5rem 1rem 1rem',
|
||||
fontFamily: theme.fonts.roboto,
|
||||
color: theme.colors.slate900,
|
||||
background: theme.colors.slate50,
|
||||
overflowY: 'scroll'
|
||||
})
|
||||
|
||||
export const Preview = styled('div', {
|
||||
position: 'relative',
|
||||
overflowY: 'scroll',
|
||||
|
||||
'&::after': {
|
||||
content: '',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0
|
||||
inset: 0
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user