chore: checkpoint admin editor and perf work

This commit is contained in:
2026-03-31 00:12:02 +08:00
parent 92a85eef20
commit 99b308e800
45 changed files with 7265 additions and 833 deletions

View File

@@ -868,7 +868,9 @@ const currentNavLabel =
renderSearchResults(query, [], 'loading');
try {
const response = await fetch(`${searchApiBase}/search?q=${encodeURIComponent(query)}&limit=6`);
const response = await fetch(
`${searchApiBase}/search?q=${encodeURIComponent(query)}&limit=6&preview=true`
);
if (!response.ok) {
throw new Error(`Search failed: ${response.status}`);
}

View File

@@ -5,21 +5,25 @@ import Footer from '../components/Footer.astro';
import BackToTop from '../components/interactive/BackToTop.svelte';
import { api, DEFAULT_SITE_SETTINGS } from '../lib/api/client';
import { getI18n, LOCALE_COOKIE_NAME, SUPPORTED_LOCALES } from '../lib/i18n';
import type { SiteSettings } from '../lib/types';
interface Props {
title?: string;
description?: string;
siteSettings?: SiteSettings;
}
const props = Astro.props;
const { locale, messages } = getI18n(Astro);
let siteSettings = DEFAULT_SITE_SETTINGS;
let siteSettings = props.siteSettings ?? DEFAULT_SITE_SETTINGS;
try {
siteSettings = await api.getSiteSettings();
} catch (error) {
console.error('Failed to load site settings:', error);
if (!props.siteSettings) {
try {
siteSettings = await api.getSiteSettings();
} catch (error) {
console.error('Failed to load site settings:', error);
}
}
const title = props.title || siteSettings.siteTitle;
@@ -305,7 +309,7 @@ const i18nPayload = JSON.stringify({ locale, messages });
</main>
<Footer siteSettings={siteSettings} />
<BackToTop client:load />
<BackToTop client:idle />
</div>
</body>
</html>

View File

@@ -44,7 +44,11 @@ try {
const ownerInitial = siteSettings.ownerName.charAt(0) || 'T';
---
<BaseLayout title={`${t('about.pageTitle')} - ${siteSettings.siteShortName}`} description={siteSettings.siteDescription}>
<BaseLayout
title={`${t('about.pageTitle')} - ${siteSettings.siteShortName}`}
description={siteSettings.siteDescription}
siteSettings={siteSettings}
>
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<TerminalWindow title="~/about" class="w-full">
<div class="mb-6 px-4">

View File

@@ -29,16 +29,21 @@ const { slug } = Astro.params;
let post = null;
let siteSettings = DEFAULT_SITE_SETTINGS;
try {
post = await apiClient.getPostBySlug(slug ?? '');
} catch (error) {
console.error('API Error:', error);
const [postResult, siteSettingsResult] = await Promise.allSettled([
apiClient.getPostBySlug(slug ?? ''),
apiClient.getSiteSettings(),
]);
if (postResult.status === 'fulfilled') {
post = postResult.value;
} else {
console.error('API Error:', postResult.reason);
}
try {
siteSettings = await apiClient.getSiteSettings();
} catch (error) {
console.error('Site settings API Error:', error);
if (siteSettingsResult.status === 'fulfilled') {
siteSettings = siteSettingsResult.value;
} else {
console.error('Site settings API Error:', siteSettingsResult.reason);
}
if (!post) {
@@ -59,7 +64,7 @@ const markdownProcessor = await createMarkdownProcessor();
const renderedContent = await markdownProcessor.render(articleMarkdown);
---
<BaseLayout title={post.title} description={post.description}>
<BaseLayout title={post.title} description={post.description} siteSettings={siteSettings}>
<ReadingProgress />
<BackToTop />
<Lightbox />

View File

@@ -19,9 +19,14 @@ const selectedSearch = url.searchParams.get('search') || '';
const { t } = getI18n(Astro);
try {
allPosts = selectedSearch ? await api.searchPosts(selectedSearch) : await api.getPosts();
allCategories = await api.getCategories();
const rawTags = await api.getTags();
const [posts, categories, rawTags] = await Promise.all([
selectedSearch ? api.searchPosts(selectedSearch) : api.getPosts(),
api.getCategories(),
api.getTags(),
]);
allPosts = posts;
allCategories = categories;
const seenTagIds = new Set<string>();
allTags = rawTags.filter(tag => {
const key = `${tag.slug}:${tag.name}`.toLowerCase();

View File

@@ -29,7 +29,11 @@ const sampleQuestions = [
];
---
<BaseLayout title={`${t('ask.pageTitle')} | ${siteSettings.siteShortName}`} description={t('ask.pageDescription', { siteName: siteSettings.siteName })}>
<BaseLayout
title={`${t('ask.pageTitle')} | ${siteSettings.siteShortName}`}
description={t('ask.pageDescription', { siteName: siteSettings.siteName })}
siteSettings={siteSettings}
>
<section class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="rounded-3xl border border-[var(--border-color)] bg-[var(--terminal-bg)] shadow-[0_28px_90px_rgba(15,23,42,0.08)] overflow-hidden">
<div class="flex items-center justify-between gap-4 border-b border-[var(--border-color)] px-5 py-4">

View File

@@ -37,8 +37,20 @@ let apiError: string | null = null;
const { locale, t } = getI18n(Astro);
try {
siteSettings = await api.getSiteSettings();
allPosts = await api.getPosts();
const [settings, posts, rawTags, rawFriendLinks, nextCategories] = await Promise.all([
api.getSiteSettings(),
api.getPosts(),
api.getTags(),
api.getFriendLinks(),
api.getCategories(),
]);
siteSettings = settings;
allPosts = posts;
tags = rawTags.map(tag => tag.name);
friendLinks = rawFriendLinks.filter(friend => friend.status === 'approved');
categories = nextCategories;
const filteredPosts = allPosts.filter(post => {
const normalizedCategory = post.category?.trim().toLowerCase() || '';
if (selectedType !== 'all' && post.type !== selectedType) return false;
@@ -50,9 +62,6 @@ try {
recentPosts = filteredPosts.slice(0, previewLimit);
filteredPostsCount = filteredPosts.length;
pinnedPost = allPosts.find(post => post.pinned) || null;
tags = (await api.getTags()).map(tag => tag.name);
friendLinks = (await api.getFriendLinks()).filter(friend => friend.status === 'approved');
categories = await api.getCategories();
} catch (error) {
apiError = error instanceof Error ? error.message : t('common.apiUnavailable');
console.error('API Error:', error);
@@ -146,7 +155,7 @@ const navLinks = [
];
---
<BaseLayout title={siteSettings.siteTitle} description={siteSettings.siteDescription}>
<BaseLayout title={siteSettings.siteTitle} description={siteSettings.siteDescription} siteSettings={siteSettings}>
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
<TerminalWindow title={terminalConfig.title} class="w-full">
<div class="mb-5 px-4 overflow-x-auto">