Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"source.fixAll.biome": "explicit",
"source.organizeImports.biome": "explicit",
"source.removeUnusedImports": "explicit"
},
"[typescriptreact]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
}
}
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/apple-touch-icon-180x180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icon-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/maskable-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 19 additions & 2 deletions src/app/context/theme-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
"use client";

import CssBaseline from "@mui/material/CssBaseline";
import { ThemeProvider } from "@mui/material/styles";
import type { ReactNode } from "react";
import { ThemeProvider, useColorScheme } from "@mui/material/styles";
import { type ReactNode, useEffect } from "react";
import { theme } from "@/app/theme";

function ThemeSynchronizer() {
const { setMode } = useColorScheme();

useEffect(() => {
const storedMode = localStorage.getItem("mui-mode");
if (!storedMode) {
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
setMode(systemPrefersDark ? "dark" : "light");
Comment on lines +14 to +17
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThemeSynchronizer sets an explicit mode ("dark"/"light") when there is no stored mode, even though the provider is configured with defaultMode="system". This overrides system-following behavior for new users and won’t react to later OS theme changes. Prefer leaving mode as "system" when nothing is stored (or explicitly calling setMode("system")), and avoid overriding it based on a one-time matchMedia read.

Suggested change
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
setMode(systemPrefersDark ? "dark" : "light");
setMode("system");

Copilot uses AI. Check for mistakes.
}
}, [setMode]);

return null;
}

const MuiProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
return (
<ThemeProvider theme={theme} defaultMode="system">
<CssBaseline />
<ThemeSynchronizer />
{children}
</ThemeProvider>
);
Expand Down
2 changes: 2 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");

/* Light Mode */
:root[data-mui-color-scheme="light"],
.light-mode {
--bg-color: #f5f5f7;
--text-color: #1d1d1f;
Expand All @@ -13,6 +14,7 @@
}

/* Dark Mode */
:root[data-mui-color-scheme="dark"],
.dark-mode {
--bg-color: #0d0d0d;
--text-color: #f5f5f7;
Expand Down
21 changes: 21 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ export const metadata: Metadata = {
title: "AI Metrics Dashboard - LibreChat Analytics",
description:
"Dashboard for monitoring and analyzing LibreChat AI usage metrics, token consumption, and agent statistics.",
icons: {
icon: [
{
url: "/favicon-32x32.png",
sizes: "32x32",
type: "image/png",
},
{
url: "/favicon-16x16.png",
sizes: "16x16",
type: "image/png",
},
],
apple: [
{
url: "/apple-touch-icon-180x180.png",
sizes: "180x180",
type: "image/png",
},
],
},
};

export default function RootLayout({
Expand Down
4 changes: 4 additions & 0 deletions src/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { type FormEvent, useCallback, useState } from "react";
import DarkLightSwitch from "@/components/dashboard/dark-light-switch";
import { API_BASE, getAbsolutePath } from "@/lib/utils/api-base";

export default function LoginPage() {
Expand Down Expand Up @@ -200,6 +201,9 @@ export default function LoginPage() {
</a>
</Typography>
</Paper>
<Box sx={{ position: "absolute", bottom: 16, right: 16 }}>
<DarkLightSwitch />
</Box>
</Box>
);
}