perf: optimize web data resources
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { getUserProfile, updateUserProfile, uploadAvatar, type UserProfile } from '../lib/api';
|
||||
import { getAuth } from '../lib/auth';
|
||||
import { updateProfileResource, uploadAvatarResource, useProfile } from '../lib/resources';
|
||||
|
||||
interface Props {
|
||||
locale: string;
|
||||
@@ -57,28 +57,25 @@ async function compressImage(file: File, maxWidth = 512, maxHeight = 512, qualit
|
||||
|
||||
export default function ProfileDetailPage({ locale, profile: p }: Props) {
|
||||
const navigate = useNavigate();
|
||||
const [profile, setProfile] = useState<UserProfile | null>(null);
|
||||
const profileState = useProfile();
|
||||
const profile = profileState.data ?? null;
|
||||
const [displayName, setDisplayName] = useState('');
|
||||
const [bio, setBio] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [success, setSuccess] = useState<string | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
// Load profile on mount
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
getUserProfile()
|
||||
.then((data) => {
|
||||
setProfile(data);
|
||||
setDisplayName(data.display_name || '');
|
||||
setBio(data.bio || '');
|
||||
})
|
||||
.catch((err) => setError(err.message || 'Failed to load profile'))
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
if (!profileState.data) return;
|
||||
setDisplayName(profileState.data.display_name || '');
|
||||
setBio(profileState.data.bio || '');
|
||||
}, [profileState.data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (profileState.error instanceof Error) setError(profileState.error.message || 'Failed to load profile');
|
||||
}, [profileState.error]);
|
||||
|
||||
// Clear messages after 3 seconds
|
||||
useEffect(() => {
|
||||
@@ -92,7 +89,7 @@ export default function ProfileDetailPage({ locale, profile: p }: Props) {
|
||||
setSaving(true);
|
||||
setError(null);
|
||||
try {
|
||||
await updateUserProfile({
|
||||
await updateProfileResource({
|
||||
display_name: displayName || undefined,
|
||||
bio: bio || undefined,
|
||||
});
|
||||
@@ -134,8 +131,7 @@ export default function ProfileDetailPage({ locale, profile: p }: Props) {
|
||||
throw new Error(locale === 'en' ? 'Image too large, please choose a smaller one' : '图片太大,请选择更小的图片');
|
||||
}
|
||||
|
||||
const updated = await uploadAvatar(compressedFile);
|
||||
setProfile(updated);
|
||||
await uploadAvatarResource(compressedFile);
|
||||
setSuccess(locale === 'en' ? 'Avatar updated' : '头像已更新');
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to upload');
|
||||
@@ -146,7 +142,7 @@ export default function ProfileDetailPage({ locale, profile: p }: Props) {
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
if (profileState.loading) {
|
||||
return (
|
||||
<div className="flex flex-col gap-6 min-h-full">
|
||||
<div className="text-slate-500">{locale === 'en' ? 'Loading...' : '加载中...'}</div>
|
||||
|
||||
Reference in New Issue
Block a user