[feature/frontend] update person info
Some checks failed
Build Backend / Build Docker Image (push) Failing after 2m24s
Test Backend / test (push) Successful in 2m58s

This commit is contained in:
CDN 2025-02-21 20:04:30 +08:00
parent 79912925db
commit 7a33038af8
Signed by: CDN
GPG key ID: 0C656827F9F80080
21 changed files with 1436 additions and 217 deletions

View file

@ -1,5 +1,5 @@
import { FC } from 'react';
import { Link, Outlet, useLocation } from 'react-router-dom';
import { FC, useState, useEffect } from 'react';
import { Link, Outlet, useLocation, useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
RiFileTextLine,
@ -10,18 +10,26 @@ import {
RiSunLine,
RiMoonLine,
RiComputerLine,
RiGlobalLine
RiGlobalLine,
RiCalendarLine,
RiImageLine,
RiSettings3Line,
} from 'react-icons/ri';
import { useTheme } from '../../../hooks/useTheme';
import type { Theme } from '../../../hooks/useTheme';
import { Suspense } from 'react';
import LoadingSpinner from '../../../components/LoadingSpinner';
import { useUser } from '../../../contexts/UserContext';
interface AdminLayoutProps {}
const menuItems = [
{ path: '/admin/posts', icon: RiFileTextLine, label: 'admin.nav.posts' },
{ path: '/admin/daily', icon: RiCalendarLine, label: 'admin.nav.daily' },
{ path: '/admin/medias', icon: RiImageLine, label: 'admin.nav.medias' },
{ path: '/admin/categories', icon: RiFolderLine, label: 'admin.nav.categories' },
{ path: '/admin/users', icon: RiUserLine, label: 'admin.nav.users' },
{ path: '/admin/contributors', icon: RiTeamLine, label: 'admin.nav.contributors' },
{ path: '/admin/settings', icon: RiSettings3Line, label: 'admin.nav.settings' },
];
const themeOptions = [
@ -49,16 +57,29 @@ const languageMap: LanguageMap = {
};
const AdminLayout: FC<AdminLayoutProps> = () => {
const location = useLocation();
const { t, i18n } = useTranslation();
const location = useLocation();
const navigate = useNavigate();
const { theme, setTheme } = useTheme();
const { user, loading, error } = useUser();
useEffect(() => {
console.log('AdminLayout user:', user);
console.log('AdminLayout loading:', loading);
console.log('AdminLayout error:', error);
}, [user, loading, error]);
const handleLogout = () => {
localStorage.removeItem('token');
navigate('/admin/login');
};
return (
<div className="min-h-screen bg-slate-100 dark:bg-slate-900 py-6 flex">
{/* Background Overlay */}
<div className="fixed inset-0 bg-gradient-to-br from-slate-200 to-slate-300 dark:from-slate-800 dark:to-slate-900 backdrop-blur-xl -z-10" />
<div className="w-full max-w-[98%] mx-auto flex gap-4">
<div className="container max-w-[1920px] mx-auto px-2 flex gap-2">
{/* Sidebar */}
<aside className="w-64 bg-white/80 dark:bg-slate-800/80 backdrop-blur-lg rounded-lg shadow-lg flex flex-col">
<div className="h-16 px-6 border-b border-slate-200/80 dark:border-slate-700/80 flex items-center justify-center">
@ -103,7 +124,7 @@ const AdminLayout: FC<AdminLayoutProps> = () => {
</button>
<button
className="flex-1 flex items-center justify-center gap-2 px-3 py-2 rounded-md text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700/50 transition-colors whitespace-nowrap"
onClick={() => {/* TODO: Implement logout */}}
onClick={handleLogout}
>
<RiLogoutBoxRLine className="text-xl flex-shrink-0" />
<span className="text-sm">{t('admin.common.logout')}</span>
@ -145,18 +166,21 @@ const AdminLayout: FC<AdminLayoutProps> = () => {
</div>
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-slate-200 dark:bg-slate-700 rounded-full flex items-center justify-center text-slate-600 dark:text-slate-300">
<span className="text-lg">A</span>
<span className="text-lg">{(user?.display_name?.[0] || user?.username?.[0] || '?').toUpperCase()}</span>
</div>
<div>
<div className="text-slate-800 dark:text-white"></div>
<div className="text-sm text-slate-500 dark:text-slate-400">Administrator</div>
<div className="text-slate-800 dark:text-white">
{loading ? 'Loading...' : user?.display_name || user?.username || 'Guest'}
</div>
</div>
</div>
</div>
</header>
<div className="flex-1 p-6">
<div className="h-full bg-white dark:bg-slate-800 rounded-lg shadow-sm border border-slate-200/60 dark:border-slate-700/60">
<Outlet />
<Suspense fallback={<LoadingSpinner />}>
<Outlet />
</Suspense>
</div>
</div>
</main>