Theming working
This commit is contained in:
8587
package-lock.json
generated
8587
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,8 +19,11 @@
|
|||||||
"@mantine/modals": "^7.12.1",
|
"@mantine/modals": "^7.12.1",
|
||||||
"@tabler/icons-react": "^3.12.0",
|
"@tabler/icons-react": "^3.12.0",
|
||||||
"@tanstack/react-query": "^5.51.23",
|
"@tanstack/react-query": "^5.51.23",
|
||||||
|
"@tanstack/react-query-devtools": "^4.36.1",
|
||||||
|
"@tanstack/react-query-persist-client": "^5.51.23",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.12",
|
"dayjs": "^1.11.12",
|
||||||
|
"idb-keyval": "^6.2.1",
|
||||||
"jotai": "^2.9.3",
|
"jotai": "^2.9.3",
|
||||||
"mantine-react-table": "^2.0.0-beta.6",
|
"mantine-react-table": "^2.0.0-beta.6",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
|
|||||||
18
src/App.tsx
18
src/App.tsx
@@ -31,15 +31,7 @@ function App() {
|
|||||||
defaultValue: "blackboard",
|
defaultValue: "blackboard",
|
||||||
});
|
});
|
||||||
|
|
||||||
const [currentTheme, setCurrentTheme] = useState<any>({});
|
const [currentTheme, setCurrentTheme] = useState<any>(undefined);
|
||||||
|
|
||||||
const overrides = createTheme({
|
|
||||||
white: currentTheme.colorbackground,
|
|
||||||
fontFamily:
|
|
||||||
"-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif",
|
|
||||||
});
|
|
||||||
|
|
||||||
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data && themeName) {
|
if (data && themeName) {
|
||||||
@@ -60,6 +52,14 @@ function App() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const overrides = createTheme({
|
||||||
|
white: currentTheme?.colorbackground,
|
||||||
|
fontFamily:
|
||||||
|
"-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif",
|
||||||
|
});
|
||||||
|
|
||||||
|
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MantineProvider theme={mantineTheme}>
|
<MantineProvider theme={mantineTheme}>
|
||||||
{currentTheme && (
|
{currentTheme && (
|
||||||
|
|||||||
@@ -1,15 +1,61 @@
|
|||||||
import { MantineReactTable, useMantineReactTable } from "mantine-react-table";
|
import {
|
||||||
|
MantineReactTable,
|
||||||
|
MRT_Row,
|
||||||
|
MRT_TableOptions,
|
||||||
|
useMantineReactTable,
|
||||||
|
} from "mantine-react-table";
|
||||||
import { memo } from "react";
|
import { memo } from "react";
|
||||||
import "../dataTableStyles.css";
|
import "../dataTableStyles.css";
|
||||||
|
import { ActionIcon, Button, Flex, Text, Tooltip } from "@mantine/core";
|
||||||
|
import { FiPlus } from "react-icons/fi";
|
||||||
|
import { IconEdit, IconTrash } from "@tabler/icons-react";
|
||||||
|
import { useMutationAPI } from "../hooks/useAPI";
|
||||||
|
import { modals } from "@mantine/modals";
|
||||||
|
|
||||||
export function DataTableComponent({
|
export function DataTableComponent({
|
||||||
|
tableName,
|
||||||
columns,
|
columns,
|
||||||
tableData,
|
tableData,
|
||||||
isFetching,
|
isFetching,
|
||||||
isLoading,
|
isLoading,
|
||||||
onCreatingRowSave,
|
endpoint,
|
||||||
onEditingRowSave,
|
}: {
|
||||||
}: any) {
|
tableName: string;
|
||||||
|
columns: any;
|
||||||
|
tableData: any;
|
||||||
|
isFetching: boolean;
|
||||||
|
isLoading: boolean;
|
||||||
|
endpoint: string;
|
||||||
|
}) {
|
||||||
|
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
||||||
|
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
||||||
|
const { mutateAsync: deleteRow, isPending: isDeletingRow } = useMutationAPI();
|
||||||
|
|
||||||
|
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
||||||
|
values,
|
||||||
|
exitCreatingMode,
|
||||||
|
}) => {
|
||||||
|
createRow({ method: "POST", endpoint: endpoint, body: values });
|
||||||
|
exitCreatingMode();
|
||||||
|
};
|
||||||
|
const handleEditRow: MRT_TableOptions<any>["onEditingRowSave"] = async ({
|
||||||
|
values,
|
||||||
|
table,
|
||||||
|
}) => {
|
||||||
|
editRow({ method: "PATCH", endpoint: endpoint, body: values });
|
||||||
|
table.setEditingRow(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openDeleteConfirmModal = (row: MRT_Row<any>) =>
|
||||||
|
modals.openConfirmModal({
|
||||||
|
title: "Are you sure you want to delete this user?",
|
||||||
|
children: <Text>Are you sure?</Text>,
|
||||||
|
labels: { confirm: "Delete", cancel: "Cancel" },
|
||||||
|
confirmProps: { color: "red" },
|
||||||
|
onConfirm: () =>
|
||||||
|
deleteRow({ method: "DELETE", endpoint: endpoint, body: row.original }),
|
||||||
|
});
|
||||||
|
|
||||||
const table = useMantineReactTable({
|
const table = useMantineReactTable({
|
||||||
columns: columns,
|
columns: columns,
|
||||||
data: tableData,
|
data: tableData,
|
||||||
@@ -21,8 +67,8 @@ export function DataTableComponent({
|
|||||||
editDisplayMode: "row",
|
editDisplayMode: "row",
|
||||||
enableBottomToolbar: false,
|
enableBottomToolbar: false,
|
||||||
enableToolbarInternalActions: false,
|
enableToolbarInternalActions: false,
|
||||||
onCreatingRowSave: onCreatingRowSave,
|
onCreatingRowSave: handleCreateRow,
|
||||||
onEditingRowSave: onEditingRowSave,
|
onEditingRowSave: handleEditRow,
|
||||||
getRowId: (row: any) => row.id,
|
getRowId: (row: any) => row.id,
|
||||||
initialState: {
|
initialState: {
|
||||||
showProgressBars: isFetching,
|
showProgressBars: isFetching,
|
||||||
@@ -47,6 +93,27 @@ export function DataTableComponent({
|
|||||||
borderLeft: "none",
|
borderLeft: "none",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
renderRowActions: ({ row, table }) => (
|
||||||
|
<Flex gap="md">
|
||||||
|
<Tooltip label="Edit">
|
||||||
|
<ActionIcon onClick={() => table.setEditingRow(row)}>
|
||||||
|
<IconEdit />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Delete">
|
||||||
|
<ActionIcon color="red" onClick={() => openDeleteConfirmModal(row)}>
|
||||||
|
<IconTrash />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
renderTopToolbarCustomActions: ({ table }) => {
|
||||||
|
return (
|
||||||
|
<Button onClick={() => table.setCreatingRow(true)}>
|
||||||
|
<FiPlus />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return <MantineReactTable table={table} />;
|
return <MantineReactTable table={table} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export default function Search() {
|
|||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
style={{
|
style={{
|
||||||
|
height: "100px",
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
position: "relative",
|
position: "relative",
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
import { useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import { DataTable } from "../../../DataTable/DataTable";
|
import { DataTable } from "../../../DataTable/DataTable";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import type { MRT_TableOptions } from "mantine-react-table";
|
|
||||||
import ApplicationColumns from "../../../DataTable/columns/ApplicationColumns";
|
import ApplicationColumns from "../../../DataTable/columns/ApplicationColumns";
|
||||||
import { Stack, Text } from "@mantine/core";
|
import { Stack, Text } from "@mantine/core";
|
||||||
import { textClasses } from "../../../styles";
|
import { textClasses } from "../../../styles";
|
||||||
|
|
||||||
const ApplicationSettings = () => {
|
const ApplicationSettings = () => {
|
||||||
const endpoint = "api/apps";
|
const endpoint = "api/apps";
|
||||||
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
const { data, isFetching, isLoading, isFetched } = useQueryAPI({
|
||||||
@@ -13,34 +12,12 @@ const ApplicationSettings = () => {
|
|||||||
});
|
});
|
||||||
const [applicationData, setApplicationData] = useState<any>([]);
|
const [applicationData, setApplicationData] = useState<any>([]);
|
||||||
|
|
||||||
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
|
||||||
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
setApplicationData(data);
|
setApplicationData(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
exitCreatingMode,
|
|
||||||
}) => {
|
|
||||||
createRow({ method: "POST", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Application created successfully");
|
|
||||||
});
|
|
||||||
exitCreatingMode();
|
|
||||||
};
|
|
||||||
const handleEditRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
table,
|
|
||||||
}) => {
|
|
||||||
editRow({ method: "PATCH", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Application updated successfully");
|
|
||||||
});
|
|
||||||
table.setEditingRow(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -52,8 +29,7 @@ const ApplicationSettings = () => {
|
|||||||
tableData={applicationData}
|
tableData={applicationData}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onCreatingRowSave={handleCreateRow}
|
endpoint={endpoint}
|
||||||
onEditingRowSave={handleEditRow}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
import { useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import { DataTable } from "../../../DataTable/DataTable";
|
import { DataTable } from "../../../DataTable/DataTable";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import type { MRT_TableOptions } from "mantine-react-table";
|
|
||||||
import { Stack, Text } from "@mantine/core";
|
import { Stack, Text } from "@mantine/core";
|
||||||
import BookmarkColumns from "../../../DataTable/columns/BookmarkColumns";
|
import BookmarkColumns from "../../../DataTable/columns/BookmarkColumns";
|
||||||
import { textClasses } from "../../../styles";
|
import { textClasses } from "../../../styles";
|
||||||
@@ -20,8 +18,6 @@ const BookmarkSettings = () => {
|
|||||||
const [bookmarkData, setBookmarkData] = useState<any>([]);
|
const [bookmarkData, setBookmarkData] = useState<any>([]);
|
||||||
const [groups, setGroups] = useState([]);
|
const [groups, setGroups] = useState([]);
|
||||||
const [fullyFetched, setFullyFetched] = useState(false);
|
const [fullyFetched, setFullyFetched] = useState(false);
|
||||||
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
|
||||||
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
@@ -39,25 +35,6 @@ const BookmarkSettings = () => {
|
|||||||
}
|
}
|
||||||
}, [groupDataisFetched]);
|
}, [groupDataisFetched]);
|
||||||
|
|
||||||
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
exitCreatingMode,
|
|
||||||
}) => {
|
|
||||||
createRow({ method: "POST", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Application created successfully");
|
|
||||||
});
|
|
||||||
exitCreatingMode();
|
|
||||||
};
|
|
||||||
const handleEditRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
table,
|
|
||||||
}) => {
|
|
||||||
editRow({ method: "PATCH", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Application updated successfully");
|
|
||||||
});
|
|
||||||
table.setEditingRow(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -69,8 +46,7 @@ const BookmarkSettings = () => {
|
|||||||
tableData={bookmarkData}
|
tableData={bookmarkData}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onCreatingRowSave={handleCreateRow}
|
endpoint={endpoint}
|
||||||
onEditingRowSave={handleEditRow}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
import { useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import { DataTable } from "../../../DataTable/DataTable";
|
import { DataTable } from "../../../DataTable/DataTable";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import type { MRT_TableOptions } from "mantine-react-table";
|
|
||||||
import CategoryColumns from "../../../DataTable/columns/CategoryColumns";
|
import CategoryColumns from "../../../DataTable/columns/CategoryColumns";
|
||||||
import { Stack, Text } from "@mantine/core";
|
import { Stack, Text } from "@mantine/core";
|
||||||
import { textClasses } from "../../../styles";
|
import { textClasses } from "../../../styles";
|
||||||
@@ -13,34 +11,12 @@ const CategorySettings = () => {
|
|||||||
});
|
});
|
||||||
const [categoryData, setCategoryData] = useState<any>([]);
|
const [categoryData, setCategoryData] = useState<any>([]);
|
||||||
|
|
||||||
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
|
||||||
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
setCategoryData(data);
|
setCategoryData(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
exitCreatingMode,
|
|
||||||
}) => {
|
|
||||||
createRow({ method: "POST", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Category created successfully");
|
|
||||||
});
|
|
||||||
exitCreatingMode();
|
|
||||||
};
|
|
||||||
const handleEditRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
table,
|
|
||||||
}) => {
|
|
||||||
editRow({ method: "PATCH", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Category updated successfully");
|
|
||||||
});
|
|
||||||
table.setEditingRow(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -52,8 +28,7 @@ const CategorySettings = () => {
|
|||||||
tableData={categoryData}
|
tableData={categoryData}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onCreatingRowSave={handleCreateRow}
|
endpoint={endpoint}
|
||||||
onEditingRowSave={handleEditRow}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
import { useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import { DataTable } from "../../../DataTable/DataTable";
|
import { DataTable } from "../../../DataTable/DataTable";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import type { MRT_TableOptions } from "mantine-react-table";
|
|
||||||
import MessagesColumns from "../../../DataTable/columns/MessagesColumns";
|
import MessagesColumns from "../../../DataTable/columns/MessagesColumns";
|
||||||
import { Stack, Text } from "@mantine/core";
|
import { Stack, Text } from "@mantine/core";
|
||||||
import { textClasses } from "../../../styles";
|
import { textClasses } from "../../../styles";
|
||||||
@@ -13,34 +11,12 @@ const MessageSettings = () => {
|
|||||||
});
|
});
|
||||||
const [messageData, setMessageData] = useState<any>([]);
|
const [messageData, setMessageData] = useState<any>([]);
|
||||||
|
|
||||||
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
|
||||||
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
setMessageData(data);
|
setMessageData(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
exitCreatingMode,
|
|
||||||
}) => {
|
|
||||||
createRow({ method: "POST", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Message created successfully");
|
|
||||||
});
|
|
||||||
exitCreatingMode();
|
|
||||||
};
|
|
||||||
const handleEditRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
table,
|
|
||||||
}) => {
|
|
||||||
editRow({ method: "PATCH", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Message updated successfully");
|
|
||||||
});
|
|
||||||
table.setEditingRow(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -52,8 +28,7 @@ const MessageSettings = () => {
|
|||||||
tableData={messageData}
|
tableData={messageData}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onCreatingRowSave={handleCreateRow}
|
endpoint={endpoint}
|
||||||
onEditingRowSave={handleEditRow}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
import { useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import { DataTable } from "../../../DataTable/DataTable";
|
import { DataTable } from "../../../DataTable/DataTable";
|
||||||
import PersonalizationColumns from "../../../DataTable/columns/PersonalizationColumns";
|
import PersonalizationColumns from "../../../DataTable/columns/PersonalizationColumns";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import type { MRT_TableOptions } from "mantine-react-table";
|
|
||||||
import { textClasses } from "../../../styles";
|
import { textClasses } from "../../../styles";
|
||||||
import { Text } from "@mantine/core";
|
import { Text } from "@mantine/core";
|
||||||
const PersonalizationSettings = () => {
|
const PersonalizationSettings = () => {
|
||||||
@@ -13,34 +11,12 @@ const PersonalizationSettings = () => {
|
|||||||
});
|
});
|
||||||
const [personalData, setPersonalData] = useState<any>([]);
|
const [personalData, setPersonalData] = useState<any>([]);
|
||||||
|
|
||||||
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
|
||||||
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
setPersonalData(data);
|
setPersonalData(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
exitCreatingMode,
|
|
||||||
}) => {
|
|
||||||
createRow({ method: "POST", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Personalization created successfully");
|
|
||||||
});
|
|
||||||
exitCreatingMode();
|
|
||||||
};
|
|
||||||
const handleEditRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
table,
|
|
||||||
}) => {
|
|
||||||
editRow({ method: "PATCH", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Personalization updated successfully");
|
|
||||||
});
|
|
||||||
table.setEditingRow(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -52,8 +28,7 @@ const PersonalizationSettings = () => {
|
|||||||
tableData={personalData}
|
tableData={personalData}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onCreatingRowSave={handleCreateRow}
|
endpoint={endpoint}
|
||||||
onEditingRowSave={handleEditRow}
|
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
import { useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import { DataTable } from "../../../DataTable/DataTable";
|
import { DataTable } from "../../../DataTable/DataTable";
|
||||||
import { toast } from "react-toastify";
|
|
||||||
import type { MRT_TableOptions } from "mantine-react-table";
|
|
||||||
import SearchProviderColumns from "../../../DataTable/columns/SearchProviderColumns";
|
import SearchProviderColumns from "../../../DataTable/columns/SearchProviderColumns";
|
||||||
import { Stack, Text } from "@mantine/core";
|
import { Stack, Text } from "@mantine/core";
|
||||||
import { textClasses } from "../../../styles";
|
import { textClasses } from "../../../styles";
|
||||||
@@ -13,34 +11,12 @@ const SearchProviderSettings = () => {
|
|||||||
});
|
});
|
||||||
const [providerData, setProviderData] = useState<any>([]);
|
const [providerData, setProviderData] = useState<any>([]);
|
||||||
|
|
||||||
const { mutateAsync: createRow, isPending: isCreatingRow } = useMutationAPI();
|
|
||||||
const { mutateAsync: editRow, isPending: isEditingRow } = useMutationAPI();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
setProviderData(data);
|
setProviderData(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCreateRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
exitCreatingMode,
|
|
||||||
}) => {
|
|
||||||
createRow({ method: "POST", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Search provider created successfully");
|
|
||||||
});
|
|
||||||
exitCreatingMode();
|
|
||||||
};
|
|
||||||
const handleEditRow: MRT_TableOptions<any>["onCreatingRowSave"] = async ({
|
|
||||||
values,
|
|
||||||
table,
|
|
||||||
}) => {
|
|
||||||
editRow({ method: "PATCH", endpoint: endpoint, body: values }).then(() => {
|
|
||||||
toast.success("Search provider updated successfully");
|
|
||||||
});
|
|
||||||
table.setEditingRow(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
||||||
@@ -52,8 +28,7 @@ const SearchProviderSettings = () => {
|
|||||||
tableData={providerData}
|
tableData={providerData}
|
||||||
isFetching={isFetching}
|
isFetching={isFetching}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
onCreatingRowSave={handleCreateRow}
|
endpoint={endpoint}
|
||||||
onEditingRowSave={handleEditRow}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useQueryAPI } from "../../../hooks/useAPI";
|
import { useMutationAPI, useQueryAPI } from "../../../hooks/useAPI";
|
||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
Button,
|
Button,
|
||||||
@@ -7,22 +7,27 @@ import {
|
|||||||
ColorPicker,
|
ColorPicker,
|
||||||
ColorSwatch,
|
ColorSwatch,
|
||||||
Divider,
|
Divider,
|
||||||
|
Grid,
|
||||||
Group,
|
Group,
|
||||||
Modal,
|
Modal,
|
||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
|
TextInput,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { FiEdit } from "react-icons/fi";
|
import { FiEdit, FiPlus, FiSave, FiTrash, FiX } from "react-icons/fi";
|
||||||
import { useDisclosure, useLocalStorage } from "@mantine/hooks";
|
import { useDisclosure, useLocalStorage } from "@mantine/hooks";
|
||||||
import "@mantine/core/styles/ModalBase.css";
|
import "@mantine/core/styles/ModalBase.css";
|
||||||
import "@mantine/core/styles/Modal.css";
|
import "@mantine/core/styles/Modal.css";
|
||||||
import { actionIconClasses, modalClasses, textClasses } from "../../../styles";
|
import { actionIconClasses, modalClasses, textClasses } from "../../../styles";
|
||||||
import ThemeModalContent from "./ThemeModalContent";
|
import ThemeModalContent from "./ThemeModalContent";
|
||||||
|
import { modals } from "@mantine/modals";
|
||||||
function ThemesSettings({ theme }: any) {
|
function ThemesSettings({ theme }: any) {
|
||||||
const [opened, { open, close }] = useDisclosure(false);
|
const [opened, { open, close }] = useDisclosure(false);
|
||||||
const [pickerOpen, { open: openPicker, close: closePicker }] = useDisclosure(false);
|
const [pickerOpen, { open: openPicker, close: closePicker }] =
|
||||||
const [colorValue, onChange] = useState('#000000');
|
useDisclosure(false);
|
||||||
|
const [colorId, setColorId] = useState<string>("");
|
||||||
|
const [colorValue, setColorValue] = useState("#000000");
|
||||||
const [value, setValue] = useLocalStorage<any>({
|
const [value, setValue] = useLocalStorage<any>({
|
||||||
key: "theme",
|
key: "theme",
|
||||||
defaultValue: {},
|
defaultValue: {},
|
||||||
@@ -32,6 +37,10 @@ function ThemesSettings({ theme }: any) {
|
|||||||
});
|
});
|
||||||
const [themesList, setThemesList] = useState([]);
|
const [themesList, setThemesList] = useState([]);
|
||||||
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
const [selectedTheme, setSelectedTheme] = useState<any>({});
|
||||||
|
const { mutateAsync: createTheme, isPending: isCreatingTheme } =
|
||||||
|
useMutationAPI();
|
||||||
|
const { mutateAsync: deleteTheme, isPending: isDeletingTheme } =
|
||||||
|
useMutationAPI();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
setThemesList(data);
|
setThemesList(data);
|
||||||
@@ -43,10 +52,33 @@ function ThemesSettings({ theme }: any) {
|
|||||||
open();
|
open();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
close();
|
close();
|
||||||
closePicker();
|
closePicker();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSaveTheme = () => {
|
||||||
|
createTheme({
|
||||||
|
method: selectedTheme.id === undefined ? "POST" : "PATCH",
|
||||||
|
endpoint: "api/themes",
|
||||||
|
body: selectedTheme,
|
||||||
|
});
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
|
const openDeleteConfirmModal = (theme: any) =>
|
||||||
|
modals.openConfirmModal({
|
||||||
|
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 }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleDeleteTheme = (theme: any) => {
|
||||||
|
openDeleteConfirmModal(theme);
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -72,87 +104,247 @@ function ThemesSettings({ theme }: any) {
|
|||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body p={"2rem"}>
|
<Modal.Body p={"2rem"}>
|
||||||
<ThemeModalContent selectedTheme={selectedTheme} />
|
<ThemeModalContent selectedTheme={selectedTheme} />
|
||||||
<Divider color="black" my="sm" />
|
<Divider color="black" my="sm" />
|
||||||
<Group w={"100%"} h={"100%"} gap={0}>
|
<TextInput
|
||||||
<Stack w={"50%"}>
|
label="Theme Name"
|
||||||
<Group c={'black'} justify="space-between">
|
value={selectedTheme.name}
|
||||||
<Text>Primary Color</Text>
|
onChange={(e) =>
|
||||||
<ColorSwatch onClick={openPicker} radius={"sm"} w={"100px"} color={selectedTheme.colortextpri} />
|
setSelectedTheme({ ...selectedTheme, name: e.target.value })
|
||||||
</Group>
|
}
|
||||||
<Group c={'black'} justify="space-between">
|
styles={{
|
||||||
<Text>Accent Color</Text>
|
label: {
|
||||||
<ColorSwatch radius={"sm"} w={"100px"} color={selectedTheme.colortextacc} />
|
color: "black",
|
||||||
</Group>
|
},
|
||||||
<Group c={'black'} justify="space-between">
|
input: {
|
||||||
<Text>Background Color</Text>
|
color: "black",
|
||||||
<ColorSwatch radius={"sm"} w={"100px"} color={selectedTheme.colorbackground} />
|
backgroundColor: "white",
|
||||||
</Group>
|
},
|
||||||
<Group c={'black'} justify="space-between">
|
}}
|
||||||
<Text>Border Color</Text>
|
/>
|
||||||
<ColorSwatch radius={"sm"} w={"100px"} color={selectedTheme.colorborder} />
|
<Divider color="black" my="sm" />
|
||||||
</Group>
|
<Group w={"100%"} h={"100%"} gap={0}>
|
||||||
<Group c={'black'} justify="space-between">
|
<Stack w={"50%"}>
|
||||||
<Text>Search Background Color</Text>
|
<Group c={"black"} justify="space-between">
|
||||||
<ColorSwatch radius={"sm"} w={"100px"} color={selectedTheme.colorsearchbackground} />
|
<Text>Primary Color</Text>
|
||||||
</Group>
|
<ColorSwatch
|
||||||
</Stack>
|
onClick={() => {
|
||||||
<Stack h={"100%"} w={'50%'} align="center" justify="center">
|
setColorId("primary");
|
||||||
{pickerOpen ? (
|
openPicker();
|
||||||
<>
|
setColorValue(selectedTheme.colortextpri);
|
||||||
<ColorPicker value={colorValue} onChange={onChange}/>
|
}}
|
||||||
<Group><Text c={'black'}>{colorValue}</Text><Button onClick={() => {setSelectedTheme({ ...selectedTheme, colorbackground: colorValue }); closePicker();}} c={'white'} bg={'forestgreen'}>Save</Button></Group>
|
radius={"sm"}
|
||||||
</>
|
w={"100px"}
|
||||||
) : (
|
color={selectedTheme.colortextpri}
|
||||||
<Card bg={'#0002'} h={"100%"} w={"90%"}>
|
style={{ cursor: "pointer" }}
|
||||||
<Text c="black">
|
/>
|
||||||
Pick a swatch to edit the color.
|
</Group>
|
||||||
</Text>
|
<Group c={"black"} justify="space-between">
|
||||||
</Card>
|
<Text>Accent Color</Text>
|
||||||
)}
|
<ColorSwatch
|
||||||
</Stack>
|
onClick={() => {
|
||||||
</Group>
|
setColorId("accent");
|
||||||
|
openPicker();
|
||||||
|
setColorValue(selectedTheme.colortextacc);
|
||||||
|
}}
|
||||||
|
radius={"sm"}
|
||||||
|
w={"100px"}
|
||||||
|
color={selectedTheme.colortextacc}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
<Group c={"black"} justify="space-between">
|
||||||
|
<Text>Background Color</Text>
|
||||||
|
<ColorSwatch
|
||||||
|
onClick={() => {
|
||||||
|
setColorId("background");
|
||||||
|
openPicker();
|
||||||
|
setColorValue(selectedTheme.colorbackground);
|
||||||
|
}}
|
||||||
|
radius={"sm"}
|
||||||
|
w={"100px"}
|
||||||
|
color={selectedTheme.colorbackground}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
<Group c={"black"} justify="space-between">
|
||||||
|
<Text>Border Color</Text>
|
||||||
|
<ColorSwatch
|
||||||
|
onClick={() => {
|
||||||
|
setColorId("border");
|
||||||
|
openPicker();
|
||||||
|
setColorValue(selectedTheme.colorborder);
|
||||||
|
}}
|
||||||
|
radius={"sm"}
|
||||||
|
w={"100px"}
|
||||||
|
color={selectedTheme.colorborder}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
<Group c={"black"} justify="space-between">
|
||||||
|
<Text>Search Background Color</Text>
|
||||||
|
<ColorSwatch
|
||||||
|
onClick={() => {
|
||||||
|
setColorId("searchbackground");
|
||||||
|
openPicker();
|
||||||
|
setColorValue(selectedTheme.colorsearchbackground);
|
||||||
|
}}
|
||||||
|
radius={"sm"}
|
||||||
|
w={"100px"}
|
||||||
|
color={selectedTheme.colorsearchbackground}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
<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>
|
||||||
|
<Button
|
||||||
|
color={"green"}
|
||||||
|
onClick={() => {
|
||||||
|
switch (colorId) {
|
||||||
|
case "primary":
|
||||||
|
setSelectedTheme({
|
||||||
|
...selectedTheme,
|
||||||
|
colortextpri: colorValue,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "accent":
|
||||||
|
setSelectedTheme({
|
||||||
|
...selectedTheme,
|
||||||
|
colortextacc: colorValue,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "background":
|
||||||
|
setSelectedTheme({
|
||||||
|
...selectedTheme,
|
||||||
|
colorbackground: colorValue,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "border":
|
||||||
|
setSelectedTheme({
|
||||||
|
...selectedTheme,
|
||||||
|
colorborder: colorValue,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "searchbackground":
|
||||||
|
setSelectedTheme({
|
||||||
|
...selectedTheme,
|
||||||
|
colorsearchbackground: colorValue,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
closePicker();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FiSave />
|
||||||
|
</Button>
|
||||||
|
<Button color={"red"} onClick={closePicker}>
|
||||||
|
<FiX />
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Card
|
||||||
|
bg={"#0002"}
|
||||||
|
h={"100%"}
|
||||||
|
w={"90%"}
|
||||||
|
style={{ alignItems: "center" }}
|
||||||
|
>
|
||||||
|
<Text c="black">Pick a swatch to edit the color.</Text>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
<Divider color="black" my="sm" />
|
||||||
|
<Group>
|
||||||
|
<Button color={"green"} onClick={handleSaveTheme}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
<Button color={"red"} onClick={close}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
</Modal.Content>
|
</Modal.Content>
|
||||||
</Modal.Root>
|
</Modal.Root>
|
||||||
<Stack h={"100%"} w={"100%"}>
|
<Stack h={"100%"} w={"100%"}>
|
||||||
<Text className={textClasses.settingsSubTitle} classNames={textClasses}>
|
<Group>
|
||||||
Themes
|
<Text
|
||||||
</Text>
|
className={textClasses.settingsSubTitle}
|
||||||
<SimpleGrid cols={5}>
|
classNames={textClasses}
|
||||||
|
>
|
||||||
|
Themes
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedTheme({
|
||||||
|
id: undefined,
|
||||||
|
name: "default",
|
||||||
|
imagebackground: "none",
|
||||||
|
colorbackground: "#EEEEEE",
|
||||||
|
colorsearchbackground: "#00000033",
|
||||||
|
colortextpri: "#222222",
|
||||||
|
colortextacc: "#5c5c5c",
|
||||||
|
colorborder: "#5c5c5c",
|
||||||
|
});
|
||||||
|
open();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FiPlus />
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
<Group justify="center">
|
||||||
{themesList.map((theme: any) => (
|
{themesList.map((theme: any) => (
|
||||||
<Stack key={theme.name}>
|
<Stack key={theme.name} w={"300px"}>
|
||||||
<Button
|
<Group gap={0} justify="space-between">
|
||||||
style={{
|
<Button
|
||||||
backgroundColor: theme.colorbackground,
|
w={"100%"}
|
||||||
border: `solid ${theme.colorborder}`,
|
h={"75px"}
|
||||||
color: theme.colortextpri,
|
style={{
|
||||||
}}
|
backgroundColor: theme.colorbackground,
|
||||||
data-theme={theme.name}
|
border: `solid ${theme.colorborder}`,
|
||||||
onClick={() => {
|
color: theme.colortextpri,
|
||||||
setValue(theme.name);
|
}}
|
||||||
}}
|
data-theme={theme.name}
|
||||||
>
|
onClick={() => {
|
||||||
{theme.name}
|
setValue(theme.name);
|
||||||
</Button>
|
}}
|
||||||
<Group justify="space-between">
|
>
|
||||||
|
{theme.name}
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
<Group justify="space-between" gap={0}>
|
||||||
<Group className="theme-palette">
|
<Group className="theme-palette">
|
||||||
|
<ActionIcon
|
||||||
|
className={actionIconClasses.editButton}
|
||||||
|
classNames={actionIconClasses}
|
||||||
|
onClick={() => handleOpen(theme)}
|
||||||
|
>
|
||||||
|
<FiEdit />
|
||||||
|
</ActionIcon>
|
||||||
<ColorSwatch color={theme.colorbackground} />
|
<ColorSwatch color={theme.colorbackground} />
|
||||||
<ColorSwatch color={theme.colorsearchbackground} />
|
<ColorSwatch color={theme.colorsearchbackground} />
|
||||||
<ColorSwatch color={theme.colortextpri} />
|
<ColorSwatch color={theme.colortextpri} />
|
||||||
<ColorSwatch color={theme.colortextacc} />
|
<ColorSwatch color={theme.colortextacc} />
|
||||||
<ColorSwatch color={theme.colorborder} />
|
<ColorSwatch color={theme.colorborder} />
|
||||||
|
|
||||||
|
<ActionIcon
|
||||||
|
className={actionIconClasses.editButton}
|
||||||
|
classNames={actionIconClasses}
|
||||||
|
onClick={() => handleDeleteTheme(theme)}
|
||||||
|
>
|
||||||
|
<FiTrash color="red" />
|
||||||
|
</ActionIcon>
|
||||||
</Group>
|
</Group>
|
||||||
<ActionIcon
|
|
||||||
className={actionIconClasses.editButton}
|
|
||||||
classNames={actionIconClasses}
|
|
||||||
onClick={() => handleOpen(theme)}
|
|
||||||
>
|
|
||||||
<FiEdit />
|
|
||||||
</ActionIcon>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
))}
|
))}
|
||||||
</SimpleGrid>
|
</Group>
|
||||||
</Stack>
|
</Stack>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -18,10 +18,11 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.section{
|
.section{
|
||||||
|
transition: opacity 0.1s 0s ease;
|
||||||
color: var(--color-border);
|
color: var(--color-border);
|
||||||
width: auto;
|
width: auto;
|
||||||
padding-left: .5rem;
|
padding-left: .5rem;
|
||||||
display: none;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.wrapper:focus-within {
|
.wrapper:focus-within {
|
||||||
@@ -41,10 +42,11 @@
|
|||||||
border-bottom-right-radius: .25em;
|
border-bottom-right-radius: .25em;
|
||||||
}
|
}
|
||||||
.section{
|
.section{
|
||||||
|
transition: opacity 0.4s 0.4s ease;
|
||||||
color: var(--color-border);
|
color: var(--color-border);
|
||||||
width: auto;
|
width: auto;
|
||||||
padding-left: .5rem;
|
padding-left: .5rem;
|
||||||
display: flex;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user