This commit is contained in:
Sean Edmunds
2024-08-20 16:28:46 -05:00
parent 8152d3fe73
commit 7990f164d6
39 changed files with 824 additions and 772 deletions

View File

@@ -1,5 +1,3 @@
import { useEffect, useState } from "react";
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
import {
ActionIcon,
Button,
@@ -12,33 +10,37 @@ import {
Stack,
Text,
TextInput,
} from "@mantine/core";
import { FiEdit, FiPlus, FiSave, FiTrash, FiX } from "react-icons/fi";
import { useDisclosure, useLocalStorage } from "@mantine/hooks";
import "@mantine/core/styles/ModalBase.css";
import "@mantine/core/styles/Modal.css";
import { actionIconClasses, buttonClasses, modalClasses, textClasses } from "../../../styles";
import ThemeModalContent from "./ThemeModalContent";
import { modals } from "@mantine/modals";
} from '@mantine/core';
import { useDisclosure, useLocalStorage } from '@mantine/hooks';
import { useEffect, useState } from 'react';
import { FiEdit, FiPlus, FiSave, FiTrash, FiX } from 'react-icons/fi';
import { useMutationAPI, useQueryAPI } from '../../../hooks/useAPI';
import '@mantine/core/styles/ModalBase.css';
import '@mantine/core/styles/Modal.css';
import { modals } from '@mantine/modals';
import {
actionIconClasses,
buttonClasses,
modalClasses,
textClasses,
} from '../../../styles';
import ThemeModalContent from './ThemeModalContent';
function ThemesSettings({ theme }: any) {
const [opened, { open, close }] = useDisclosure(false);
const [pickerOpen, { open: openPicker, close: closePicker }] =
useDisclosure(false);
const [colorId, setColorId] = useState<string>("");
const [colorValue, setColorValue] = useState("#000000");
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
const [colorId, setColorId] = useState<string>('');
const [colorValue, setColorValue] = useState('#000000');
const [value, setValue] = useLocalStorage<any>({
key: "theme",
key: 'theme',
defaultValue: {},
});
const { data, isFetched } = useQueryAPI({
endpoint: "api/themes",
endpoint: 'api/themes',
});
const [themesList, setThemesList] = useState([]);
const [selectedTheme, setSelectedTheme] = useState<any>({});
const { mutateAsync: createTheme, isPending: isCreatingTheme } =
useMutationAPI();
const { mutateAsync: deleteTheme, isPending: isDeletingTheme } =
useMutationAPI();
const { mutateAsync: createTheme, isPending: isCreatingTheme } = useMutationAPI();
const { mutateAsync: deleteTheme, isPending: isDeletingTheme } = useMutationAPI();
useEffect(() => {
if (isFetched) {
setThemesList(data);
@@ -57,8 +59,8 @@ function ThemesSettings({ theme }: any) {
const handleSaveTheme = () => {
createTheme({
method: selectedTheme.id === undefined ? "POST" : "PATCH",
endpoint: "api/themes",
method: selectedTheme.id === undefined ? 'POST' : 'PATCH',
endpoint: 'api/themes',
body: selectedTheme,
});
close();
@@ -66,11 +68,11 @@ function ThemesSettings({ theme }: any) {
const openDeleteConfirmModal = (theme: any) =>
modals.openConfirmModal({
title: "Are you sure you want to delete this theme?",
labels: { confirm: "Delete", cancel: "Cancel" },
confirmProps: { color: "red" },
title: 'Are you sure you want to delete this theme?',
labels: { confirm: 'Delete', cancel: 'Cancel' },
confirmProps: { color: 'red' },
onConfirm: () =>
deleteTheme({ method: "DELETE", endpoint: "api/themes", body: theme }),
deleteTheme({ method: 'DELETE', endpoint: 'api/themes', body: theme }),
});
const handleDeleteTheme = (theme: any) => {
@@ -81,7 +83,7 @@ function ThemesSettings({ theme }: any) {
return (
<>
<Modal.Root
size={"50%"}
size={'50%'}
className={modalClasses.editThemeModal}
classNames={modalClasses}
opened={opened}
@@ -93,135 +95,153 @@ function ThemesSettings({ theme }: any) {
<Modal.Title>Edit Theme</Modal.Title>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body p={"2rem"}>
<Modal.Body p={'2rem'}>
<ThemeModalContent selectedTheme={selectedTheme} />
<Divider color="black" my="sm" />
<Divider color='black' my='sm' />
<TextInput
label="Theme Name"
label='Theme Name'
value={selectedTheme.name}
onChange={(e) =>
setSelectedTheme({ ...selectedTheme, name: e.target.value })
}
styles={{
label: {
color: "black",
color: 'black',
},
input: {
color: "black",
backgroundColor: "white",
color: 'black',
backgroundColor: 'white',
},
}}
/>
<Divider color="black" my="sm" />
<Group w={"100%"} h={"100%"} gap={0}>
<Stack w={"50%"}>
<Group c={"black"} justify="space-between">
<Divider color='black' my='sm' />
<Group w={'100%'} h={'100%'} gap={0}>
<Stack w={'50%'}>
<Group c={'black'} justify='space-between'>
<Text>Primary Color</Text>
<ColorSwatch
onClick={() => {
setColorId("primary");
setColorId('primary');
openPicker();
setColorValue(selectedTheme.colortextpri);
}}
radius={"sm"}
w={"100px"}
radius={'sm'}
w={'100px'}
color={selectedTheme.colortextpri}
style={{ cursor: "pointer" }}
style={{ cursor: 'pointer' }}
/>
</Group>
<Group c={"black"} justify="space-between">
<Group c={'black'} justify='space-between'>
<Text>Accent Color</Text>
<ColorSwatch
onClick={() => {
setColorId("accent");
setColorId('accent');
openPicker();
setColorValue(selectedTheme.colortextacc);
}}
radius={"sm"}
w={"100px"}
radius={'sm'}
w={'100px'}
color={selectedTheme.colortextacc}
style={{ cursor: "pointer" }}
style={{ cursor: 'pointer' }}
/>
</Group>
<Group c={"black"} justify="space-between">
<Group c={'black'} justify='space-between'>
<Text>Background Color</Text>
<ColorSwatch
onClick={() => {
setColorId("background");
setColorId('background');
openPicker();
setColorValue(selectedTheme.colorbackground);
}}
radius={"sm"}
w={"100px"}
radius={'sm'}
w={'100px'}
color={selectedTheme.colorbackground}
style={{ cursor: "pointer" }}
style={{ cursor: 'pointer' }}
/>
</Group>
<Group c={"black"} justify="space-between">
<Group c={'black'} justify='space-between'>
<Text>Border Color</Text>
<ColorSwatch
onClick={() => {
setColorId("border");
setColorId('border');
openPicker();
setColorValue(selectedTheme.colorborder);
}}
radius={"sm"}
w={"100px"}
radius={'sm'}
w={'100px'}
color={selectedTheme.colorborder}
style={{ cursor: "pointer" }}
style={{ cursor: 'pointer' }}
/>
</Group>
<Group c={"black"} justify="space-between">
<Group c={'black'} justify='space-between'>
<Text>Search Background Color</Text>
<ColorSwatch
onClick={() => {
setColorId("searchbackground");
setColorId('searchbackground');
openPicker();
setColorValue(selectedTheme.colorsearchbackground);
}}
radius={"sm"}
w={"100px"}
radius={'sm'}
w={'100px'}
color={selectedTheme.colorsearchbackground}
style={{ cursor: "pointer" }}
style={{ cursor: 'pointer' }}
/>
</Group>
<Group c={'black'} justify='space-between'>
<TextInput
label='Background Image Path'
value={selectedTheme.imagebackground}
onChange={(e) =>
setSelectedTheme({ ...selectedTheme, imagebackground: e.target.value })
}
styles={{
label: {
color: 'black',
},
input: {
color: 'black',
backgroundColor: 'white',
},
}}
/>
</Group>
</Stack>
<Stack h={"100%"} w={"50%"} align="center" justify="center">
<Stack h={'100%'} w={'50%'} align='center' justify='center'>
{pickerOpen ? (
<>
<ColorPicker value={colorValue} onChange={setColorValue} />
<Group w={"75%"} justify="space-between">
<Text c={"black"}>{colorValue}</Text>
<Group w={'75%'} justify='space-between'>
<Text c={'black'}>{colorValue}</Text>
<Group>
<Button
color={"green"}
color={'green'}
onClick={() => {
switch (colorId) {
case "primary":
case 'primary':
setSelectedTheme({
...selectedTheme,
colortextpri: colorValue,
});
break;
case "accent":
case 'accent':
setSelectedTheme({
...selectedTheme,
colortextacc: colorValue,
});
break;
case "background":
case 'background':
setSelectedTheme({
...selectedTheme,
colorbackground: colorValue,
});
break;
case "border":
case 'border':
setSelectedTheme({
...selectedTheme,
colorborder: colorValue,
});
break;
case "searchbackground":
case 'searchbackground':
setSelectedTheme({
...selectedTheme,
colorsearchbackground: colorValue,
@@ -233,7 +253,7 @@ function ThemesSettings({ theme }: any) {
>
<FiSave />
</Button>
<Button color={"red"} onClick={closePicker}>
<Button color={'red'} onClick={closePicker}>
<FiX />
</Button>
</Group>
@@ -241,34 +261,31 @@ function ThemesSettings({ theme }: any) {
</>
) : (
<Card
bg={"#0002"}
h={"100%"}
w={"90%"}
style={{ alignItems: "center" }}
bg={'#0002'}
h={'100%'}
w={'90%'}
style={{ alignItems: 'center' }}
>
<Text c="black">Pick a swatch to edit the color.</Text>
<Text c='black'>Pick a swatch to edit the color.</Text>
</Card>
)}
</Stack>
</Group>
<Divider color="black" my="sm" />
<Divider color='black' my='sm' />
<Group>
<Button color={"green"} onClick={handleSaveTheme}>
<Button color={'green'} onClick={handleSaveTheme}>
Save
</Button>
<Button color={"red"} onClick={close}>
<Button color={'red'} onClick={close}>
Cancel
</Button>
</Group>
</Modal.Body>
</Modal.Content>
</Modal.Root>
<Stack h={"100%"} w={"100%"}>
<Stack h={'100%'} w={'100%'}>
<Group>
<Text
className={textClasses.settingsSubTitle}
classNames={textClasses}
>
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
Themes
</Text>
<Button
@@ -277,13 +294,13 @@ function ThemesSettings({ theme }: any) {
onClick={() => {
setSelectedTheme({
id: undefined,
name: "default",
imagebackground: "none",
colorbackground: "#EEEEEE",
colorsearchbackground: "#00000033",
colortextpri: "#222222",
colortextacc: "#5c5c5c",
colorborder: "#5c5c5c",
name: 'default',
imagebackground: 'none',
colorbackground: '#EEEEEE',
colorsearchbackground: '#00000033',
colortextpri: '#222222',
colortextacc: '#5c5c5c',
colorborder: '#5c5c5c',
});
open();
}}
@@ -291,13 +308,13 @@ function ThemesSettings({ theme }: any) {
<FiPlus />
</Button>
</Group>
<Group justify="center">
<Group justify='center'>
{themesList.map((theme: any) => (
<Stack key={theme.name} w={"300px"}>
<Group gap={0} justify="space-between">
<Stack key={theme.name} w={'300px'}>
<Group gap={0} justify='space-between'>
<Button
w={"100%"}
h={"75px"}
w={'100%'}
h={'75px'}
style={{
backgroundColor: theme.colorbackground,
border: `solid ${theme.colorborder}`,
@@ -311,8 +328,8 @@ function ThemesSettings({ theme }: any) {
{theme.name}
</Button>
</Group>
<Group justify="space-between" gap={0}>
<Group className="theme-palette">
<Group justify='space-between' gap={0}>
<Group className='theme-palette'>
<ActionIcon
className={actionIconClasses.editButton}
classNames={actionIconClasses}
@@ -331,7 +348,7 @@ function ThemesSettings({ theme }: any) {
classNames={actionIconClasses}
onClick={() => handleDeleteTheme(theme)}
>
<FiTrash color="red" />
<FiTrash color='red' />
</ActionIcon>
</Group>
</Group>