diff --git a/backend/app/api/routes/notification_templates.py b/backend/app/api/routes/notification_templates.py index 2e1fbb9c0..55371e96f 100644 --- a/backend/app/api/routes/notification_templates.py +++ b/backend/app/api/routes/notification_templates.py @@ -43,6 +43,9 @@ EVENT_NAMES = { "queue_job_skipped": "Queue Job Skipped", "queue_job_failed": "Queue Job Failed", "queue_completed": "Queue Completed", + # User management + "user_created": "Welcome Email", + "password_reset": "Password Reset", } diff --git a/backend/app/models/notification_template.py b/backend/app/models/notification_template.py index fb21b9456..811a034f2 100644 --- a/backend/app/models/notification_template.py +++ b/backend/app/models/notification_template.py @@ -146,4 +146,16 @@ DEFAULT_TEMPLATES = [ "title_template": "Queue Complete", "body_template": "All {completed_count} queued jobs have finished", }, + { + "event_type": "user_created", + "name": "Welcome Email", + "title_template": "Welcome to {app_name}", + "body_template": "Welcome {username}!\n\nYour account has been created.\nUsername: {username}\nPassword: {password}\n\nLogin at: {login_url}", + }, + { + "event_type": "password_reset", + "name": "Password Reset", + "title_template": "{app_name} - Password Reset", + "body_template": "Hello {username},\n\nYour password has been reset.\nNew Password: {password}\n\nLogin at: {login_url}", + }, ] diff --git a/backend/app/schemas/notification_template.py b/backend/app/schemas/notification_template.py index c3f0467ef..754371b85 100644 --- a/backend/app/schemas/notification_template.py +++ b/backend/app/schemas/notification_template.py @@ -53,6 +53,9 @@ EVENT_VARIABLES: dict[str, list[str]] = { "queue_job_skipped": ["printer", "job_name", "reason", "timestamp", "app_name"], "queue_job_failed": ["printer", "job_name", "reason", "timestamp", "app_name"], "queue_completed": ["completed_count", "timestamp", "app_name"], + # User management notifications + "user_created": ["username", "password", "login_url", "app_name", "timestamp"], + "password_reset": ["username", "password", "login_url", "app_name", "timestamp"], } # Sample data for previewing templates @@ -191,6 +194,21 @@ SAMPLE_DATA: dict[str, dict[str, str]] = { "timestamp": "2024-01-15 18:30", "app_name": "Bambuddy", }, + # User management notifications + "user_created": { + "username": "john_doe", + "password": "TempPass123!", + "login_url": "https://bambuddy.example.com/login", + "app_name": "Bambuddy", + "timestamp": "2024-01-15 14:30", + }, + "password_reset": { + "username": "john_doe", + "password": "NewPass456!", + "login_url": "https://bambuddy.example.com/login", + "app_name": "Bambuddy", + "timestamp": "2024-01-15 14:30", + }, } diff --git a/frontend/src/pages/SettingsPage.tsx b/frontend/src/pages/SettingsPage.tsx index afe07ef15..bc8b293b9 100644 --- a/frontend/src/pages/SettingsPage.tsx +++ b/frontend/src/pages/SettingsPage.tsx @@ -380,6 +380,16 @@ export function SettingsPage() { }, }); + const resetPasswordMutation = useMutation({ + mutationFn: (userId: number) => api.resetUserPassword({ user_id: userId }), + onSuccess: (response) => { + showToast(response.message, 'success'); + }, + onError: (error: Error) => { + showToast(error.message, 'error'); + }, + }); + // Function to initiate user deletion with item count check const handleDeleteUserClick = async (userId: number) => { setDeleteUserId(userId); @@ -501,6 +511,7 @@ export function SettingsPage() { setUserFormData({ username: userToEdit.username, password: '', + email: userToEdit.email || '', confirmPassword: '', role: userToEdit.role, group_ids: userToEdit.groups?.map(g => g.id) || [], @@ -946,7 +957,7 @@ export function SettingsPage() { {/* Tab Navigation */} -