Fix file sharing load speed and move error; misc updates
- Remove recursive directory size calculations (single Seafile API call per list) - Remove 'Used in this location' usage display - Fix move using v2 per-type endpoints instead of broken batch endpoint - Send entry type from frontend for correct move routing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-70
@@ -5,47 +5,32 @@ import { useAuth } from '../context/AuthContext';
|
||||
|
||||
export default function Settings() {
|
||||
const { currentUser } = useAuth();
|
||||
const [form, setForm] = useState({
|
||||
name: currentUser?.name || '',
|
||||
company: currentUser?.company || '',
|
||||
});
|
||||
const [passwords, setPasswords] = useState({ current: '', next: '', confirm: '' });
|
||||
const [profileSaved, setProfileSaved] = useState(false);
|
||||
const [passwords, setPasswords] = useState({ next: '', confirm: '' });
|
||||
const [passwordSaved, setPasswordSaved] = useState(false);
|
||||
const [passwordError, setPasswordError] = useState('');
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [savingPw, setSavingPw] = useState(false);
|
||||
|
||||
const set = (field) => (e) => setForm(f => ({ ...f, [field]: e.target.value }));
|
||||
const setPw = (field) => (e) => setPasswords(p => ({ ...p, [field]: e.target.value }));
|
||||
|
||||
const handleProfileSave = async (e) => {
|
||||
e.preventDefault();
|
||||
setSaving(true);
|
||||
await supabase.from('profiles').update({
|
||||
name: form.name.trim(),
|
||||
company: form.company.trim(),
|
||||
}).eq('id', currentUser.id);
|
||||
setProfileSaved(true);
|
||||
setSaving(false);
|
||||
setTimeout(() => setProfileSaved(false), 3000);
|
||||
};
|
||||
|
||||
const handlePasswordSave = async (e) => {
|
||||
e.preventDefault();
|
||||
setPasswordError('');
|
||||
setPasswordSaved(false);
|
||||
if (passwords.next !== passwords.confirm) { setPasswordError('New passwords do not match.'); return; }
|
||||
if (passwords.next.length < 6) { setPasswordError('Password must be at least 6 characters.'); return; }
|
||||
setSavingPw(true);
|
||||
const { error } = await supabase.auth.updateUser({ password: passwords.next });
|
||||
if (error) { setPasswordError(error.message); setSavingPw(false); return; }
|
||||
setPasswords({ current: '', next: '', confirm: '' });
|
||||
setPasswordSaved(true);
|
||||
setSavingPw(false);
|
||||
setTimeout(() => setPasswordSaved(false), 3000);
|
||||
try {
|
||||
const { error } = await supabase.auth.updateUser({ password: passwords.next });
|
||||
if (error) { setPasswordError(error.message); return; }
|
||||
setPasswords({ next: '', confirm: '' });
|
||||
setPasswordSaved(true);
|
||||
setTimeout(() => setPasswordSaved(false), 3000);
|
||||
} finally {
|
||||
setSavingPw(false);
|
||||
}
|
||||
};
|
||||
|
||||
const initials = form.name
|
||||
const initials = (currentUser?.name || '')
|
||||
.split(' ')
|
||||
.map(n => n[0])
|
||||
.join('')
|
||||
@@ -56,63 +41,26 @@ export default function Settings() {
|
||||
<Layout>
|
||||
<div className="page-header">
|
||||
<div>
|
||||
<div className="page-title">Profile & Settings</div>
|
||||
<div className="page-subtitle">Update your name, company, and password.</div>
|
||||
<div className="page-title">Settings</div>
|
||||
<div className="page-subtitle">Your account info and password.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ maxWidth: 520, display: 'flex', flexDirection: 'column', gap: 24 }}>
|
||||
|
||||
{/* Avatar preview */}
|
||||
<div className="card" style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<div className="sidebar-avatar" style={{ width: 56, height: 56, fontSize: 20, flexShrink: 0 }}>
|
||||
{initials || '?'}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontWeight: 700, fontSize: 15 }}>{form.name || 'Your Name'}</div>
|
||||
<div style={{ fontWeight: 700, fontSize: 15 }}>{currentUser?.name || '—'}</div>
|
||||
<div style={{ fontSize: 13, color: 'var(--text-secondary)' }}>{currentUser?.email}</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 2, textTransform: 'capitalize' }}>{currentUser?.role}</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 2, textTransform: 'capitalize' }}>
|
||||
{currentUser?.role}{currentUser?.company?.name ? ` · ${currentUser.company.name}` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Profile form */}
|
||||
<div className="card">
|
||||
<div className="card-title">Profile Info</div>
|
||||
<form onSubmit={handleProfileSave}>
|
||||
<div className="form-group">
|
||||
<label>Full Name *</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="First Last"
|
||||
value={form.name}
|
||||
onChange={set('name')}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Company / Organization</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Your company"
|
||||
value={form.company}
|
||||
onChange={set('company')}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Email Address</label>
|
||||
<input type="email" value={currentUser?.email} disabled style={{ opacity: 0.6, cursor: 'not-allowed' }} />
|
||||
<div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 4 }}>Contact Fourge to change your email.</div>
|
||||
</div>
|
||||
{profileSaved && (
|
||||
<div className="notification notification-success" style={{ marginBottom: 12 }}>✓ Profile updated.</div>
|
||||
)}
|
||||
<button type="submit" className="btn btn-primary" disabled={saving}>
|
||||
{saving ? 'Saving...' : 'Save Changes'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{/* Password form */}
|
||||
<div className="card">
|
||||
<div className="card-title">Change Password</div>
|
||||
<form onSubmit={handlePasswordSave}>
|
||||
|
||||
Reference in New Issue
Block a user