feat: add admin profile editing capability

Added admin endpoint and functionality for editing user profiles from the
report management interface:

Backend Changes:
- Added PUT /api/users/:id endpoint for admin-only profile editing
- Reuses existing updateUserSettings logic with slug uniqueness validation
- Protected with adminGuard and csrfProtection
- Proper audit logging for admin profile edits

Frontend Changes:
- Added adminUpdateUser() method to UserService
- Updated editProfile() in admin-reports to load profile and allow bio editing
- Uses prompt for quick bio editing (can be expanded to full form later)
- Shows success/error toasts and refreshes report list after edit

Admins can now quickly edit reported user profiles directly from the
report management interface.
This commit is contained in:
2026-02-19 20:05:57 -08:00
committed by Naomi Carrigan
parent 6e884b9ae8
commit c154ef1897
3 changed files with 61 additions and 3 deletions
@@ -1529,10 +1529,30 @@ export class AdminReportsComponent implements OnInit {
editProfile(report: ProfileReportWithUsers): void {
const userId = report.reportedUser.id;
const username = report.reportedUser.username;
// Navigate to profile page using ObjectId
this.router.navigate(['/profile', userId]);
this.toastService.success('Navigate to profile to edit');
// Load the full profile first to get current values
this.userService.getProfile(userId).subscribe({
next: (profile) => {
const newBio = prompt(`Edit bio for ${username}:`, profile.bio || '');
if (newBio !== null) {
this.userService.adminUpdateUser(userId, { bio: newBio }).subscribe({
next: () => {
this.toastService.success('Profile updated successfully');
this.loadReports();
this.closeProfileReviewModal();
},
error: (err) => {
this.toastService.error(err.message ?? 'Failed to update profile');
}
});
}
},
error: (err) => {
this.toastService.error(err.message ?? 'Failed to load profile');
}
});
}
makeProfilePrivate(report: ProfileReportWithUsers): void {
@@ -85,4 +85,8 @@ export class UserService {
makeProfilePrivate(userId: string): Observable<User> {
return this.api.post<User>(`/users/${userId}/make-private`, {});
}
adminUpdateUser(userId: string, settings: UpdateUserSettingsRequest): Observable<User> {
return this.api.put<User>(`/users/${userId}`, settings);
}
}