frontend:

Fix undefined api call
Simplify some parts
Better theme management
Add color picker (dynamic themes wohoo)
Add missing lists keys
This commit is contained in:
Kentai Radiquum 2024-04-21 05:35:44 +05:00
parent 17b5693f34
commit 79782b4228
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
8 changed files with 157 additions and 137 deletions

View file

@ -1,21 +1,47 @@
"use client";
import "beercss";
import "material-dynamic-colors";
import { NavigationRail } from "@/app/components/NavigationRail/NavigationRail";
import { useThemeStore } from "./store/theme-store";
import { useEffect } from "react";
// import { useStore } from "./store/app-store";
import { setTheme, getTheme, setMode, getMode } from "./store/theme-store";
import { useEffect, useState } from "react";
import { ColorPicker } from "@/app/components/ColorPicker/ColorPicker";
export const App = (props) => {
const themeStore = useThemeStore();
const [colorPicker, setColorPicker] = useState(false);
const theme = async (from) => {
setTheme(from);
await ui("theme", from);
};
const mode = () => {
let newMode = ui("mode") == "dark" ? "light" : "dark";
setMode(newMode);
ui("mode", getMode());
};
useEffect(() => {
themeStore.checkTheme();
const mode = getMode();
const theme = getTheme();
if (mode != ui("mode")) {
ui("mode", getMode());
}
if (theme != ui("theme")) {
ui("theme", theme);
}
}, []);
return (
<body className={themeStore.theme}>
<NavigationRail />
<main className="responsive">{props.children}</main>
<body>
<NavigationRail
colorPicker={colorPicker}
setColorPicker={setColorPicker}
/>
<main className="responsive">
{colorPicker && <ColorPicker mode={mode} theme={theme} />}
{props.children}
</main>
</body>
);
};

View file

@ -0,0 +1,48 @@
"use client";
import { useState } from "react";
import Styles from "./ColorPicker.module.css"
export const ColorPicker = (props) => {
const colors = [
{ hex: "#ffffff", color: "white" },
{ hex: "#e91e63", color: "pink" },
{ hex: "#ff9800", color: "orange" },
{ hex: "#4caf50", color: "green" },
{ hex: "#009688", color: "teal" },
{ hex: "#9c27b0", color: "purple" },
{ hex: "#673ab7", color: "deep-purple" },
{ hex: "#ffeb3b", color: "yellow" },
{ hex: "#ffc8ff", color: Styles["radiquum-pink"]},
{ hex: "#0087c7", color: Styles["fuxigen-blue"]},
{ hex: "#e54040", color: Styles["anixart-red"]},
];
const [mode, setMode] = useState(ui("mode"));
return (
<dialog className="active">
<h5>Theme Select</h5>
<div className="grid center-align">
{colors.map((item) => {
return (
<button
key={item.color}
className={`circle small ${item.color} s2`}
onClick={() => props.theme(item.hex)}
></button>
);
})}
</div>
<div className="medium-divider"></div>
<button
className={`circle small transparent`}
onClick={() => {
props.mode();
setMode(ui("mode"));
}}
>
{mode == "light" ? <i>dark_mode</i> : <i>light_mode</i>}
</button>
</dialog>
);
};

View file

@ -0,0 +1,9 @@
.radiquum-pink{
background-color: #ffc8ff !important;
}
.fuxigen-blue{
background-color: #0087c7 !important;
}
.anixart-red{
background-color: #e54040 !important;
}

View file

@ -1,12 +1,38 @@
"use client";
import { usePathname } from "next/navigation";
import { useThemeStore } from "@/app/store/theme-store";
import Link from "next/link";
export const NavigationRail = () => {
export const NavigationRail = (props) => {
const pathname = usePathname();
const themeStore = useThemeStore();
const items = [
{
title: "Домашняя",
icon: "home",
path: "/",
},
{
title: "Поиск",
icon: "search",
path: "/search",
},
{
title: "Закладки",
icon: "bookmark",
path: "/bookmarks",
},
{
title: "Избранное",
icon: "favorite",
path: "/favorites",
},
{
title: "История",
icon: "history",
path: "/history",
},
];
return (
<nav className="left">
@ -14,40 +40,27 @@ export const NavigationRail = () => {
<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> */}
{items.map((item) => {
return (
<Link
key={item.path}
href={item.path}
className={pathname == item.path ? "active" : ""}
>
<i>{item.icon}</i>
<div>{item.title}</div>
</Link>
);
})}
<span className="max"></span>
<button className="circle transparent" onClick={() => themeStore.changeTheme(themeStore.theme == "dark" ? "light" : "dark")}>
<button
className="circle transparent"
onClick={() => props.setColorPicker(!props.colorPicker)}
>
<i>palette</i>
</button>
</nav>
);
};

View file

@ -21,81 +21,3 @@ 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;
}

View file

@ -1,5 +1,4 @@
import "./globals.css";
import "beercss";
import {App} from "@/app/App"
export const metadata = {

View file

@ -28,7 +28,12 @@ export default function Home() {
// set list on initial page load
useEffect(() => {
setList(searchParams.get("list") || "last");
const query = searchParams.get("list");
if (query) {
setList(query);
} else {
setList("last");
}
}, []);
async function fetchData(list, page = 0) {
@ -44,10 +49,12 @@ export default function Home() {
}
useEffect(() => {
router.push(pathname + "?" + createQueryString("list", list));
setReleases(null);
setPage(0);
fetchData(list); // Call fetchData here
if (list) {
router.push(pathname + "?" + createQueryString("list", list));
setReleases(null);
setPage(0);
fetchData(list); // Call fetchData here
}
}, [list]);
useEffect(() => {
@ -81,6 +88,7 @@ export default function Home() {
{chips.map((item) => {
return (
<button
key={item.list}
className={`chip ${list == item.list ? "fill" : ""}`}
onClick={() => {
setList(item.list);

View file

@ -1,5 +1,10 @@
"use client";
import { create } from "zustand";
export function setMode(mode) {
localStorage.setItem("mode", mode);
}
export function getMode() {
return localStorage.getItem("mode");
}
export function setTheme(theme) {
localStorage.setItem("theme", theme);
@ -8,13 +13,3 @@ 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" });
}
}));