️ feat: add post fetching by ID and improve blog home page

- Implemented `getPostById` API function to fetch a post by its ID.
- Refactored the main page to use a new `BlogHome` component for better organization.
- Added loading state and sorting functionality for posts on the blog home page.
- Integrated label fetching and display on the blog home page.
- Enhanced the blog card component with improved layout and statistics display.
- Updated the navbar to use dynamic configuration values.
- Added Docker support with a comprehensive build and push workflow.
- Created a custom hook `useStoredState` for managing local storage state.
- Added a new page for displaying individual posts with metadata generation.
- Removed unused components and files to streamline the codebase.
This commit is contained in:
2025-07-25 03:58:53 +08:00
parent abe1099711
commit 5fac42439a
24 changed files with 752 additions and 338 deletions

View File

@ -0,0 +1,35 @@
import { useState, useEffect, useCallback } from 'react';
export function useStoredState<T>(key: string, defaultValue: T) {
const [value, setValue] = useState<T>(defaultValue);
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
try {
const stored = localStorage.getItem(key);
if (stored) {
try {
setValue(JSON.parse(stored));
} catch {
setValue(stored as T);
}
}
} catch (error) {
console.error('Error reading from localStorage:', error);
} finally {
setIsLoaded(true);
}
}, [key]);
// 使用 useCallback 确保 setter 函数引用稳定
const setStoredValue = useCallback((newValue: T) => {
setValue(newValue);
try {
localStorage.setItem(key, typeof newValue === 'string' ? newValue : JSON.stringify(newValue));
} catch (error) {
console.error('Error writing to localStorage:', error);
}
}, [key]);
return [value, setStoredValue, isLoaded] as const;
}