mirror of
https://github.com/Radiquum/AniX.git
synced 2025-05-01 10:29:40 +05:00
frontend: add color theme & theme switcher
This commit is contained in:
parent
84b13a2c80
commit
b8878c4fb8
7 changed files with 192 additions and 19 deletions
21
frontend/app/App.jsx
Normal file
21
frontend/app/App.jsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
"use client";
|
||||
|
||||
import { NavigationRail } from "@/app/components/NavigationRail/NavigationRail";
|
||||
import { useThemeStore } from "./store/theme-store";
|
||||
import { useEffect } from "react";
|
||||
// import { useStore } from "./store/app-store";
|
||||
|
||||
export const App = (props) => {
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
useEffect(() => {
|
||||
themeStore.checkTheme();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<body className={themeStore.theme}>
|
||||
<NavigationRail />
|
||||
<main className="responsive">{props.children}</main>
|
||||
</body>
|
||||
);
|
||||
};
|
53
frontend/app/components/NavigationRail/NavigationRail.js
Normal file
53
frontend/app/components/NavigationRail/NavigationRail.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
"use client";
|
||||
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useThemeStore } from "@/app/store/theme-store";
|
||||
import Link from "next/link";
|
||||
|
||||
export const NavigationRail = () => {
|
||||
const pathname = usePathname();
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
return (
|
||||
<nav className="left">
|
||||
<button className="circle transparent ">
|
||||
<img className="responsive" src="/favicon.ico"></img>
|
||||
</button>
|
||||
|
||||
<Link href="/" className={pathname == "/" ? "active" : ""}>
|
||||
<i>home</i>
|
||||
<div>Домашняя</div>
|
||||
</Link>
|
||||
<Link href="/search" className={pathname == "/search" ? "active" : ""}>
|
||||
<i>search</i>
|
||||
<div>Поиск</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/bookmarks"
|
||||
className={pathname == "/bookmarks" ? "active" : ""}
|
||||
>
|
||||
<i>bookmark</i>
|
||||
<div>Закладки</div>
|
||||
</Link>
|
||||
<Link
|
||||
href="/favorites"
|
||||
className={pathname == "/favorites" ? "active" : ""}
|
||||
>
|
||||
<i>favorite</i>
|
||||
<div>Избранное</div>
|
||||
</Link>
|
||||
<Link href="/history" className={pathname == "/history" ? "active" : ""}>
|
||||
<i>history</i>
|
||||
<div>История</div>
|
||||
</Link>
|
||||
{/* <a>
|
||||
<i>share</i>
|
||||
<div>share</div>
|
||||
</a> */}
|
||||
<span className="max"></span>
|
||||
<button className="circle transparent end-align" onClick={() => themeStore.changeTheme(themeStore.theme == "dark" ? "light" : "dark")}>
|
||||
<i>palette</i>
|
||||
</button>
|
||||
</nav>
|
||||
);
|
||||
};
|
|
@ -11,3 +11,86 @@ body {
|
|||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
|
||||
body, nav.left{
|
||||
transition: background .2s;
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
body.light.light {
|
||||
--primary: #bc004b;
|
||||
--on-primary: #ffffff;
|
||||
--primary-container: #ffd9de;
|
||||
--on-primary-container: #400014;
|
||||
--secondary: #75565b;
|
||||
--on-secondary: #ffffff;
|
||||
--secondary-container: #ffd9de;
|
||||
--on-secondary-container: #2c1519;
|
||||
--tertiary: #795831;
|
||||
--on-tertiary: #ffffff;
|
||||
--tertiary-container: #ffddba;
|
||||
--on-tertiary-container: #2b1700;
|
||||
--error: #ba1a1a;
|
||||
--on-error: #ffffff;
|
||||
--error-container: #ffdad6;
|
||||
--on-error-container: #410002;
|
||||
--background: #fffbff;
|
||||
--on-background: #201a1b;
|
||||
--surface: #fff8f7;
|
||||
--on-surface: #201a1b;
|
||||
--surface-variant: #f3dddf;
|
||||
--on-surface-variant: #524345;
|
||||
--outline: #847375;
|
||||
--outline-variant: #d6c2c3;
|
||||
--shadow: #000000;
|
||||
--scrim: #000000;
|
||||
--inverse-surface: #362f2f;
|
||||
--inverse-on-surface: #fbeeee;
|
||||
--inverse-primary: #ffb2be;
|
||||
--surface-dim: #e3d7d8;
|
||||
--surface-bright: #fff8f7;
|
||||
--surface-container-lowest: #ffffff;
|
||||
--surface-container-low: #fdf1f1;
|
||||
--surface-container: #f8ebeb;
|
||||
--surface-container-high: #f2e5e6;
|
||||
--surface-container-highest: #ece0e0;
|
||||
}
|
||||
|
||||
body.dark.dark {
|
||||
--primary: #ffb2be;
|
||||
--on-primary: #660025;
|
||||
--primary-container: #900038;
|
||||
--on-primary-container: #ffd9de;
|
||||
--secondary: #e5bdc2;
|
||||
--on-secondary: #43292d;
|
||||
--secondary-container: #5c3f43;
|
||||
--on-secondary-container: #ffd9de;
|
||||
--tertiary: #ebbf90;
|
||||
--on-tertiary: #452b08;
|
||||
--tertiary-container: #5f411c;
|
||||
--on-tertiary-container: #ffddba;
|
||||
--error: #ffb4ab;
|
||||
--on-error: #690005;
|
||||
--error-container: #93000a;
|
||||
--on-error-container: #ffb4ab;
|
||||
--background: #201a1b;
|
||||
--on-background: #ece0e0;
|
||||
--surface: #181213;
|
||||
--on-surface: #ece0e0;
|
||||
--surface-variant: #524345;
|
||||
--on-surface-variant: #d6c2c3;
|
||||
--outline: #9f8c8e;
|
||||
--outline-variant: #524345;
|
||||
--shadow: #000000;
|
||||
--scrim: #000000;
|
||||
--inverse-surface: #ece0e0;
|
||||
--inverse-on-surface: #362f2f;
|
||||
--inverse-primary: #bc004b;
|
||||
--surface-dim: #181213;
|
||||
--surface-bright: #3f3738;
|
||||
--surface-container-lowest: #120d0d;
|
||||
--surface-container-low: #201a1b;
|
||||
--surface-container: #241e1f;
|
||||
--surface-container-high: #2f2829;
|
||||
--surface-container-highest: #3a3334;
|
||||
}
|
|
@ -1,21 +1,16 @@
|
|||
import "./globals.css";
|
||||
import "beercss";
|
||||
import "material-dynamic-colors";
|
||||
|
||||
import { NavigationRail } from "@/components/NavigationRail";
|
||||
import {App} from "@/app/App"
|
||||
|
||||
export const metadata = {
|
||||
title: "AniX",
|
||||
description: "Unofficial web app for anixart",
|
||||
description: "Неофициальное веб приложение для anixart",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
export default async function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<NavigationRail />
|
||||
<main className="responsive">{children}</main>
|
||||
</body>
|
||||
<html lang="ru">
|
||||
<App>{children}</App>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
20
frontend/app/store/theme-store.js
Normal file
20
frontend/app/store/theme-store.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
"use client";
|
||||
import { create } from "zustand";
|
||||
|
||||
export function setTheme(theme) {
|
||||
localStorage.setItem("theme", theme);
|
||||
}
|
||||
export function getTheme() {
|
||||
return localStorage.getItem("theme");
|
||||
}
|
||||
|
||||
export const useThemeStore = create((set) => ({
|
||||
theme: "light",
|
||||
changeTheme: (theme) => {
|
||||
set({ theme: theme });
|
||||
setTheme(theme);
|
||||
},
|
||||
checkTheme: () => {
|
||||
set({ theme: getTheme() || "light" });
|
||||
}
|
||||
}));
|
Loading…
Add table
Add a link
Reference in a new issue