mirror of
https://github.com/dsoaress/link-free.git
synced 2026-08-17 15:06:06 +01:00
refactor: with styled-components
This commit is contained in:
@@ -1,18 +1,17 @@
|
||||
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}
|
||||
value={data.settings.buttonsSchema}
|
||||
onChange={e =>
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
buttonsSchema: e.target.value as ButtonVariantProps['styleSchema']
|
||||
buttonsSchema: e.target.value as 'square' | 'rounded' | 'pill'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
35
src/components/Dash/ColorPicker/index.tsx
Normal file
35
src/components/Dash/ColorPicker/index.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { BlockPicker } from 'react-color'
|
||||
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import { colors } from '../../../styles/colors'
|
||||
|
||||
type ColorPickerProps = {
|
||||
prop: 'texts' | 'socialLinks' | 'background' | 'buttonLinks'
|
||||
}
|
||||
|
||||
export function ColorPicker({ prop }: ColorPickerProps) {
|
||||
const { data, setData } = useData()
|
||||
|
||||
const handleChange = (color: string) => {
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
colors: {
|
||||
...data.settings.colors,
|
||||
[prop]: color
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<BlockPicker
|
||||
color={data.settings.colors[prop]}
|
||||
colors={colors}
|
||||
triangle="hide"
|
||||
width="100%"
|
||||
onChangeComplete={color => handleChange(color.hex)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import type { Colors } from '../../../styles/stitches.config'
|
||||
import { theme } from '../../../styles/stitches.config'
|
||||
import { Color, SelectButton, Wrapper } from './styles'
|
||||
|
||||
type ColorSelectProps = {
|
||||
prop: 'texts' | 'socialLinks' | 'background' | 'buttonLinks'
|
||||
}
|
||||
|
||||
export function ColorSelect({ prop }: ColorSelectProps) {
|
||||
const { data, setData } = useData()
|
||||
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 = [
|
||||
'slate',
|
||||
'red',
|
||||
'orange',
|
||||
'amber',
|
||||
'yellow',
|
||||
'lime',
|
||||
'green',
|
||||
'emerald',
|
||||
'teal',
|
||||
'cyan',
|
||||
'sky',
|
||||
'blue',
|
||||
'indigo',
|
||||
'violet',
|
||||
'purple',
|
||||
'fuchsia',
|
||||
'pink',
|
||||
'rose'
|
||||
]
|
||||
|
||||
const colors = {
|
||||
texts: allColors,
|
||||
socialLinks: colorsSchema,
|
||||
background: allColors,
|
||||
buttonLinks: colorsSchema
|
||||
}[prop]
|
||||
|
||||
const backgroundColor = (color: string) => {
|
||||
if (prop === 'background' || prop === 'texts') {
|
||||
return theme.colors[color as Colors]
|
||||
}
|
||||
|
||||
return theme.colors[`${color}600` as Colors]
|
||||
}
|
||||
|
||||
const handleChange = (color: string) => {
|
||||
setActiveColor(color)
|
||||
setData({
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
colors: {
|
||||
...data.settings.colors,
|
||||
[prop]: color
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{colors.map(color => (
|
||||
<SelectButton
|
||||
key={color}
|
||||
active={color === activeColor}
|
||||
onClick={() => handleChange(color)}
|
||||
>
|
||||
<Color
|
||||
css={{
|
||||
backgroundColor: backgroundColor(color)
|
||||
}}
|
||||
/>
|
||||
</SelectButton>
|
||||
))}
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { styled, theme } from '../../../styles/stitches.config'
|
||||
|
||||
export const Wrapper = styled('div', {
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(10, 1fr)',
|
||||
gridGap: '0.5rem'
|
||||
})
|
||||
|
||||
export const SelectButton = styled('button', {
|
||||
width: '100%',
|
||||
height: '3rem',
|
||||
padding: '0.25rem',
|
||||
borderRadius: '0.2rem',
|
||||
borderWidth: '3px',
|
||||
borderStyle: 'solid',
|
||||
borderColor: theme.colors.slate200,
|
||||
background: 'transparent',
|
||||
cursor: 'pointer',
|
||||
|
||||
variants: {
|
||||
active: {
|
||||
true: {
|
||||
borderColor: theme.colors.sky500
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const Color = styled('div', {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: '0.25rem'
|
||||
})
|
||||
@@ -1,19 +1,34 @@
|
||||
import { ColorSelect } from '../ColorSelect'
|
||||
import { ColorPicker } from '../ColorPicker'
|
||||
|
||||
export function ColorsSettings() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Texts</h1>
|
||||
<ColorSelect prop="texts" />
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: '1rem',
|
||||
flexWrap: 'wrap',
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<h1>Texts</h1>
|
||||
<ColorPicker prop="texts" />
|
||||
</div>
|
||||
|
||||
<h1>Icons</h1>
|
||||
<ColorSelect prop="socialLinks" />
|
||||
<div>
|
||||
<h1>Icons</h1>
|
||||
<ColorPicker prop="socialLinks" />
|
||||
</div>
|
||||
|
||||
<h1>Buttons</h1>
|
||||
<ColorSelect prop="buttonLinks" />
|
||||
<div>
|
||||
<h1>Buttons</h1>
|
||||
<ColorPicker prop="buttonLinks" />
|
||||
</div>
|
||||
|
||||
<h1>Background</h1>
|
||||
<ColorSelect prop="background" />
|
||||
<div>
|
||||
<h1>Background</h1>
|
||||
<ColorPicker prop="background" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useData } from '../../../hooks/useData'
|
||||
import type { Fonts } from '../../../styles/stitches.config'
|
||||
|
||||
export function FontsSelect() {
|
||||
const { data, setData } = useData()
|
||||
@@ -12,14 +11,14 @@ export function FontsSelect() {
|
||||
...data,
|
||||
settings: {
|
||||
...data.settings,
|
||||
font: e.target.value as Fonts
|
||||
font: e.target.value
|
||||
}
|
||||
})
|
||||
}
|
||||
>
|
||||
<option value="baloo">Baloo</option>
|
||||
<option value="montserrat">Montserrat</option>
|
||||
<option value="roboto">Roboto</option>
|
||||
<option value="'Baloo Bhaijaan 2', sans-serif">Baloo</option>
|
||||
<option value="'Montserrat', sans-serif">Montserrat</option>
|
||||
<option value="'Roboto', sans-serif">Roboto</option>
|
||||
</select>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,23 +40,17 @@ export function SaveChangesAlert({
|
||||
setData(initialData)
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper show={hasUnsavedChanges}>
|
||||
return hasUnsavedChanges ? (
|
||||
<Wrapper>
|
||||
You have unsaved changes.
|
||||
<ButtonsGroup>
|
||||
<Button
|
||||
size="small"
|
||||
styleSchema="square"
|
||||
colorSchema="rose"
|
||||
outline
|
||||
onClick={() => handleCancel()}
|
||||
>
|
||||
<Button size="small" outlined onClick={() => handleCancel()}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size="small" styleSchema="square" colorSchema="slate" onClick={() => handleSave()}>
|
||||
<Button size="small" onClick={() => handleSave()}>
|
||||
Save
|
||||
</Button>
|
||||
</ButtonsGroup>
|
||||
</Wrapper>
|
||||
)
|
||||
) : null
|
||||
}
|
||||
|
||||
@@ -1,38 +1,19 @@
|
||||
import { styled, theme } from '../../../styles/stitches.config'
|
||||
import styled from 'styled-components'
|
||||
|
||||
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',
|
||||
export const Wrapper = styled.div`
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1;
|
||||
`
|
||||
|
||||
variants: {
|
||||
show: {
|
||||
true: {
|
||||
opacity: 1
|
||||
},
|
||||
false: {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
defaultVariant: {
|
||||
show: false
|
||||
}
|
||||
})
|
||||
|
||||
export const ButtonsGroup = styled('div', {
|
||||
display: 'flex',
|
||||
gap: '1rem'
|
||||
})
|
||||
export const ButtonsGroup = styled.div`
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
`
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { isEqual } from 'lodash'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Collapsible from 'react-collapsible'
|
||||
|
||||
import { useData } from '../../hooks/useData'
|
||||
import type { Data } from '../../types/Data'
|
||||
import { getLocalStorageData, setLocalStorageData } from '../../utils/localStorage'
|
||||
import { Home } from '../Home'
|
||||
import { ColorsSettings } from './ColorsSettings'
|
||||
@@ -10,15 +10,12 @@ import { DataSettings } from './DataSettings'
|
||||
import { SaveChangesAlert } from './SaveChangesAlert'
|
||||
import { Content, Preview, Wrapper } from './styles'
|
||||
|
||||
type DashProps = {
|
||||
initialData: Data
|
||||
}
|
||||
|
||||
export function Dash({ initialData }: DashProps) {
|
||||
export function Dash() {
|
||||
const { data, setData } = useData()
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
||||
const [activeTab, setActiveTab] = useState<'data' | 'colors'>('data')
|
||||
const initialData = data
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoading) {
|
||||
@@ -53,13 +50,18 @@ export function Dash({ initialData }: DashProps) {
|
||||
/>
|
||||
<h1>Dash </h1>
|
||||
|
||||
{tabs.map(tab => (
|
||||
<button key={tab.value} onClick={() => setActiveTab(tab.value as 'data' | 'colors')}>
|
||||
{tabs.map((tab, i) => (
|
||||
<button key={i} onClick={() => setActiveTab(tab.value as 'data' | 'colors')}>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
|
||||
{body[activeTab]}
|
||||
|
||||
<Collapsible trigger="Start here">
|
||||
<p>This is the collapsible content. It can be any element or React component you like.</p>
|
||||
<p>It can even be another Collapsible component. Check out the next section!</p>
|
||||
</Collapsible>
|
||||
</Content>
|
||||
<Preview>
|
||||
<Home />
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
import { styled, theme } from '../../styles/stitches.config'
|
||||
import styled from 'styled-components'
|
||||
|
||||
export const Wrapper = styled('main', {
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr 1fr',
|
||||
position: 'fixed',
|
||||
inset: 0
|
||||
})
|
||||
export const Wrapper = styled.main`
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
`
|
||||
|
||||
export const Content = styled('div', {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1rem',
|
||||
padding: '5rem 1rem 1rem',
|
||||
fontFamily: theme.fonts.roboto,
|
||||
color: theme.colors.slate900,
|
||||
background: theme.colors.slate50,
|
||||
overflowY: 'scroll'
|
||||
})
|
||||
export const Content = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: 5rem 1rem 1rem;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
overflow-y: scroll;
|
||||
`
|
||||
|
||||
export const Preview = styled('div', {
|
||||
position: 'relative',
|
||||
overflowY: 'scroll',
|
||||
export const Preview = styled.div`
|
||||
position: relative;
|
||||
overflow-y: scroll;
|
||||
|
||||
'&::after': {
|
||||
content: '',
|
||||
position: 'absolute',
|
||||
inset: 0
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
})
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user