Added custom theme creator

This commit is contained in:
Paweł Malak
2022-03-24 16:07:14 +01:00
parent 378dd8e36d
commit 9ab6c65d85
10 changed files with 246 additions and 41 deletions

View File

@@ -1,21 +1,69 @@
import { useState } from 'react';
// Redux
import { useSelector } from 'react-redux';
import { State } from '../../../../store/reducers';
// Other
import { Theme } from '../../../../interfaces';
import { Button } from '../../../UI';
// UI
import { Button, Modal } from '../../../UI';
import { ThemeGrid } from '../ThemeGrid/ThemeGrid';
import classes from './ThemeBuilder.module.css';
import { ThemeCreator } from './ThemeCreator';
import { ThemeEditor } from './ThemeEditor';
interface Props {
themes: Theme[];
}
export const ThemeBuilder = ({ themes }: Props): JSX.Element => {
const {
auth: { isAuthenticated },
} = useSelector((state: State) => state);
const [showModal, toggleShowModal] = useState(false);
const [isInEdit, toggleIsInEdit] = useState(false);
return (
<div className={classes.ThemeBuilder}>
{/* MODALS */}
<Modal isOpen={showModal} setIsOpen={() => toggleShowModal(!showModal)}>
{isInEdit ? (
<ThemeEditor modalHandler={() => toggleShowModal(!showModal)} />
) : (
<ThemeCreator modalHandler={() => toggleShowModal(!showModal)} />
)}
</Modal>
{/* USER THEMES */}
<ThemeGrid themes={themes} />
<div className={classes.Buttons}>
<Button>Create new theme</Button>
{themes.length && <Button>Edit user themes</Button>}
</div>
{/* BUTTONS */}
{isAuthenticated && (
<div className={classes.Buttons}>
<Button
click={() => {
toggleIsInEdit(false);
toggleShowModal(!showModal);
}}
>
Create new theme
</Button>
{themes.length && (
<Button
click={() => {
toggleIsInEdit(true);
toggleShowModal(!showModal);
}}
>
Edit user themes
</Button>
)}
</div>
)}
</div>
);
};

View File

@@ -0,0 +1,6 @@
.ColorsContainer {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
margin-bottom: 20px;
}

View File

@@ -0,0 +1,117 @@
import { ChangeEvent, FormEvent, useState } from 'react';
import { useDispatch } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actionCreators } from '../../../../store';
import { Theme } from '../../../../interfaces';
import { Button, InputGroup, ModalForm } from '../../../UI';
import classes from './ThemeCreator.module.css';
interface Props {
modalHandler: () => void;
}
export const ThemeCreator = ({ modalHandler }: Props): JSX.Element => {
const { addTheme } = bindActionCreators(actionCreators, useDispatch());
const [formData, setFormData] = useState<Theme>({
name: '',
isCustom: true,
colors: {
primary: '#ffffff',
accent: '#ffffff',
background: '#ffffff',
},
});
const inputChangeHandler = (e: ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
const setColor = ({
target: { value, name },
}: ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
colors: {
...formData.colors,
[name]: value,
},
});
};
const formHandler = (e: FormEvent) => {
e.preventDefault();
// add new theme
addTheme(formData);
// close modal
modalHandler();
// clear theme name
setFormData({ ...formData, name: '' });
};
return (
<ModalForm formHandler={formHandler} modalHandler={modalHandler}>
<InputGroup>
<label htmlFor="name">Theme name</label>
<input
type="text"
name="name"
id="name"
placeholder="my_theme"
required
value={formData.name}
onChange={(e) => inputChangeHandler(e)}
/>
</InputGroup>
<div className={classes.ColorsContainer}>
<InputGroup>
<label htmlFor="primary">Primary color</label>
<input
type="color"
name="primary"
id="primary"
required
value={formData.colors.primary}
onChange={(e) => setColor(e)}
/>
</InputGroup>
<InputGroup>
<label htmlFor="accent">Accent color</label>
<input
type="color"
name="accent"
id="accent"
required
value={formData.colors.accent}
onChange={(e) => setColor(e)}
/>
</InputGroup>
<InputGroup>
<label htmlFor="background">Background color</label>
<input
type="color"
name="background"
id="background"
required
value={formData.colors.background}
onChange={(e) => setColor(e)}
/>
</InputGroup>
</div>
<Button>Add theme</Button>
</ModalForm>
);
};

View File

@@ -0,0 +1,13 @@
import { ModalForm } from '../../../UI';
interface Props {
modalHandler: () => void;
}
export const ThemeEditor = (props: Props): JSX.Element => {
return (
<ModalForm formHandler={() => {}} modalHandler={props.modalHandler}>
<h1>edit</h1>
</ModalForm>
);
};

View File

@@ -4,6 +4,7 @@ import { ChangeEvent, FormEvent, Fragment, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actionCreators } from '../../../store';
import { State } from '../../../store/reducers';
// Typescript
import { Theme, ThemeSettingsForm } from '../../../interfaces';
@@ -14,7 +15,6 @@ import { ThemeBuilder } from './ThemeBuilder/ThemeBuilder';
import { ThemeGrid } from './ThemeGrid/ThemeGrid';
// Other
import { State } from '../../../store/reducers';
import {
inputHandler,
parseThemeToPAB,
@@ -82,7 +82,7 @@ export const Themer = (): JSX.Element => {
<form onSubmit={formSubmitHandler}>
<SettingsHeadline text="Other settings" />
<InputGroup>
<label htmlFor="defaultTheme">Default theme (for new users)</label>
<label htmlFor="defaultTheme">Default theme for new users</label>
<select
id="defaultTheme"
name="defaultTheme"