Merge pull request 'add coporate theme color variables' (#419) from feat/theme into main
@ -11,9 +11,10 @@
|
||||
treefmt.flakeFormatter = true;
|
||||
treefmt.programs.shellcheck.enable = true;
|
||||
treefmt.programs.prettier.enable = true;
|
||||
treefmt.programs.prettier.settings.plugins = [
|
||||
"${self'.packages.prettier-plugin-tailwindcss}/lib/node_modules/prettier-plugin-tailwindcss/dist/index.mjs"
|
||||
];
|
||||
# TODO: add custom prettier package, that uses our ui/node_modules
|
||||
# treefmt.programs.prettier.settings.plugins = [
|
||||
# "${self'.packages.prettier-plugin-tailwindcss}/lib/node_modules/prettier-plugin-tailwindcss/dist/index.mjs"
|
||||
# ];
|
||||
treefmt.settings.formatter.prettier.excludes = [
|
||||
"secrets.yaml"
|
||||
"key.json"
|
||||
|
@ -20,29 +20,30 @@ export const config: PaletteConfig = {
|
||||
* Steps are defined in 'tones'
|
||||
*/
|
||||
baseColors: {
|
||||
neutral: {
|
||||
keyColor: "#92898a",
|
||||
tones: [2, 5, 8, 92, 95, 98],
|
||||
},
|
||||
green: {
|
||||
keyColor: "#7AC51B",
|
||||
tones: [98],
|
||||
tones: [2, 98],
|
||||
},
|
||||
yellow: {
|
||||
keyColor: "#E0E01F",
|
||||
tones: [2, 98],
|
||||
},
|
||||
purple: {
|
||||
keyColor: "#661bc5",
|
||||
tones: [],
|
||||
},
|
||||
neutral: {
|
||||
keyColor: "#807788",
|
||||
tones: [2, 5, 8, 98],
|
||||
tones: [2, 98],
|
||||
},
|
||||
|
||||
red: {
|
||||
keyColor: "#e82439",
|
||||
tones: [95],
|
||||
},
|
||||
yellow: {
|
||||
keyColor: "#E0E01F",
|
||||
tones: [98],
|
||||
},
|
||||
blue: {
|
||||
keyColor: "#1B7AC5",
|
||||
tones: [95],
|
||||
tones: [5, 95],
|
||||
},
|
||||
},
|
||||
|
||||
|
7823
pkgs/ui/public/cLAN/cLAN.ai
Normal file
7121
pkgs/ui/public/cLAN/cLAN.svg
Normal file
After Width: | Height: | Size: 689 KiB |
BIN
pkgs/ui/public/cLAN/logo-black.jpg
Normal file
After Width: | Height: | Size: 266 KiB |
BIN
pkgs/ui/public/cLAN/logo-black.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
pkgs/ui/public/cLAN/logo-color.png
Normal file
After Width: | Height: | Size: 149 KiB |
BIN
pkgs/ui/public/cLAN/logo-white.png
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
pkgs/ui/public/cLAN/no_text_black/128x128.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
pkgs/ui/public/cLAN/no_text_black/16x16.png
Normal file
After Width: | Height: | Size: 360 B |
BIN
pkgs/ui/public/cLAN/no_text_black/32x32.png
Normal file
After Width: | Height: | Size: 815 B |
BIN
pkgs/ui/public/cLAN/no_text_black/64x64.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
pkgs/ui/public/cLAN/no_text_color/128x128.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
pkgs/ui/public/cLAN/no_text_color/16x16.png
Normal file
After Width: | Height: | Size: 490 B |
BIN
pkgs/ui/public/cLAN/no_text_color/32x32.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
pkgs/ui/public/cLAN/no_text_color/64x64.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
pkgs/ui/public/cLAN/no_text_white/128x128.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
pkgs/ui/public/cLAN/no_text_white/16x16.png
Normal file
After Width: | Height: | Size: 375 B |
BIN
pkgs/ui/public/cLAN/no_text_white/32x32.png
Normal file
After Width: | Height: | Size: 717 B |
BIN
pkgs/ui/public/cLAN/no_text_white/64x64.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
pkgs/ui/public/cLAN/text_color/128x128.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
pkgs/ui/public/cLAN/text_color/16x16.png
Normal file
After Width: | Height: | Size: 555 B |
BIN
pkgs/ui/public/cLAN/text_color/32x32.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
pkgs/ui/public/cLAN/text_color/64x64.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
pkgs/ui/public/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
pkgs/ui/public/favicon.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
pkgs/ui/public/logo.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 14 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
Before Width: | Height: | Size: 629 B |
@ -14,7 +14,7 @@ pkgs.mkShell {
|
||||
mkdir -p .floco
|
||||
if [[ "$ID" != "$currID" || ! -d "node_modules" ]];
|
||||
then
|
||||
${pkgs.rsync}/bin/rsync -a --chmod=ug+w --delete ${pkg.built.tree}/node_modules/ ./node_modules/
|
||||
${pkgs.rsync}/bin/rsync -a --checksum --chmod=ug+w --delete ${pkg.built.tree}/node_modules/ ./node_modules/
|
||||
echo -n $ID > .floco/.node_modules_id
|
||||
echo "floco ok: node_modules updated"
|
||||
fi
|
||||
|
@ -1,33 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import "./globals.css";
|
||||
import localFont from "next/font/local";
|
||||
import * as React from "react";
|
||||
import { Sidebar } from "@/components/sidebar";
|
||||
import { tw } from "@/utils/tailwind";
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import {
|
||||
Button,
|
||||
CssBaseline,
|
||||
IconButton,
|
||||
ThemeProvider,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { StyledEngineProvider } from "@mui/material/styles";
|
||||
|
||||
import { darkTheme, lightTheme } from "./theme/themes";
|
||||
import { Sidebar } from "@/components/sidebar";
|
||||
import MenuIcon from "@mui/icons-material/Menu";
|
||||
import Image from "next/image";
|
||||
import { tw } from "@/utils/tailwind";
|
||||
import axios from "axios";
|
||||
import localFont from "next/font/local";
|
||||
import Image from "next/image";
|
||||
import * as React from "react";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import "./globals.css";
|
||||
import { darkTheme, lightTheme } from "./theme/themes";
|
||||
|
||||
import {
|
||||
AppContext,
|
||||
WithAppState,
|
||||
// useAppState,
|
||||
} from "@/components/hooks/useAppContext";
|
||||
import Background from "@/components/background";
|
||||
import { AppContext, WithAppState } from "@/components/hooks/useAppContext";
|
||||
// import { usePathname, redirect } from "next/navigation";
|
||||
|
||||
const roboto = localFont({
|
||||
@ -62,27 +54,27 @@ export default function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const userPrefersDarkmode = useMediaQuery("(prefers-color-scheme: dark)");
|
||||
const theme = useTheme();
|
||||
const is_small = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
|
||||
let [useDarkTheme, setUseDarkTheme] = useState(false);
|
||||
let [showSidebar, setShowSidebar] = useState(true);
|
||||
// const theme = useTheme({});
|
||||
// const is_small = useMediaQuery(theme.breakpoints.down("sm"));
|
||||
// const [useDarkTheme, setUseDarkTheme] = useState(false);
|
||||
const [showSidebar, setShowSidebar] = React.useState(true);
|
||||
|
||||
// If the screen is small, hide the sidebar
|
||||
React.useEffect(() => {
|
||||
if (is_small) {
|
||||
setShowSidebar(false);
|
||||
} else {
|
||||
setShowSidebar(true);
|
||||
}
|
||||
}, [is_small]);
|
||||
// useEffect(() => {
|
||||
// if (is_small) {
|
||||
// setShowSidebar(false);
|
||||
// } else {
|
||||
// setShowSidebar(true);
|
||||
// }
|
||||
// }, [is_small]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (useDarkTheme !== userPrefersDarkmode) {
|
||||
// Enable dark theme if the user prefers dark mode
|
||||
setUseDarkTheme(userPrefersDarkmode);
|
||||
}
|
||||
}, [userPrefersDarkmode, useDarkTheme, setUseDarkTheme]);
|
||||
// useEffect(() => {
|
||||
// if (useDarkTheme !== userPrefersDarkmode) {
|
||||
// // Enable dark theme if the user prefers dark mode
|
||||
// setUseDarkTheme(userPrefersDarkmode);
|
||||
// }
|
||||
// }, [userPrefersDarkmode, useDarkTheme, setUseDarkTheme]);
|
||||
|
||||
// const changeThemeHandler = (target: ChangeEvent, currentValue: boolean) => {
|
||||
// setUseDarkTheme(currentValue);
|
||||
@ -97,7 +89,7 @@ export default function RootLayout({
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<StyledEngineProvider injectFirst>
|
||||
<ThemeProvider theme={useDarkTheme ? darkTheme : lightTheme}>
|
||||
<ThemeProvider theme={userPrefersDarkmode ? darkTheme : lightTheme}>
|
||||
<body id="__next" className={roboto.className}>
|
||||
<CssBaseline />
|
||||
<Toaster />
|
||||
@ -134,9 +126,9 @@ export default function RootLayout({
|
||||
)}
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="col-span-1 block w-full bg-fixed text-center font-semibold text-white lg:hidden">
|
||||
<div className="col-span-1 block w-full bg-fixed text-center font-semibold dark:invert lg:hidden">
|
||||
<Image
|
||||
src="/logo.svg"
|
||||
src="/favicon.png"
|
||||
alt="Clan Logo"
|
||||
width={58}
|
||||
height={58}
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { StrictMode } from "react";
|
||||
import { NodeTable } from "@/components/table";
|
||||
import { StrictMode } from "react";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
|
@ -1,41 +1,39 @@
|
||||
"use client";
|
||||
import { NetworkOverview } from "@/components/dashboard/NetworkOverview";
|
||||
import { RecentActivity } from "@/components/dashboard/activity";
|
||||
import { AppOverview } from "@/components/dashboard/appOverview";
|
||||
import { NetworkOverview } from "@/components/dashboard/NetworkOverview";
|
||||
import { Notifications } from "@/components/dashboard/notifications";
|
||||
import { QuickActions } from "@/components/dashboard/quickActions";
|
||||
import { TaskQueue } from "@/components/dashboard/taskQueue";
|
||||
import { useAppState } from "@/components/hooks/useAppContext";
|
||||
import { MachineContextProvider } from "@/components/hooks/useMachines";
|
||||
import { LoadingOverlay } from "@/components/join/loadingOverlay";
|
||||
import { tw } from "@/utils/tailwind";
|
||||
import JoinPrequel from "@/views/joinPrequel";
|
||||
|
||||
interface DashboardCardProps {
|
||||
children?: React.ReactNode;
|
||||
rowSpan?: number;
|
||||
sx?: string;
|
||||
}
|
||||
const DashboardCard = (props: DashboardCardProps) => {
|
||||
const { children, rowSpan, sx = "" } = props;
|
||||
return (
|
||||
<div
|
||||
className={tw`col-span-full row-span-${rowSpan || 1} xl:col-span-1 ${sx}`}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
// interface DashboardCardProps {
|
||||
// children?: React.ReactNode;
|
||||
// rowSpan?: number;
|
||||
// sx?: string;
|
||||
// }
|
||||
// const DashboardCard = (props: DashboardCardProps) => {
|
||||
// const { children, rowSpan, sx = "" } = props;
|
||||
// return (
|
||||
// // <div className={tw`col-span-full row-span-${rowSpan} 2xl:col-span-1 ${sx}`}>
|
||||
// <div className={tw`row-span-2`}>
|
||||
// {children}
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
interface DashboardPanelProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
const DashboardPanel = (props: DashboardPanelProps) => {
|
||||
const { children } = props;
|
||||
return (
|
||||
<div className="col-span-full row-span-1 xl:col-span-2">{children}</div>
|
||||
);
|
||||
};
|
||||
// interface DashboardPanelProps {
|
||||
// children?: React.ReactNode;
|
||||
// }
|
||||
// const DashboardPanel = (props: DashboardPanelProps) => {
|
||||
// const { children } = props;
|
||||
// return (
|
||||
// <div className="col-span-full row-span-1 2xl:col-span-2">{children}</div>
|
||||
// );
|
||||
// };
|
||||
|
||||
export default function Dashboard() {
|
||||
const { data, isLoading } = useAppState();
|
||||
@ -58,26 +56,20 @@ export default function Dashboard() {
|
||||
if (data.isJoined) {
|
||||
return (
|
||||
<MachineContextProvider>
|
||||
<div className="flex h-screen w-full">
|
||||
<div className="grid w-full auto-rows-max grid-cols-1 grid-rows-none gap-4 xl:grid-cols-2 2xl:grid-cols-3 ">
|
||||
<DashboardCard rowSpan={2}>
|
||||
<div className="flex w-full">
|
||||
<div className="grid w-full grid-flow-row grid-cols-3 gap-4">
|
||||
<div className="row-span-2">
|
||||
<NetworkOverview />
|
||||
</DashboardCard>
|
||||
<DashboardCard rowSpan={2}>
|
||||
<RecentActivity />
|
||||
</DashboardCard>
|
||||
<DashboardCard>
|
||||
<Notifications />
|
||||
</DashboardCard>
|
||||
<DashboardCard>
|
||||
<QuickActions />
|
||||
</DashboardCard>
|
||||
<DashboardPanel>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<AppOverview />
|
||||
</DashboardPanel>
|
||||
<DashboardCard sx={tw`xl:col-span-full 2xl:col-span-1`}>
|
||||
<TaskQueue />
|
||||
</DashboardCard>
|
||||
</div>
|
||||
<div className="row-span-2">
|
||||
<RecentActivity />
|
||||
</div>
|
||||
<QuickActions />
|
||||
<Notifications />
|
||||
<TaskQueue />
|
||||
</div>
|
||||
</div>
|
||||
</MachineContextProvider>
|
||||
|
@ -67,12 +67,12 @@ export default function TemplateDetail({ params }: TemplateDetailProps) {
|
||||
Back
|
||||
</Button>
|
||||
</div>
|
||||
<div className="h-full w-full border border-solid border-slate-100 bg-slate-50 shadow-sm shadow-slate-400">
|
||||
<div className="h-full w-full border border-solid border-neutral-90 bg-neutral-98 shadow-sm shadow-neutral-60 dark:bg-paper-dark">
|
||||
<div className="flex w-full flex-col items-center justify-center xl:p-2">
|
||||
<Avatar className="m-1 h-20 w-20 bg-violet-600">
|
||||
<Avatar className="m-1 h-20 w-20 bg-purple-40">
|
||||
<Typography variant="h5">N</Typography>
|
||||
</Avatar>
|
||||
<Typography variant="h6" className="text-violet-600">
|
||||
<Typography variant="h6" className="text-purple-40">
|
||||
{details.short}
|
||||
</Typography>
|
||||
<div className="w-full">
|
||||
@ -159,12 +159,12 @@ export default function TemplateDetail({ params }: TemplateDetailProps) {
|
||||
<div className="mt-2 flex w-full justify-evenly">
|
||||
<Button
|
||||
variant="text"
|
||||
className="w-full text-black"
|
||||
className="w-full text-black dark:text-white"
|
||||
startIcon={<Edit />}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button className="w-full text-red-700" startIcon={<Delete />}>
|
||||
<Button className="w-full text-red" startIcon={<Delete />}>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@ export default function ImageOverview() {
|
||||
<ListItem key={id}>
|
||||
<ListItemButton LinkComponent={"a"} href={`/templates/${id}`}>
|
||||
<ListItemAvatar>
|
||||
<Avatar className="bg-violet-600">{name.slice(0, 1)}</Avatar>
|
||||
<Avatar className="bg-purple-40">{name.slice(0, 1)}</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={name} secondary={date} />
|
||||
<ListItemSecondaryAction>
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { ThemeOptions, createTheme } from "@mui/material/styles";
|
||||
import {
|
||||
PaletteOptions,
|
||||
ThemeOptions,
|
||||
createTheme,
|
||||
} from "@mui/material/styles";
|
||||
|
||||
import colors from "@clan/colors/colors.json";
|
||||
const { palette, common } = colors.ref;
|
||||
@ -15,31 +19,39 @@ const commonOptions: Partial<ThemeOptions> = {
|
||||
},
|
||||
};
|
||||
|
||||
const commonPalette: Partial<PaletteOptions> = {
|
||||
primary: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
secondary: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
info: {
|
||||
main: palette.blue50.value,
|
||||
},
|
||||
success: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
warning: {
|
||||
main: palette.yellow50.value,
|
||||
},
|
||||
error: {
|
||||
main: palette.red50.value,
|
||||
},
|
||||
};
|
||||
|
||||
export const darkTheme = createTheme({
|
||||
...commonOptions,
|
||||
palette: {
|
||||
mode: "dark",
|
||||
...commonPalette,
|
||||
background: {
|
||||
default: palette.neutral5.value,
|
||||
paper: palette.neutral20.value,
|
||||
default: palette.neutral2.value,
|
||||
paper: palette.neutral5.value,
|
||||
},
|
||||
primary: {
|
||||
main: palette.green60.value,
|
||||
},
|
||||
secondary: {
|
||||
main: palette.green60.value,
|
||||
},
|
||||
error: {
|
||||
main: palette.red60.value,
|
||||
},
|
||||
warning: {
|
||||
main: palette.yellow60.value,
|
||||
},
|
||||
success: {
|
||||
main: palette.green60.value,
|
||||
},
|
||||
info: {
|
||||
main: palette.red60.value,
|
||||
common: {
|
||||
black: common.black.value,
|
||||
white: common.white.value,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -48,27 +60,10 @@ export const lightTheme = createTheme({
|
||||
...commonOptions,
|
||||
palette: {
|
||||
mode: "light",
|
||||
...commonPalette,
|
||||
background: {
|
||||
default: common.white.value,
|
||||
paper: palette.neutral98.value,
|
||||
},
|
||||
primary: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
secondary: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
error: {
|
||||
main: palette.red50.value,
|
||||
},
|
||||
warning: {
|
||||
main: palette.yellow50.value,
|
||||
},
|
||||
success: {
|
||||
main: palette.green50.value,
|
||||
},
|
||||
info: {
|
||||
main: palette.red50.value,
|
||||
default: palette.neutral98.value,
|
||||
paper: palette.neutral100.value,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,6 +1,8 @@
|
||||
import Image from "next/image";
|
||||
import clanLight from "../../public/clan-dark.png";
|
||||
import clanDark from "../../public/clan-dark.png";
|
||||
import {
|
||||
default as clanDark,
|
||||
default as clanLight,
|
||||
} from "../../public/clan-dark.png";
|
||||
import { useAppState } from "./hooks/useAppContext";
|
||||
|
||||
export default function Background() {
|
||||
|
@ -8,7 +8,11 @@ interface DashboardCardProps {
|
||||
const DashboardCard = (props: DashboardCardProps) => {
|
||||
const { children, title } = props;
|
||||
return (
|
||||
<div className="h-full w-full border border-solid border-slate-100 bg-slate-50 shadow-sm shadow-slate-400">
|
||||
<div
|
||||
className="h-full w-full
|
||||
border border-solid border-neutral-80 bg-neutral-98
|
||||
shadow-sm shadow-neutral-60 dark:border-none dark:bg-neutral-5 dark:shadow-none"
|
||||
>
|
||||
<div className="h-full w-full px-3 py-2">
|
||||
<Typography variant="h6" color={"secondary"}>
|
||||
{title}
|
||||
|
@ -14,11 +14,6 @@ import {
|
||||
} from "@mui/material";
|
||||
import { IChangeEvent } from "@rjsf/core";
|
||||
import { Form } from "@rjsf/mui";
|
||||
import validator from "@rjsf/validator-ajv8";
|
||||
import toast from "react-hot-toast";
|
||||
import { JSONSchema7 } from "json-schema";
|
||||
import { useMemo, useRef } from "react";
|
||||
import { FormStepContentProps } from "./interfaces";
|
||||
import {
|
||||
ErrorListProps,
|
||||
FormContextType,
|
||||
@ -26,6 +21,11 @@ import {
|
||||
StrictRJSFSchema,
|
||||
TranslatableString,
|
||||
} from "@rjsf/utils";
|
||||
import validator from "@rjsf/validator-ajv8";
|
||||
import { JSONSchema7 } from "json-schema";
|
||||
import { useMemo, useRef } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { FormStepContentProps } from "./interfaces";
|
||||
|
||||
interface PureCustomConfigProps extends FormStepContentProps {
|
||||
schema: JSONSchema7;
|
||||
@ -34,6 +34,18 @@ interface PureCustomConfigProps extends FormStepContentProps {
|
||||
export function CustomConfig(props: FormStepContentProps) {
|
||||
const { formHooks } = props;
|
||||
const { data, isLoading, error } = useGetMachineSchema("mama");
|
||||
// const { data, isLoading, error } = { data: {data:{schema: {
|
||||
// title: 'Test form',
|
||||
// type: 'object',
|
||||
// properties: {
|
||||
// name: {
|
||||
// type: 'string',
|
||||
// },
|
||||
// age: {
|
||||
// type: 'number',
|
||||
// },
|
||||
// },
|
||||
// }}}, isLoading: false, error: undefined }
|
||||
const schema = useMemo(() => {
|
||||
if (!isLoading && !error?.message && data?.data) {
|
||||
return data?.data.schema;
|
||||
|
@ -4,7 +4,7 @@ import { NoDataOverlay } from "@/components/noDataOverlay";
|
||||
export const RecentActivity = () => {
|
||||
return (
|
||||
<DashboardCard title="Recent Activity">
|
||||
<div className="flex h-full w-full justify-center align-middle">
|
||||
<div className="flex w-full justify-center align-middle">
|
||||
<NoDataOverlay label="No Activity yet" />
|
||||
</div>
|
||||
</DashboardCard>
|
||||
|
@ -13,10 +13,12 @@ const AppCard = (props: AppCardProps) => {
|
||||
<div
|
||||
role="button"
|
||||
className="flex h-40 w-40 cursor-pointer items-center justify-center rounded-3xl p-2
|
||||
align-middle shadow-md ring-2 ring-inset ring-violet-500 hover:bg-slate-200 focus:bg-slate-200 active:bg-slate-300"
|
||||
align-middle shadow-md ring-2 ring-inset ring-purple-50
|
||||
hover:bg-neutral-90 focus:bg-neutral-90 active:bg-neutral-80
|
||||
dark:hover:bg-neutral-10 dark:focus:bg-neutral-10 dark:active:bg-neutral-20"
|
||||
>
|
||||
<div className="flex w-full flex-col justify-center">
|
||||
<div className="my-1 flex h-[22] w-[22] items-center justify-center self-center overflow-visible p-1">
|
||||
<div className="my-1 flex h-[22] w-[22] items-center justify-center self-center overflow-visible p-1 dark:invert">
|
||||
<Image
|
||||
src={iconPath}
|
||||
alt={`${name}-app-icon`}
|
||||
|
@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
import { DashboardCard } from "@/components/card";
|
||||
import { Fab } from "@mui/material";
|
||||
import { Fab, Typography } from "@mui/material";
|
||||
import { MouseEventHandler, ReactNode } from "react";
|
||||
|
||||
import LanIcon from "@mui/icons-material/Lan";
|
||||
import AppsIcon from "@mui/icons-material/Apps";
|
||||
import DevicesIcon from "@mui/icons-material/Devices";
|
||||
import LanIcon from "@mui/icons-material/Lan";
|
||||
|
||||
type Action = {
|
||||
id: string;
|
||||
@ -43,7 +43,7 @@ export const QuickActions = () => {
|
||||
];
|
||||
return (
|
||||
<DashboardCard title="Quick Actions">
|
||||
<div className="flex h-fit w-full items-center justify-start pt-5 align-bottom">
|
||||
<div className="flex h-full w-full items-center justify-start pb-10 align-bottom">
|
||||
<div className="flex w-full flex-col flex-wrap justify-evenly gap-2 sm:flex-row">
|
||||
{actions.map(({ id, icon, label, eventHandler }) => (
|
||||
<Fab
|
||||
@ -54,7 +54,7 @@ export const QuickActions = () => {
|
||||
variant="extended"
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
<Typography>{label}</Typography>
|
||||
</Fab>
|
||||
))}
|
||||
</div>
|
||||
|
@ -1,11 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { useListMachines } from "@/api/default/default";
|
||||
import { Machine, MachinesResponse } from "@/api/model";
|
||||
import { AxiosError, AxiosResponse } from "axios";
|
||||
import React, {
|
||||
createContext,
|
||||
Dispatch,
|
||||
ReactNode,
|
||||
SetStateAction,
|
||||
createContext,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
|
@ -6,8 +6,8 @@ interface LogOptions {
|
||||
export const Log = (props: LogOptions) => {
|
||||
const { lines, title } = props;
|
||||
return (
|
||||
<div className="max-h-[70vh] min-h-[9rem] w-full overflow-scroll bg-slate-800 p-4 text-white shadow-inner shadow-black">
|
||||
<div className="mb-1 text-slate-400">{title}</div>
|
||||
<div className="max-h-[70vh] min-h-[9rem] w-full overflow-scroll bg-neutral-20 p-4 text-white shadow-inner shadow-black">
|
||||
<div className="mb-1 text-neutral-70">{title}</div>
|
||||
<pre className="max-w-[90vw] text-xs">
|
||||
{lines.map((item, idx) => (
|
||||
<code key={`${idx}`} className="mb-2 block break-words">
|
||||
|
@ -10,17 +10,16 @@ import {
|
||||
import Image from "next/image";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
import { tw } from "@/utils/tailwind";
|
||||
import AppsIcon from "@mui/icons-material/Apps";
|
||||
import BackupIcon from "@mui/icons-material/Backup";
|
||||
import DashboardIcon from "@mui/icons-material/Dashboard";
|
||||
import DesignServicesIcon from "@mui/icons-material/DesignServices";
|
||||
import DevicesIcon from "@mui/icons-material/Devices";
|
||||
import LanIcon from "@mui/icons-material/Lan";
|
||||
import AppsIcon from "@mui/icons-material/Apps";
|
||||
import DesignServicesIcon from "@mui/icons-material/DesignServices";
|
||||
import BackupIcon from "@mui/icons-material/Backup";
|
||||
import Link from "next/link";
|
||||
import { tw } from "@/utils/tailwind";
|
||||
|
||||
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
|
||||
import React from "react";
|
||||
|
||||
type MenuEntry = {
|
||||
icon: ReactNode;
|
||||
@ -84,22 +83,22 @@ export function Sidebar(props: SidebarProps) {
|
||||
<aside
|
||||
className={tw`${
|
||||
show ? showSidebar : hideSidebar
|
||||
} z-9999 dark:bg-boxdark static left-0 top-0 flex h-screen w-14 flex-col overflow-x-hidden overflow-y-hidden bg-zinc-950 transition duration-150 ease-in-out lg:w-64`}
|
||||
} z-9999 static left-0 top-0 flex h-screen w-14 flex-col overflow-x-hidden overflow-y-hidden bg-neutral-10 transition duration-150 ease-in-out dark:bg-neutral-2 lg:w-64`}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-2 overflow-hidden px-0 py-5 lg:p-6">
|
||||
<div className="mt-8 hidden w-full text-center font-semibold text-white lg:block">
|
||||
<Image
|
||||
src="/logo.svg"
|
||||
src="/logo.png"
|
||||
alt="Clan Logo"
|
||||
width={58}
|
||||
height={58}
|
||||
width={75}
|
||||
height={75}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Divider
|
||||
flexItem
|
||||
className="mx-8 mb-4 mt-9 hidden bg-zinc-600 lg:block"
|
||||
className="mx-8 mb-4 mt-9 hidden bg-neutral-40 lg:block"
|
||||
/>
|
||||
<div className="flex w-full justify-center">
|
||||
<IconButton size="large" className="text-white" onClick={onClose}>
|
||||
@ -139,7 +138,10 @@ export function Sidebar(props: SidebarProps) {
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
<Divider flexItem className="mx-8 my-10 hidden bg-zinc-600 lg:block" />
|
||||
<Divider
|
||||
flexItem
|
||||
className="mx-8 my-10 hidden bg-neutral-40 lg:block"
|
||||
/>
|
||||
<div className="mx-auto mb-8 hidden w-full max-w-xs rounded-sm px-4 py-6 text-center align-bottom shadow-sm lg:block">
|
||||
<h3 className="mb-2 w-full font-semibold text-white">
|
||||
Clan.lol Admin
|
||||
@ -148,7 +150,7 @@ export function Sidebar(props: SidebarProps) {
|
||||
href=""
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="inline-block w-full rounded-md p-2 text-center text-white hover:text-violet-400/95"
|
||||
className="inline-block w-full rounded-md p-2 text-center text-white hover:text-purple-60/95"
|
||||
>
|
||||
Donate
|
||||
</a>
|
||||
|
@ -1,23 +1,22 @@
|
||||
"use client";
|
||||
|
||||
import { useState, ChangeEvent, useMemo } from "react";
|
||||
import Box from "@mui/material/Box";
|
||||
import TablePagination from "@mui/material/TablePagination";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { CircularProgress, Grid, useTheme } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import TablePagination from "@mui/material/TablePagination";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
import { ChangeEvent, useMemo, useState } from "react";
|
||||
|
||||
import { EnhancedTableToolbar } from "./enhancedTableToolbar";
|
||||
import { StickySpeedDial } from "./stickySpeedDial";
|
||||
import { NodeTableContainer } from "./nodeTableContainer";
|
||||
import { SearchBar } from "./searchBar";
|
||||
import { Machine } from "@/api/model/machine";
|
||||
import Grid2 from "@mui/material/Unstable_Grid2/Grid2";
|
||||
import { useMachines } from "../hooks/useMachines";
|
||||
import { Machine } from "@/api/model/machine";
|
||||
import { EnhancedTableToolbar } from "./enhancedTableToolbar";
|
||||
import { NodeTableContainer } from "./nodeTableContainer";
|
||||
import { SearchBar } from "./searchBar";
|
||||
import { StickySpeedDial } from "./stickySpeedDial";
|
||||
|
||||
export function NodeTable() {
|
||||
const machines = useMachines();
|
||||
|
||||
const theme = useTheme();
|
||||
const is_xs = useMediaQuery(theme.breakpoints.only("xs"));
|
||||
|
||||
@ -47,49 +46,51 @@ export function NodeTable() {
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
style={{ height: "100vh" }} // make the container fill the screen height
|
||||
alignItems="center" // center the items vertically
|
||||
justifyContent="center" // center the items horizontally
|
||||
sx={{
|
||||
h: "100vh",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<CircularProgress size={80} color="secondary" />
|
||||
</Grid>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Box sx={{ width: "100%" }}>
|
||||
<Paper sx={{ width: "100%", mb: 2 }}>
|
||||
<StickySpeedDial selected={selected} />
|
||||
<EnhancedTableToolbar tableData={tableData}>
|
||||
<Grid2 xs={12}>
|
||||
<SearchBar
|
||||
tableData={tableData}
|
||||
setFilteredList={setFilteredList}
|
||||
/>
|
||||
</Grid2>
|
||||
</EnhancedTableToolbar>
|
||||
|
||||
<NodeTableContainer
|
||||
tableData={filteredList}
|
||||
page={page}
|
||||
rowsPerPage={rowsPerPage}
|
||||
dense={false}
|
||||
selected={selected}
|
||||
setSelected={setSelected}
|
||||
/>
|
||||
|
||||
{/* TODO: This creates the error Warning: Prop `id` did not match. Server: ":RspmmcqH1:" Client: ":R3j6qpj9H1:" */}
|
||||
<TablePagination
|
||||
rowsPerPageOptions={[5, 10, 25]}
|
||||
labelRowsPerPage={is_xs ? "Rows" : "Rows per page:"}
|
||||
component="div"
|
||||
count={filteredList.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box sx={{ width: "100%" }}>
|
||||
<Paper sx={{ width: "100%", mb: 2 }}>
|
||||
<StickySpeedDial selected={selected} />
|
||||
<EnhancedTableToolbar tableData={tableData}>
|
||||
<Grid2 xs={12}>
|
||||
<SearchBar
|
||||
tableData={tableData}
|
||||
setFilteredList={setFilteredList}
|
||||
/>
|
||||
</Grid2>
|
||||
</EnhancedTableToolbar>
|
||||
|
||||
<NodeTableContainer
|
||||
tableData={filteredList}
|
||||
page={page}
|
||||
rowsPerPage={rowsPerPage}
|
||||
dense={false}
|
||||
selected={selected}
|
||||
setSelected={setSelected}
|
||||
/>
|
||||
|
||||
{/* TODO: This creates the error Warning: Prop `id` did not match. Server: ":RspmmcqH1:" Client: ":R3j6qpj9H1:" */}
|
||||
<TablePagination
|
||||
rowsPerPageOptions={[5, 10, 25]}
|
||||
labelRowsPerPage={is_xs ? "Rows" : "Rows per page:"}
|
||||
component="div"
|
||||
count={filteredList.length}
|
||||
rowsPerPage={rowsPerPage}
|
||||
page={page}
|
||||
onPageChange={handleChangePage}
|
||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { IconButton, Input, InputAdornment } from "@mui/material";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { Suspense } from "react";
|
||||
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { Confirm } from "@/components/join/confirm";
|
||||
import { Layout } from "@/components/join/layout";
|
||||
import { ChevronRight } from "@mui/icons-material";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
|
||||
type FormValues = {
|
||||
flakeUrl: string;
|
||||
@ -21,43 +21,45 @@ export default function JoinPrequel() {
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
{!formState.isSubmitted && !flakeUrl && (
|
||||
<form
|
||||
onSubmit={handleSubmit(() => {})}
|
||||
className="w-full max-w-2xl justify-self-center"
|
||||
>
|
||||
<Controller
|
||||
name="flakeUrl"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
color="secondary"
|
||||
aria-required="true"
|
||||
{...field}
|
||||
required
|
||||
fullWidth
|
||||
startAdornment={
|
||||
<InputAdornment position="start">Clan</InputAdornment>
|
||||
}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton type="submit">
|
||||
<ChevronRight />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Suspense fallback="Loading">
|
||||
{!formState.isSubmitted && !flakeUrl && (
|
||||
<form
|
||||
onSubmit={handleSubmit(() => {})}
|
||||
className="w-full max-w-2xl justify-self-center"
|
||||
>
|
||||
<Controller
|
||||
name="flakeUrl"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
color="secondary"
|
||||
aria-required="true"
|
||||
{...field}
|
||||
required
|
||||
fullWidth
|
||||
startAdornment={
|
||||
<InputAdornment position="start">Clan</InputAdornment>
|
||||
}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton type="submit">
|
||||
<ChevronRight />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
)}
|
||||
{(formState.isSubmitted || flakeUrl) && (
|
||||
<Confirm
|
||||
handleBack={() => reset()}
|
||||
flakeUrl={formState.isSubmitted ? getValues("flakeUrl") : flakeUrl}
|
||||
flakeAttr={flakeAttr}
|
||||
/>
|
||||
</form>
|
||||
)}
|
||||
{(formState.isSubmitted || flakeUrl) && (
|
||||
<Confirm
|
||||
handleBack={() => reset()}
|
||||
flakeUrl={formState.isSubmitted ? getValues("flakeUrl") : flakeUrl}
|
||||
flakeAttr={flakeAttr}
|
||||
/>
|
||||
)}
|
||||
)}
|
||||
</Suspense>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,26 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
import colors from "@clan/colors/colors.json";
|
||||
|
||||
const {
|
||||
ref: { palette, common },
|
||||
} = colors;
|
||||
|
||||
/**
|
||||
* @param {typeof palette} palette
|
||||
* @param {string} baseName
|
||||
* @returns {import("tailwindcss/types/config").ThemeConfig['colors']}
|
||||
*/
|
||||
const getTailwindColors = (palette) => (baseName) =>
|
||||
Object.entries(palette).reduce((acc, [_, v]) => {
|
||||
if (v.meta.color.baseName === baseName) {
|
||||
return {
|
||||
...acc,
|
||||
[Math.round(v.meta.color.shade)]: v.value,
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
module.exports = {
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
@ -10,7 +32,30 @@ module.exports = {
|
||||
],
|
||||
important: "#__next",
|
||||
theme: {
|
||||
extend: {},
|
||||
colors: {
|
||||
white: common.white.value,
|
||||
black: common.black.value,
|
||||
neutral: getTailwindColors(palette)("neutral"),
|
||||
purple: {
|
||||
...getTailwindColors(palette)("purple"),
|
||||
DEFAULT: palette.purple50.value,
|
||||
},
|
||||
red: {
|
||||
...getTailwindColors(palette)("red"),
|
||||
DEFAULT: palette.red50.value,
|
||||
},
|
||||
primary: { DEFAULT: palette.green50.value },
|
||||
secondary: { DEFAULT: palette.purple50.value },
|
||||
paper: {
|
||||
dark: palette.neutral5.value,
|
||||
light: palette.neutral98.value,
|
||||
},
|
||||
},
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
|