chore: reorganize project into monorepo
This commit is contained in:
220
frontend/src/layouts/BaseLayout.astro
Normal file
220
frontend/src/layouts/BaseLayout.astro
Normal file
@@ -0,0 +1,220 @@
|
||||
---
|
||||
import '../styles/global.css';
|
||||
import Header from '../components/Header.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import BackToTop from '../components/interactive/BackToTop.svelte';
|
||||
import { api, DEFAULT_SITE_SETTINGS } from '../lib/api/client';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const props = Astro.props;
|
||||
|
||||
let siteSettings = DEFAULT_SITE_SETTINGS;
|
||||
|
||||
try {
|
||||
siteSettings = await api.getSiteSettings();
|
||||
} catch (error) {
|
||||
console.error('Failed to load site settings:', error);
|
||||
}
|
||||
|
||||
const title = props.title || siteSettings.siteTitle;
|
||||
const description = props.description || siteSettings.siteDescription;
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content={description} />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<title>{title}</title>
|
||||
|
||||
<style is:inline>
|
||||
:root {
|
||||
--primary: #2563eb;
|
||||
--primary-rgb: 37 99 235;
|
||||
--primary-light: rgba(37 99 235 / 0.14);
|
||||
--primary-dark: #1d4ed8;
|
||||
--secondary: #f97316;
|
||||
--secondary-rgb: 249 115 22;
|
||||
--secondary-light: rgba(249 115 22 / 0.14);
|
||||
--bg: #eef3f8;
|
||||
--bg-rgb: 238 243 248;
|
||||
--bg-secondary: #e2e8f0;
|
||||
--bg-tertiary: #cbd5e1;
|
||||
--terminal-bg: #f8fbff;
|
||||
--text: #0f172a;
|
||||
--text-rgb: 15 23 42;
|
||||
--text-secondary: #475569;
|
||||
--text-tertiary: #7c8aa0;
|
||||
--terminal-text: #0f172a;
|
||||
--title-color: #0f172a;
|
||||
--button-text: #0f172a;
|
||||
--border-color: #d6e0ea;
|
||||
--border-color-rgb: 214 224 234;
|
||||
--terminal-border: #d6e0ea;
|
||||
--tag-bg: #edf3f8;
|
||||
--tag-text: #0f172a;
|
||||
--header-bg: rgba(244 248 252 / 0.92);
|
||||
--code-bg: #eef3f8;
|
||||
--success: #10b981;
|
||||
--success-rgb: 16 185 129;
|
||||
--success-light: #d1fae5;
|
||||
--success-dark: #065f46;
|
||||
--warning: #f59e0b;
|
||||
--warning-rgb: 245 158 11;
|
||||
--warning-light: #fef3c7;
|
||||
--warning-dark: #92400e;
|
||||
--danger: #ef4444;
|
||||
--danger-rgb: 239 68 68;
|
||||
--danger-light: #fee2e2;
|
||||
--danger-dark: #991b1b;
|
||||
--gray-light: #f3f4f6;
|
||||
--gray-dark: #374151;
|
||||
--btn-close: #ff5f56;
|
||||
--btn-minimize: #ffbd2e;
|
||||
--btn-expand: #27c93f;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--primary: #00ff9d;
|
||||
--primary-rgb: 0 255 157;
|
||||
--primary-light: #00ff9d33;
|
||||
--primary-dark: #00b8ff;
|
||||
--secondary: #00b8ff;
|
||||
--secondary-rgb: 0 184 255;
|
||||
--secondary-light: #00b8ff33;
|
||||
--bg: #0a0e17;
|
||||
--bg-rgb: 10 14 23;
|
||||
--bg-secondary: #161b22;
|
||||
--bg-tertiary: #21262d;
|
||||
--terminal-bg: #0d1117;
|
||||
--text: #e6e6e6;
|
||||
--text-rgb: 230 230 230;
|
||||
--text-secondary: #d1d5db;
|
||||
--text-tertiary: #6b7280;
|
||||
--terminal-text: #e6e6e6;
|
||||
--title-color: #ffffff;
|
||||
--button-text: #e6e6e6;
|
||||
--border-color: rgba(255 255 255 / 0.1);
|
||||
--border-color-rgb: 255 255 255;
|
||||
--terminal-border: rgba(255 255 255 / 0.1);
|
||||
--tag-bg: #161b22;
|
||||
--tag-text: #e6e6e6;
|
||||
--header-bg: rgba(22 27 34 / 0.9);
|
||||
--code-bg: #161b22;
|
||||
--success-light: #064e3b;
|
||||
--success-dark: #d1fae5;
|
||||
--warning-light: #78350f;
|
||||
--warning-dark: #fef3c7;
|
||||
--danger-light: #7f1d1d;
|
||||
--danger-dark: #fee2e2;
|
||||
--gray-light: #1f2937;
|
||||
--gray-dark: #e5e7eb;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not(.light) {
|
||||
--primary: #00ff9d;
|
||||
--primary-rgb: 0 255 157;
|
||||
--primary-light: #00ff9d33;
|
||||
--primary-dark: #00b8ff;
|
||||
--secondary: #00b8ff;
|
||||
--secondary-rgb: 0 184 255;
|
||||
--secondary-light: #00b8ff33;
|
||||
--bg: #0a0e17;
|
||||
--bg-rgb: 10 14 23;
|
||||
--bg-secondary: #161b22;
|
||||
--bg-tertiary: #21262d;
|
||||
--terminal-bg: #0d1117;
|
||||
--text: #e6e6e6;
|
||||
--text-rgb: 230 230 230;
|
||||
--text-secondary: #d1d5db;
|
||||
--text-tertiary: #6b7280;
|
||||
--terminal-text: #e6e6e6;
|
||||
--title-color: #ffffff;
|
||||
--button-text: #e6e6e6;
|
||||
--border-color: rgba(255 255 255 / 0.1);
|
||||
--border-color-rgb: 255 255 255;
|
||||
--terminal-border: rgba(255 255 255 / 0.1);
|
||||
--tag-bg: #161b22;
|
||||
--tag-text: #e6e6e6;
|
||||
--header-bg: rgba(22 27 34 / 0.9);
|
||||
--code-bg: #161b22;
|
||||
--success-light: #064e3b;
|
||||
--success-dark: #d1fae5;
|
||||
--warning-light: #78350f;
|
||||
--warning-dark: #fef3c7;
|
||||
--danger-light: #7f1d1d;
|
||||
--danger-dark: #fee2e2;
|
||||
--gray-light: #1f2937;
|
||||
--gray-dark: #e5e7eb;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script is:inline>
|
||||
(function() {
|
||||
const theme = localStorage.getItem('theme');
|
||||
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
if (theme === 'dark' || (!theme && systemDark)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else if (theme === 'light') {
|
||||
document.documentElement.classList.add('light');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body class="min-h-screen bg-[var(--bg)] text-[var(--text)] font-sans antialiased">
|
||||
<div class="relative min-h-screen flex flex-col">
|
||||
<div class="fixed inset-0 -z-10 bg-[var(--bg)]"></div>
|
||||
<div
|
||||
class="fixed inset-0 -z-10 opacity-70"
|
||||
style="background:
|
||||
radial-gradient(circle at top left, rgba(var(--primary-rgb), 0.06), transparent 30%),
|
||||
radial-gradient(circle at top right, rgba(var(--secondary-rgb), 0.05), transparent 26%),
|
||||
linear-gradient(180deg, color-mix(in oklab, var(--terminal-bg) 34%, transparent), transparent 48%);"
|
||||
></div>
|
||||
<div
|
||||
class="fixed inset-0 -z-10 opacity-30"
|
||||
style="background-image:
|
||||
linear-gradient(rgba(var(--primary-rgb), 0.035) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(var(--primary-rgb), 0.03) 1px, transparent 1px);
|
||||
background-size: 100% 18px, 18px 100%;"
|
||||
></div>
|
||||
|
||||
<Header siteSettings={siteSettings} />
|
||||
|
||||
<main class="flex-1 w-full">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<Footer siteSettings={siteSettings} />
|
||||
<BackToTop client:load />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
font-family: 'IBM Plex Sans', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
:global(code, pre) {
|
||||
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user