Refactor admin theme handling and optimize initialization.

Simplified theme detection logic and improved the loading screen for better performance on slower networks. Adjusted styles, reorganized imports, and removed unnecessary rendering logic in `main.tsx`.
This commit is contained in:
dswbx
2025-01-10 18:33:12 +01:00
parent c7d983942f
commit 87e07570d4
4 changed files with 174 additions and 163 deletions

View File

@@ -174,23 +174,14 @@ export class AdminController extends Controller {
<script type="module" src={"/@vite/client"} /> <script type="module" src={"/@vite/client"} />
</Fragment> </Fragment>
)} )}
<style dangerouslySetInnerHTML={{ __html: "body { margin: 0; padding: 0; }" }} />
</head> </head>
<body style={{ backgroundColor: theme === "light" ? "#fff" : "#000" }}> <body>
<div id="root" /> <div id="root">
<div id="app"> <div id="loading" style={style(theme)}>
<div <span style={{ opacity: 0.3, fontSize: 14, fontFamily: "monospace" }}>
id="loading"
style={{
height: "100vh",
width: "100vw",
display: "flex",
justifyContent: "center",
alignItems: "center",
fontFamily: "monospace",
opacity: 0.3
}}
>
Initializing... Initializing...
</span>
</div> </div>
</div> </div>
<script <script
@@ -205,3 +196,32 @@ export class AdminController extends Controller {
); );
} }
} }
const style = (theme: "light" | "dark" = "light") => {
const base = {
margin: 0,
padding: 0,
height: "100vh",
width: "100vw",
display: "flex",
justifyContent: "center",
alignItems: "center",
"-webkit-font-smoothing": "antialiased",
"-moz-osx-font-smoothing": "grayscale"
};
const styles = {
light: {
color: "rgb(9,9,11)",
backgroundColor: "rgb(250,250,250)"
},
dark: {
color: "rgb(250,250,250)",
backgroundColor: "rgb(30,31,34)"
}
};
return {
...base,
...styles[theme]
};
};

View File

@@ -54,16 +54,19 @@ function AdminInternal() {
); );
} }
const Skeleton = ({ theme = "light" }: { theme?: string }) => { const Skeleton = ({ theme }: { theme?: string }) => {
const actualTheme =
(theme ?? document.querySelector("html")?.classList.contains("light")) ? "light" : "dark";
return ( return (
<div id="bknd-admin" className={(theme ?? "light") + " antialiased"}> <div id="bknd-admin" className={actualTheme + " antialiased"}>
<AppShell.Root> <AppShell.Root>
<header <header
data-shell="header" data-shell="header"
className="flex flex-row w-full h-16 gap-2.5 border-muted border-b justify-start bg-muted/10" className="flex flex-row w-full h-16 gap-2.5 border-muted border-b justify-start bg-muted/10"
> >
<div className="max-h-full flex hover:bg-primary/5 link p-2.5 w-[134px] outline-none"> <div className="max-h-full flex hover:bg-primary/5 link p-2.5 w-[134px] outline-none">
<Logo theme={theme} /> <Logo theme={actualTheme} />
</div> </div>
<nav className="hidden md:flex flex-row gap-2.5 pl-0 p-2.5 items-center"> <nav className="hidden md:flex flex-row gap-2.5 pl-0 p-2.5 items-center">
{[...new Array(5)].map((item, key) => ( {[...new Array(5)].map((item, key) => (

View File

@@ -1,13 +1,14 @@
@import "./components/form/json-schema/styles.css"; @import "./components/form/json-schema/styles.css";
@import '@xyflow/react/dist/style.css'; @import "@xyflow/react/dist/style.css";
@import "@mantine/core/styles.css"; @import "@mantine/core/styles.css";
@import '@mantine/notifications/styles.css'; @import "@mantine/notifications/styles.css";
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
html.fixed, html.fixed body { html.fixed,
html.fixed body {
top: 0; top: 0;
left: 0; left: 0;
height: 100%; height: 100%;
@@ -18,20 +19,14 @@ html.fixed, html.fixed body {
touch-action: none; touch-action: none;
} }
#bknd-admin, .bknd-admin { #bknd-admin,
.bknd-admin {
--color-primary: 9 9 11; /* zinc-950 */ --color-primary: 9 9 11; /* zinc-950 */
--color-background: 250 250 250; /* zinc-50 */ --color-background: 250 250 250; /* zinc-50 */
--color-muted: 228 228 231; /* ? */ --color-muted: 228 228 231; /* ? */
--color-darkest: 0 0 0; /* black */ --color-darkest: 0 0 0; /* black */
--color-lightest: 255 255 255; /* white */ --color-lightest: 255 255 255; /* white */
&.dark {
--color-primary: 250 250 250; /* zinc-50 */
--color-background: 9 9 11; /* zinc-950 */
--color-muted: 39 39 42; /* zinc-800 */
--color-darkest: 255 255 255; /* white */
--color-lightest: 0 0 0; /* black */
}
&.dark { &.dark {
--color-primary: 250 250 250; /* zinc-50 */ --color-primary: 250 250 250; /* zinc-50 */
--color-background: 30 31 34; --color-background: 30 31 34;
@@ -52,7 +47,8 @@ html.fixed, html.fixed body {
} }
} }
html, body { html,
body {
font-size: 14px; font-size: 14px;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
@@ -111,7 +107,8 @@ body,
} }
} }
@layer utilities {} @layer utilities {
}
/* Hide scrollbar for Chrome, Safari and Opera */ /* Hide scrollbar for Chrome, Safari and Opera */
.app-scrollbar::-webkit-scrollbar { .app-scrollbar::-webkit-scrollbar {
@@ -153,11 +150,15 @@ input[type="date"]::-webkit-calendar-picker-indicator {
} }
} }
input[readonly]::placeholder, input[disabled]::placeholder { input[readonly]::placeholder,
input[disabled]::placeholder {
opacity: 0.1; opacity: 0.1;
} }
.react-flow__pane, .react-flow__renderer, .react-flow__node, .react-flow__edge { .react-flow__pane,
.react-flow__renderer,
.react-flow__node,
.react-flow__edge {
cursor: inherit !important; cursor: inherit !important;
.drag-handle { .drag-handle {
cursor: grab; cursor: grab;
@@ -168,7 +169,6 @@ input[readonly]::placeholder, input[disabled]::placeholder {
stroke-width: 2; stroke-width: 2;
} }
.mantine-TextInput-wrapper input { .mantine-TextInput-wrapper input {
font-family: inherit; font-family: inherit;
line-height: 1; line-height: 1;
@@ -191,7 +191,8 @@ input[readonly]::placeholder, input[disabled]::placeholder {
flex: 1 1 0; flex: 1 1 0;
} }
#bknd-admin, .bknd-admin { #bknd-admin,
.bknd-admin {
/* Chrome, Edge, and Safari */ /* Chrome, Edge, and Safari */
& *::-webkit-scrollbar { & *::-webkit-scrollbar {
@apply w-1; @apply w-1;

View File

@@ -1,26 +1,13 @@
import * as React from "react"; import * as React from "react";
import * as ReactDOM from "react-dom/client"; import * as ReactDOM from "react-dom/client";
import Admin from "./Admin";
import "./main.css"; import "./main.css";
import Admin from "./Admin"; ReactDOM.createRoot(document.getElementById("root")!).render(
function ClientApp() {
return <Admin withProvider />;
}
// Render the app
const rootElement = document.getElementById("app")!;
const shouldRender =
!rootElement.innerHTML ||
(rootElement.childElementCount === 1 && rootElement.firstElementChild?.id === "loading");
if (shouldRender) {
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode> <React.StrictMode>
<ClientApp /> <Admin withProvider />
</React.StrictMode> </React.StrictMode>
); );
}
// REGISTER ERROR OVERLAY // REGISTER ERROR OVERLAY
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {