[feature/frontend] update person info
This commit is contained in:
parent
79912925db
commit
7a33038af8
21 changed files with 1436 additions and 217 deletions
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue