feat(quick-260630-gbh-01): account settings page — avatar upload + conditional password form
- AuthUser interface: add isLocalUser? + hasAvatar? fields - uploadAvatarAction: server action forwarding file to POST /users/me/avatar - AccountSettingsForm: avatar preview with initial fallback + upload; password form only for local users; LDAP notice - /settings/general/account page mirroring smtp page structure - SettingsSidebar: Konto link above SMTP link - de.json + en.json: categoryAccount + account.* keys
This commit is contained in:
@@ -12,6 +12,8 @@ export interface AuthUser {
|
||||
role: 'SUPER_ADMIN' | 'ADMIN' | 'USER';
|
||||
tenantId: string;
|
||||
mustChangePassword: boolean;
|
||||
isLocalUser?: boolean;
|
||||
hasAvatar?: boolean;
|
||||
}
|
||||
|
||||
export interface LoginResult {
|
||||
@@ -157,6 +159,47 @@ export async function changePasswordAction(
|
||||
redirect('/');
|
||||
}
|
||||
|
||||
export interface UploadAvatarResult {
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a profile picture for the currently authenticated user.
|
||||
* Forwards the multipart file to POST /users/me/avatar using the session cookie.
|
||||
* Returns a discriminated result — does NOT redirect.
|
||||
*/
|
||||
export async function uploadAvatarAction(
|
||||
formData: FormData,
|
||||
): Promise<UploadAvatarResult> {
|
||||
const cookieStore = await cookies();
|
||||
const session = cookieStore.get('session')?.value;
|
||||
|
||||
if (!session) {
|
||||
return { success: false, error: 'notAuthenticated' };
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/users/me/avatar`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Cookie: `session=${session}`,
|
||||
},
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => null);
|
||||
return { success: false, error: data?.message ?? 'uploadError' };
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
console.error('[uploadAvatarAction] fetch threw:', err);
|
||||
return { success: false, error: 'networkError' };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current authenticated user from the API.
|
||||
* Uses the session cookie for authentication.
|
||||
|
||||
Reference in New Issue
Block a user