[V1] Folder/Tag System

This commit is contained in:
Youwes09
2026-02-22 16:44:25 -06:00
parent 7ed7ec0ea3
commit 9e7f66e302
10 changed files with 748 additions and 91 deletions
+19 -42
View File
@@ -15,29 +15,32 @@
display: flex;
align-items: center;
justify-content: center;
margin-bottom: var(--sp-3);
overflow: visible;
background: none;
border: none;
cursor: pointer;
border-radius: var(--radius-lg);
transition: opacity var(--t-base), transform var(--t-base);
padding: 0;
}
.logo:hover { opacity: 0.8; transform: scale(0.96); }
.logo:active { transform: scale(0.92); }
.logoIcon {
width: 80px;
height: 80px;
background-color: var(--accent);
mask-image: url("../../assets/moku-icon.svg");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
-webkit-mask-image: url("../../assets/moku-icon.svg");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
filter: drop-shadow(0 0 8px rgba(107, 143, 107, 0.35));
pointer-events: none;
}
.nav {
@@ -51,54 +54,28 @@
}
.tab {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
width: 36px; height: 36px;
display: flex; align-items: center; justify-content: center;
border-radius: var(--radius-md);
color: var(--text-faint);
transition: color var(--t-base), background var(--t-base);
}
.tab:hover {
color: var(--text-muted);
background: var(--bg-raised);
}
.tabActive {
color: var(--accent-fg);
background: var(--accent-muted);
}
.tabActive:hover {
color: var(--accent-fg);
background: var(--accent-muted);
}
.tab:hover { color: var(--text-muted); background: var(--bg-raised); }
.tabActive { color: var(--accent-fg); background: var(--accent-muted); }
.tabActive:hover { color: var(--accent-fg); background: var(--accent-muted); }
.bottom {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding: var(--sp-3) var(--sp-2) 0;
display: flex; flex-direction: column; align-items: center;
width: 100%; padding: var(--sp-3) var(--sp-2) 0;
border-top: 1px solid var(--border-dim);
margin-top: var(--sp-3);
}
.settingsBtn {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
width: 36px; height: 36px;
display: flex; align-items: center; justify-content: center;
border-radius: var(--radius-md);
color: var(--text-faint);
transition: color var(--t-base), background var(--t-base), transform var(--t-slow);
}
.settingsBtn:hover {
color: var(--text-muted);
background: var(--bg-raised);
transform: rotate(30deg);
}
.settingsBtn:hover { color: var(--text-muted); background: var(--bg-raised); transform: rotate(30deg); }
+23 -13
View File
@@ -6,30 +6,40 @@ import { useStore, type NavPage } from "../../store";
import s from "./Sidebar.module.css";
const TABS: { id: NavPage; icon: React.ReactNode; label: string }[] = [
{ id: "library", icon: <Books size={18} weight="light" />, label: "Library" },
{ id: "search", icon: <MagnifyingGlass size={18} weight="light" />, label: "Search" },
{ id: "history", icon: <ClockCounterClockwise size={18} weight="light" />, label: "History" },
{ id: "sources", icon: <Compass size={18} weight="light" />, label: "Sources" },
{ id: "downloads", icon: <DownloadSimple size={18} weight="light" />, label: "Downloads" },
{ id: "extensions", icon: <PuzzlePiece size={18} weight="light" />, label: "Extensions" },
{ id: "library", icon: <Books size={18} weight="light" />, label: "Library" },
{ id: "search", icon: <MagnifyingGlass size={18} weight="light" />, label: "Search" },
{ id: "history", icon: <ClockCounterClockwise size={18} weight="light" />, label: "History" },
{ id: "sources", icon: <Compass size={18} weight="light" />, label: "Sources" },
{ id: "downloads", icon: <DownloadSimple size={18} weight="light" />, label: "Downloads" },
{ id: "extensions", icon: <PuzzlePiece size={18} weight="light" />, label: "Extensions" },
];
export default function Sidebar() {
const navPage = useStore((state) => state.navPage);
const setNavPage = useStore((state) => state.setNavPage);
const setActiveSource = useStore((state) => state.setActiveSource);
const openSettings = useStore((state) => state.openSettings);
const navPage = useStore((state) => state.navPage);
const setNavPage = useStore((state) => state.setNavPage);
const setActiveSource = useStore((state) => state.setActiveSource);
const setActiveManga = useStore((state) => state.setActiveManga);
const setLibraryFilter = useStore((state) => state.setLibraryFilter);
const openSettings = useStore((state) => state.openSettings);
function navigate(id: NavPage) {
setNavPage(id);
if (id !== "sources") setActiveSource(null);
}
function goHome() {
setNavPage("library");
setActiveSource(null);
setActiveManga(null);
setLibraryFilter("library");
}
return (
<aside className={s.root}>
<div className={s.logo}>
<div className={s.logoIcon} aria-label="Moku Logo" />
</div>
{/* Logo click → back to library root */}
<button className={s.logo} onClick={goHome} title="Go to Library" aria-label="Go to Library">
<div className={s.logoIcon} />
</button>
<nav className={s.nav}>
{TABS.map((tab) => (
<button key={tab.id} title={tab.label}