feat: middle save
This commit is contained in:
parent
d9280bdead
commit
a2f00ac83e
10 changed files with 303 additions and 84 deletions
3
bun.lock
3
bun.lock
|
@ -5,6 +5,7 @@
|
|||
"name": "kuma-archive",
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.3.3",
|
||||
"lucide-react": "^0.482.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router": "^7.3.0",
|
||||
|
@ -359,6 +360,8 @@
|
|||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"lucide-react": ["lucide-react@0.482.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-XM8PzHzSrg8ATmmO+fzf+JyYlVVdQnJjuyLDj2p4V2zEtcKeBNAqAoJIGFv1x2HSBa7kT8gpYUxwdQ0g7nypfw=="],
|
||||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||
|
|
11
package.json
11
package.json
|
@ -4,17 +4,18 @@
|
|||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev:server": "go run ./app.go daemon -d --api-only",
|
||||
"dev:all": "bun run build && go run ./app.go daemon -d",
|
||||
"build": "tsc -b && vite build",
|
||||
"build:view": "tsc -b && vite build",
|
||||
"build:server": "go build -o kuma-archive",
|
||||
"build:all": "bun run build && bun run build-server",
|
||||
"build": "bun run build:view && bun run build:server",
|
||||
"dev:view": "vite",
|
||||
"dev:server": "go run ./app.go daemon -d --api-only",
|
||||
"dev": "bun run build:view && go run ./app.go daemon -d",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"bootstrap": "^5.3.3",
|
||||
"lucide-react": "^0.482.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router": "^7.3.0",
|
||||
|
|
1
public/assets/index-EHS3EQtg.css
Normal file
1
public/assets/index-EHS3EQtg.css
Normal file
|
@ -0,0 +1 @@
|
|||
:root{font-family:system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{margin:0;display:flex;place-items:center;min-width:320px;min-height:100vh}h1{font-size:3.2em;line-height:1.1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}#root{max-width:1280px;margin:0 auto;padding:2rem;text-align:center}.logo{height:6em;padding:1.5em;will-change:filter;transition:filter .3s}.logo:hover{filter:drop-shadow(0 0 2em rgba(100,108,255,.6666666667))}.logo.react:hover{filter:drop-shadow(0 0 2em rgba(97,218,251,.6666666667))}@keyframes logo-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: no-preference){a:nth-of-type(2) .logo{animation:logo-spin infinite 20s linear}}.card{padding:2em}.read-the-docs{color:#888}
|
60
public/assets/index-T1mLj9f8.js
Normal file
60
public/assets/index-T1mLj9f8.js
Normal file
File diff suppressed because one or more lines are too long
13
public/index.html
Normal file
13
public/index.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Kuma Archive</title>
|
||||
<script type="module" crossorigin src="/assets/index-T1mLj9f8.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-EHS3EQtg.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
28
src/App.scss
28
src/App.scss
|
@ -0,0 +1,28 @@
|
|||
.ka-view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ka-nav {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.title-content {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
47
src/App.tsx
47
src/App.tsx
|
@ -1,7 +1,10 @@
|
|||
import { BrowserRouter, Route, Routes } from "react-router";
|
||||
import Dashboard from "./components/dashboard";
|
||||
import { BrowserRouter, Route, Routes, useLocation } from "react-router";
|
||||
import { usePath } from "./store/path";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import "./App.scss";
|
||||
import kuma from "./assets/kuma.png";
|
||||
import { Menu } from "lucide-react";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
@ -13,4 +16,44 @@ function App() {
|
|||
);
|
||||
}
|
||||
|
||||
function Dashboard() {
|
||||
const path = usePath();
|
||||
const location = useLocation();
|
||||
const [load, setLoad] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!load) {
|
||||
path.update(location.pathname.substring(1, location.pathname.length));
|
||||
setLoad(true);
|
||||
}
|
||||
|
||||
const id = setInterval(() => {
|
||||
path.update(location.pathname.substring(1, location.pathname.length));
|
||||
}, 5000);
|
||||
|
||||
return () => clearInterval(id);
|
||||
}, [load, path, location]);
|
||||
|
||||
return (
|
||||
<main className="container-md ka-view">
|
||||
<Header />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
function Header() {
|
||||
return (
|
||||
<nav className="ka-nav">
|
||||
<div className="title">
|
||||
<img src={kuma} alt="" />
|
||||
<h4 className="title-content">Kuma Archive</h4>
|
||||
</div>
|
||||
|
||||
<button>
|
||||
<Menu />
|
||||
</button>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import Directory from "../directory";
|
||||
import { usePath } from "../../store/path";
|
||||
import { useLocation } from "react-router";
|
||||
|
||||
import "./dashboard.scss";
|
||||
|
||||
function Dashboard() {
|
||||
const path = usePath();
|
||||
const location = useLocation();
|
||||
const [load, setLoad] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!load) {
|
||||
path.update(location.pathname.substring(1, location.pathname.length));
|
||||
setLoad(true);
|
||||
}
|
||||
|
||||
const id = setInterval(() => {
|
||||
path.update(location.pathname.substring(1, location.pathname.length));
|
||||
}, 5000);
|
||||
|
||||
return () => clearInterval(id);
|
||||
}, [load, path, location]);
|
||||
|
||||
return (
|
||||
<Directory />
|
||||
);
|
||||
}
|
||||
|
||||
export default Dashboard;
|
187
src/index.scss
187
src/index.scss
|
@ -1,11 +1,50 @@
|
|||
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");
|
||||
|
||||
:root {
|
||||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
--background: #242424;
|
||||
--foreground: rgba(255, 255, 255, 0.87);
|
||||
--sidebar-color: #2a2a2a;
|
||||
|
||||
--stroke: #3c3c3c;
|
||||
--nav-color: #191919;
|
||||
--nav-hover: #101010;
|
||||
--profile-color: #3a3a3a;
|
||||
|
||||
--hover: rgba(255, 255, 255, 0.7);
|
||||
--focus: rgba(255, 255, 255, 0.55);
|
||||
|
||||
--form-color: #151515;
|
||||
|
||||
--btn-primary: #0069d9;
|
||||
--btn-secondary: #859099;
|
||||
--btn-success: #28a745;
|
||||
--btn-danger: #dc3545;
|
||||
|
||||
--btn-primary-hover: #0254ac;
|
||||
--btn-secondary-hover: #596066;
|
||||
--btn-success-hover: #208a39;
|
||||
--btn-danger-hover: #b32735;
|
||||
|
||||
--btn-primary-focus: #034fa0;
|
||||
--btn-secondary-focus: #50565c;
|
||||
--btn-success-focus: #1d7c33;
|
||||
--btn-danger-focus: #a72532;
|
||||
|
||||
--font-family: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
font-size: 11pt;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
|
@ -13,57 +52,119 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
|
||||
&:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
* {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
font-size: 32pt;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
h2 {
|
||||
font-size: 24pt;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18pt;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 15pt;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
user-select: none;
|
||||
text-decoration: none;
|
||||
transition-duration: 0.3s;
|
||||
color: var(--foreground);
|
||||
|
||||
&:hover {
|
||||
color: var(--hover);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
&:focus {
|
||||
color: var(--focus);
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
|
||||
input {
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition-duration: 0.3s;
|
||||
background-color: var(--background);
|
||||
|
||||
&.primary {
|
||||
background-color: var(--btn-primary);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--btn-primary-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: var(--btn-primary-focus);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background-color: var(--btn-secondary);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--btn-secondary-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: var(--btn-secondary-focus);
|
||||
}
|
||||
}
|
||||
|
||||
&.success {
|
||||
background-color: var(--btn-success);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--btn-success-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: var(--btn-success-focus);
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: var(--btn-danger);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--btn-danger-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: var(--btn-danger-focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input, button {
|
||||
height: 40px;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 12pt;
|
||||
border-radius: 25px;
|
||||
padding: 0.25rem 15px;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue