hazo_auth 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +383 -774
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +5 -0
- package/dist/components/layouts/email_verification/config/email_verification_field_config.d.ts +23 -0
- package/dist/components/layouts/email_verification/config/email_verification_field_config.d.ts.map +1 -0
- package/dist/components/layouts/email_verification/config/email_verification_field_config.js +44 -0
- package/dist/components/layouts/email_verification/hooks/use_email_verification.d.ts +31 -0
- package/dist/components/layouts/email_verification/hooks/use_email_verification.d.ts.map +1 -0
- package/dist/components/layouts/email_verification/hooks/use_email_verification.js +222 -0
- package/dist/components/layouts/email_verification/index.d.ts +23 -0
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -0
- package/dist/components/layouts/email_verification/index.js +61 -0
- package/dist/components/layouts/forgot_password/config/forgot_password_field_config.d.ts +10 -0
- package/dist/components/layouts/forgot_password/config/forgot_password_field_config.d.ts.map +1 -0
- package/dist/components/layouts/forgot_password/config/forgot_password_field_config.js +33 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts +22 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts.map +1 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.js +127 -0
- package/dist/components/layouts/forgot_password/index.d.ts +18 -0
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -0
- package/dist/components/layouts/forgot_password/index.js +43 -0
- package/dist/components/layouts/index.d.ts +16 -0
- package/dist/components/layouts/index.d.ts.map +1 -0
- package/dist/components/layouts/index.js +11 -0
- package/dist/components/layouts/login/config/login_field_config.d.ts +11 -0
- package/dist/components/layouts/login/config/login_field_config.d.ts.map +1 -0
- package/dist/components/layouts/login/config/login_field_config.js +42 -0
- package/dist/components/layouts/login/hooks/use_login_form.d.ts +34 -0
- package/dist/components/layouts/login/hooks/use_login_form.d.ts.map +1 -0
- package/dist/components/layouts/login/hooks/use_login_form.js +196 -0
- package/dist/components/layouts/login/index.d.ts +31 -0
- package/dist/components/layouts/login/index.d.ts.map +1 -0
- package/dist/components/layouts/login/index.js +58 -0
- package/dist/components/layouts/my_settings/components/editable_field.d.ts +19 -0
- package/dist/components/layouts/my_settings/components/editable_field.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/editable_field.js +73 -0
- package/dist/components/layouts/my_settings/components/password_change_dialog.d.ts +28 -0
- package/dist/components/layouts/my_settings/components/password_change_dialog.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/password_change_dialog.js +138 -0
- package/dist/components/layouts/my_settings/components/profile_picture_dialog.d.ts +42 -0
- package/dist/components/layouts/my_settings/components/profile_picture_dialog.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_dialog.js +198 -0
- package/dist/components/layouts/my_settings/components/profile_picture_display.d.ts +16 -0
- package/dist/components/layouts/my_settings/components/profile_picture_display.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_display.js +33 -0
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.d.ts +17 -0
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.js +48 -0
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts +21 -0
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +144 -0
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.d.ts +23 -0
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.js +169 -0
- package/dist/components/layouts/my_settings/config/my_settings_field_config.d.ts +19 -0
- package/dist/components/layouts/my_settings/config/my_settings_field_config.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/config/my_settings_field_config.js +26 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts +46 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.js +354 -0
- package/dist/components/layouts/my_settings/index.d.ts +64 -0
- package/dist/components/layouts/my_settings/index.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/index.js +65 -0
- package/dist/components/layouts/register/config/register_field_config.d.ts +14 -0
- package/dist/components/layouts/register/config/register_field_config.d.ts.map +1 -0
- package/dist/components/layouts/register/config/register_field_config.js +69 -0
- package/dist/components/layouts/register/hooks/use_register_form.d.ts +30 -0
- package/dist/components/layouts/register/hooks/use_register_form.d.ts.map +1 -0
- package/dist/components/layouts/register/hooks/use_register_form.js +184 -0
- package/dist/components/layouts/register/index.d.ts +23 -0
- package/dist/components/layouts/register/index.d.ts.map +1 -0
- package/dist/components/layouts/register/index.js +58 -0
- package/dist/components/layouts/reset_password/config/reset_password_field_config.d.ts +13 -0
- package/dist/components/layouts/reset_password/config/reset_password_field_config.d.ts.map +1 -0
- package/dist/components/layouts/reset_password/config/reset_password_field_config.js +53 -0
- package/dist/components/layouts/reset_password/hooks/use_reset_password_form.d.ts +28 -0
- package/dist/components/layouts/reset_password/hooks/use_reset_password_form.d.ts.map +1 -0
- package/dist/components/layouts/reset_password/hooks/use_reset_password_form.js +201 -0
- package/dist/components/layouts/reset_password/index.d.ts +23 -0
- package/dist/components/layouts/reset_password/index.d.ts.map +1 -0
- package/dist/components/layouts/reset_password/index.js +53 -0
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts +20 -0
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/already_logged_in_guard.js +32 -0
- package/dist/components/layouts/shared/components/auth_page_shell.d.ts +7 -0
- package/dist/components/layouts/shared/components/auth_page_shell.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/auth_page_shell.js +12 -0
- package/dist/components/layouts/shared/components/field_error_message.d.ts +7 -0
- package/dist/components/layouts/shared/components/field_error_message.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/field_error_message.js +6 -0
- package/dist/components/layouts/shared/components/form_action_buttons.d.ts +14 -0
- package/dist/components/layouts/shared/components/form_action_buttons.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/form_action_buttons.js +15 -0
- package/dist/components/layouts/shared/components/form_field_wrapper.d.ts +11 -0
- package/dist/components/layouts/shared/components/form_field_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/form_field_wrapper.js +9 -0
- package/dist/components/layouts/shared/components/form_header.d.ts +10 -0
- package/dist/components/layouts/shared/components/form_header.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/form_header.js +5 -0
- package/dist/components/layouts/shared/components/logout_button.d.ts +7 -0
- package/dist/components/layouts/shared/components/logout_button.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/logout_button.js +44 -0
- package/dist/components/layouts/shared/components/password_field.d.ts +13 -0
- package/dist/components/layouts/shared/components/password_field.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/password_field.js +13 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts +22 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/profile_pic_menu.js +169 -0
- package/dist/components/layouts/shared/components/profile_pic_menu_wrapper.d.ts +12 -0
- package/dist/components/layouts/shared/components/profile_pic_menu_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/profile_pic_menu_wrapper.js +16 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts +6 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +15 -0
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts +11 -0
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/standalone_layout_wrapper.js +10 -0
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts +12 -0
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/two_column_auth_layout.js +8 -0
- package/dist/components/layouts/shared/components/unauthorized_guard.d.ts +14 -0
- package/dist/components/layouts/shared/components/unauthorized_guard.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/unauthorized_guard.js +30 -0
- package/dist/components/layouts/shared/components/visual_panel.d.ts +9 -0
- package/dist/components/layouts/shared/components/visual_panel.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/visual_panel.js +10 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +38 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -0
- package/dist/components/layouts/shared/config/layout_customization.js +19 -0
- package/dist/components/layouts/shared/data/layout_data_client.d.ts +6 -0
- package/dist/components/layouts/shared/data/layout_data_client.d.ts.map +1 -0
- package/dist/components/layouts/shared/data/layout_data_client.js +9 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.d.ts +20 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.d.ts.map +1 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.js +71 -0
- package/dist/components/layouts/shared/hooks/use_hazo_auth.d.ts +48 -0
- package/dist/components/layouts/shared/hooks/use_hazo_auth.d.ts.map +1 -0
- package/dist/components/layouts/shared/hooks/use_hazo_auth.js +90 -0
- package/dist/components/layouts/shared/index.d.ts +24 -0
- package/dist/components/layouts/shared/index.d.ts.map +1 -0
- package/dist/components/layouts/shared/index.js +27 -0
- package/dist/components/layouts/shared/utils/ip_address.d.ts +7 -0
- package/dist/components/layouts/shared/utils/ip_address.d.ts.map +1 -0
- package/dist/components/layouts/shared/utils/ip_address.js +34 -0
- package/dist/components/layouts/shared/utils/validation.d.ts +15 -0
- package/dist/components/layouts/shared/utils/validation.d.ts.map +1 -0
- package/dist/components/layouts/shared/utils/validation.js +45 -0
- package/dist/components/layouts/user_management/components/roles_matrix.d.ts +29 -0
- package/dist/components/layouts/user_management/components/roles_matrix.d.ts.map +1 -0
- package/dist/components/layouts/user_management/components/roles_matrix.js +287 -0
- package/dist/components/layouts/user_management/index.d.ts +13 -0
- package/dist/components/layouts/user_management/index.d.ts.map +1 -0
- package/dist/components/layouts/user_management/index.js +495 -0
- package/dist/components/ui/alert-dialog.d.ts +21 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +62 -0
- package/dist/components/ui/avatar.d.ts +7 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +32 -0
- package/dist/components/ui/button.d.ts +12 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +45 -0
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +23 -0
- package/dist/components/ui/dialog.d.ts +20 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +52 -0
- package/dist/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +72 -0
- package/dist/components/ui/hazo_ui_tooltip.d.ts +26 -0
- package/dist/components/ui/hazo_ui_tooltip.d.ts.map +1 -0
- package/dist/components/ui/hazo_ui_tooltip.js +17 -0
- package/dist/components/ui/index.d.ts +20 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +21 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +20 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +24 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +22 -0
- package/dist/components/ui/sheet.d.ts +23 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +66 -0
- package/dist/components/ui/sidebar.d.ts +66 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +267 -0
- package/dist/components/ui/skeleton.d.ts +3 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +18 -0
- package/dist/components/ui/sonner.d.ts +5 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/sonner.js +28 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +22 -0
- package/dist/components/ui/table.d.ts +11 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +55 -0
- package/dist/components/ui/tabs.d.ts +8 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +33 -0
- package/dist/components/ui/tooltip.d.ts +8 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +25 -0
- package/dist/components/ui/vertical-tabs.d.ts +8 -0
- package/dist/components/ui/vertical-tabs.d.ts.map +1 -0
- package/dist/components/ui/vertical-tabs.js +37 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/lib/already_logged_in_config.server.d.ts +14 -0
- package/dist/lib/already_logged_in_config.server.d.ts.map +1 -0
- package/dist/lib/already_logged_in_config.server.js +29 -0
- package/dist/lib/app_logger.d.ts +12 -0
- package/dist/lib/app_logger.d.ts.map +1 -0
- package/dist/lib/app_logger.js +14 -0
- package/dist/lib/auth/auth_cache.d.ts +83 -0
- package/dist/lib/auth/auth_cache.d.ts.map +1 -0
- package/dist/lib/auth/auth_cache.js +158 -0
- package/dist/lib/auth/auth_rate_limiter.d.ts +39 -0
- package/dist/lib/auth/auth_rate_limiter.d.ts.map +1 -0
- package/dist/lib/auth/auth_rate_limiter.js +95 -0
- package/dist/lib/auth/auth_types.d.ts +53 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -0
- package/dist/lib/auth/auth_types.js +16 -0
- package/dist/lib/auth/auth_utils.server.d.ts +47 -0
- package/dist/lib/auth/auth_utils.server.d.ts.map +1 -0
- package/dist/lib/auth/auth_utils.server.js +150 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts +12 -0
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -0
- package/dist/lib/auth/hazo_get_auth.server.js +256 -0
- package/dist/lib/auth/index.d.ts +9 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +12 -0
- package/dist/lib/auth/server_auth.d.ts +26 -0
- package/dist/lib/auth/server_auth.d.ts.map +1 -0
- package/dist/lib/auth/server_auth.js +62 -0
- package/dist/lib/auth_utility_config.server.d.ts +20 -0
- package/dist/lib/auth_utility_config.server.d.ts.map +1 -0
- package/dist/lib/auth_utility_config.server.js +64 -0
- package/dist/lib/config/config_loader.server.d.ts +44 -0
- package/dist/lib/config/config_loader.server.d.ts.map +1 -0
- package/dist/lib/config/config_loader.server.js +122 -0
- package/dist/lib/email_verification_config.server.d.ts +14 -0
- package/dist/lib/email_verification_config.server.d.ts.map +1 -0
- package/dist/lib/email_verification_config.server.js +20 -0
- package/dist/lib/file_types_config.server.d.ts +11 -0
- package/dist/lib/file_types_config.server.d.ts.map +1 -0
- package/dist/lib/file_types_config.server.js +16 -0
- package/dist/lib/forgot_password_config.server.d.ts +14 -0
- package/dist/lib/forgot_password_config.server.d.ts.map +1 -0
- package/dist/lib/forgot_password_config.server.js +20 -0
- package/dist/lib/hazo_connect_instance.server.d.ts +17 -0
- package/dist/lib/hazo_connect_instance.server.d.ts.map +1 -0
- package/dist/lib/hazo_connect_instance.server.js +88 -0
- package/dist/lib/hazo_connect_setup.d.ts +2 -0
- package/dist/lib/hazo_connect_setup.d.ts.map +1 -0
- package/dist/lib/hazo_connect_setup.js +49 -0
- package/dist/lib/hazo_connect_setup.server.d.ts +20 -0
- package/dist/lib/hazo_connect_setup.server.d.ts.map +1 -0
- package/dist/lib/hazo_connect_setup.server.js +138 -0
- package/dist/lib/index.d.ts +28 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +35 -0
- package/dist/lib/login_config.server.d.ts +20 -0
- package/dist/lib/login_config.server.d.ts.map +1 -0
- package/dist/lib/login_config.server.js +37 -0
- package/dist/lib/messages_config.server.d.ts +13 -0
- package/dist/lib/messages_config.server.d.ts.map +1 -0
- package/dist/lib/messages_config.server.js +18 -0
- package/dist/lib/migrations/apply_migration.d.ts +22 -0
- package/dist/lib/migrations/apply_migration.d.ts.map +1 -0
- package/dist/lib/migrations/apply_migration.js +78 -0
- package/dist/lib/my_settings_config.server.d.ts +65 -0
- package/dist/lib/my_settings_config.server.d.ts.map +1 -0
- package/dist/lib/my_settings_config.server.js +67 -0
- package/dist/lib/password_requirements_config.server.d.ts +15 -0
- package/dist/lib/password_requirements_config.server.d.ts.map +1 -0
- package/dist/lib/password_requirements_config.server.js +26 -0
- package/dist/lib/profile_pic_menu_config.server.d.ts +26 -0
- package/dist/lib/profile_pic_menu_config.server.d.ts.map +1 -0
- package/dist/lib/profile_pic_menu_config.server.js +95 -0
- package/dist/lib/profile_picture_config.server.d.ts +16 -0
- package/dist/lib/profile_picture_config.server.d.ts.map +1 -0
- package/dist/lib/profile_picture_config.server.js +40 -0
- package/dist/lib/register_config.server.d.ts +24 -0
- package/dist/lib/register_config.server.d.ts.map +1 -0
- package/dist/lib/register_config.server.js +39 -0
- package/dist/lib/reset_password_config.server.d.ts +25 -0
- package/dist/lib/reset_password_config.server.d.ts.map +1 -0
- package/dist/lib/reset_password_config.server.js +38 -0
- package/dist/lib/services/email_service.d.ts +44 -0
- package/dist/lib/services/email_service.d.ts.map +1 -0
- package/dist/lib/services/email_service.js +480 -0
- package/dist/lib/services/email_verification_service.d.ts +35 -0
- package/dist/lib/services/email_verification_service.d.ts.map +1 -0
- package/dist/lib/services/email_verification_service.js +208 -0
- package/dist/lib/services/index.d.ts +13 -0
- package/dist/lib/services/index.d.ts.map +1 -0
- package/dist/lib/services/index.js +14 -0
- package/dist/lib/services/login_service.d.ts +20 -0
- package/dist/lib/services/login_service.d.ts.map +1 -0
- package/dist/lib/services/login_service.js +94 -0
- package/dist/lib/services/password_change_service.d.ts +19 -0
- package/dist/lib/services/password_change_service.d.ts.map +1 -0
- package/dist/lib/services/password_change_service.js +118 -0
- package/dist/lib/services/password_reset_service.d.ts +52 -0
- package/dist/lib/services/password_reset_service.d.ts.map +1 -0
- package/dist/lib/services/password_reset_service.js +318 -0
- package/dist/lib/services/profile_picture_remove_service.d.ts +15 -0
- package/dist/lib/services/profile_picture_remove_service.d.ts.map +1 -0
- package/dist/lib/services/profile_picture_remove_service.js +94 -0
- package/dist/lib/services/profile_picture_service.d.ts +45 -0
- package/dist/lib/services/profile_picture_service.d.ts.map +1 -0
- package/dist/lib/services/profile_picture_service.js +183 -0
- package/dist/lib/services/profile_picture_source_mapper.d.ts +23 -0
- package/dist/lib/services/profile_picture_source_mapper.d.ts.map +1 -0
- package/dist/lib/services/profile_picture_source_mapper.js +45 -0
- package/dist/lib/services/registration_service.d.ts +20 -0
- package/dist/lib/services/registration_service.d.ts.map +1 -0
- package/dist/lib/services/registration_service.js +147 -0
- package/dist/lib/services/token_service.d.ts +20 -0
- package/dist/lib/services/token_service.d.ts.map +1 -0
- package/dist/lib/services/token_service.js +201 -0
- package/dist/lib/services/user_profiles_service.d.ts +31 -0
- package/dist/lib/services/user_profiles_service.d.ts.map +1 -0
- package/dist/lib/services/user_profiles_service.js +99 -0
- package/dist/lib/services/user_update_service.d.ts +23 -0
- package/dist/lib/services/user_update_service.d.ts.map +1 -0
- package/dist/lib/services/user_update_service.js +103 -0
- package/dist/lib/ui_shell_config.server.d.ts +16 -0
- package/dist/lib/ui_shell_config.server.d.ts.map +1 -0
- package/dist/lib/ui_shell_config.server.js +28 -0
- package/dist/lib/ui_sizes_config.server.d.ts +17 -0
- package/dist/lib/ui_sizes_config.server.d.ts.map +1 -0
- package/dist/lib/ui_sizes_config.server.js +22 -0
- package/dist/lib/user_fields_config.server.d.ts +13 -0
- package/dist/lib/user_fields_config.server.d.ts.map +1 -0
- package/dist/lib/user_fields_config.server.js +21 -0
- package/dist/lib/user_management_config.server.d.ts +10 -0
- package/dist/lib/user_management_config.server.d.ts.map +1 -0
- package/dist/lib/user_management_config.server.js +26 -0
- package/dist/lib/utils/api_route_helpers.d.ts +13 -0
- package/dist/lib/utils/api_route_helpers.d.ts.map +1 -0
- package/dist/lib/utils/api_route_helpers.js +58 -0
- package/dist/lib/utils/error_sanitizer.d.ts +16 -0
- package/dist/lib/utils/error_sanitizer.d.ts.map +1 -0
- package/dist/lib/utils/error_sanitizer.js +39 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/server/config/config_loader.d.ts +26 -0
- package/dist/server/config/config_loader.d.ts.map +1 -0
- package/dist/server/config/config_loader.js +329 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +32 -0
- package/dist/server/logging/logger_service.d.ts +3 -0
- package/dist/server/logging/logger_service.d.ts.map +1 -0
- package/dist/server/logging/logger_service.js +37 -0
- package/dist/server/routes/root_router.d.ts +3 -0
- package/dist/server/routes/root_router.d.ts.map +1 -0
- package/dist/server/routes/root_router.js +14 -0
- package/dist/server/server.d.ts +3 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +25 -0
- package/dist/server/types/app_types.d.ts +53 -0
- package/dist/server/types/app_types.d.ts.map +1 -0
- package/dist/server/types/app_types.js +1 -0
- package/migrations/003_add_url_on_logon_to_hazo_users.sql +8 -0
- package/next.config.mjs +12 -0
- package/package.json +38 -1
- package/src/components/index.ts +7 -0
- package/src/components/layouts/email_verification/config/email_verification_field_config.ts +2 -2
- package/src/components/layouts/email_verification/hooks/use_email_verification.ts +3 -3
- package/src/components/layouts/email_verification/index.tsx +11 -11
- package/src/components/layouts/forgot_password/config/forgot_password_field_config.ts +2 -2
- package/src/components/layouts/forgot_password/hooks/use_forgot_password_form.ts +3 -3
- package/src/components/layouts/forgot_password/index.tsx +10 -10
- package/src/components/layouts/index.ts +26 -0
- package/src/components/layouts/login/config/login_field_config.ts +2 -2
- package/src/components/layouts/login/hooks/use_login_form.ts +5 -5
- package/src/components/layouts/login/index.tsx +11 -11
- package/src/components/layouts/my_settings/components/editable_field.tsx +3 -3
- package/src/components/layouts/my_settings/components/password_change_dialog.tsx +5 -5
- package/src/components/layouts/my_settings/components/profile_picture_dialog.tsx +7 -7
- package/src/components/layouts/my_settings/components/profile_picture_display.tsx +2 -2
- package/src/components/layouts/my_settings/components/profile_picture_gravatar_tab.tsx +3 -3
- package/src/components/layouts/my_settings/components/profile_picture_library_tab.tsx +5 -5
- package/src/components/layouts/my_settings/components/profile_picture_upload_tab.tsx +4 -4
- package/src/components/layouts/my_settings/config/my_settings_field_config.ts +2 -2
- package/src/components/layouts/my_settings/hooks/use_my_settings.ts +2 -2
- package/src/components/layouts/my_settings/index.tsx +10 -10
- package/src/components/layouts/register/config/register_field_config.ts +2 -2
- package/src/components/layouts/register/hooks/use_register_form.ts +4 -4
- package/src/components/layouts/register/index.tsx +11 -11
- package/src/components/layouts/reset_password/config/reset_password_field_config.ts +2 -2
- package/src/components/layouts/reset_password/hooks/use_reset_password_form.ts +4 -4
- package/src/components/layouts/reset_password/index.tsx +10 -10
- package/src/components/layouts/shared/components/already_logged_in_guard.tsx +4 -4
- package/src/components/layouts/shared/components/auth_page_shell.tsx +3 -3
- package/src/components/layouts/shared/components/form_action_buttons.tsx +2 -2
- package/src/components/layouts/shared/components/form_field_wrapper.tsx +2 -2
- package/src/components/layouts/shared/components/logout_button.tsx +2 -2
- package/src/components/layouts/shared/components/password_field.tsx +3 -3
- package/src/components/layouts/shared/components/profile_pic_menu.tsx +5 -5
- package/src/components/layouts/shared/components/profile_pic_menu_wrapper.tsx +2 -2
- package/src/components/layouts/shared/components/sidebar_layout_wrapper.tsx +3 -3
- package/src/components/layouts/shared/components/standalone_layout_wrapper.tsx +1 -1
- package/src/components/layouts/shared/components/two_column_auth_layout.tsx +1 -1
- package/src/components/layouts/shared/components/unauthorized_guard.tsx +2 -2
- package/src/components/layouts/shared/hooks/use_hazo_auth.ts +1 -1
- package/src/components/layouts/shared/index.ts +34 -0
- package/src/components/layouts/shared/utils/validation.ts +1 -1
- package/src/components/layouts/user_management/components/roles_matrix.tsx +7 -7
- package/src/components/layouts/user_management/index.tsx +11 -11
- package/src/components/ui/alert-dialog.tsx +2 -2
- package/src/components/ui/avatar.tsx +1 -1
- package/src/components/ui/button.tsx +1 -1
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/dropdown-menu.tsx +1 -1
- package/src/components/ui/hazo_ui_tooltip.tsx +1 -1
- package/src/components/ui/index.ts +22 -0
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/separator.tsx +1 -1
- package/src/components/ui/sheet.tsx +1 -1
- package/src/components/ui/sidebar.tsx +8 -8
- package/src/components/ui/skeleton.tsx +1 -1
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/table.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -1
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/components/ui/vertical-tabs.tsx +1 -1
- package/src/index.ts +7 -0
- package/src/lib/already_logged_in_config.server.ts +1 -1
- package/src/lib/app_logger.ts +1 -1
- package/src/lib/auth/auth_cache.ts +1 -1
- package/src/lib/auth/auth_utils.server.ts +2 -2
- package/src/lib/auth/hazo_get_auth.server.ts +8 -8
- package/src/lib/auth/index.ts +23 -0
- package/src/lib/auth/server_auth.ts +2 -2
- package/src/lib/auth_utility_config.server.ts +1 -1
- package/src/lib/config/config_loader.server.ts +1 -1
- package/src/lib/email_verification_config.server.ts +1 -1
- package/src/lib/file_types_config.server.ts +1 -1
- package/src/lib/forgot_password_config.server.ts +1 -1
- package/src/lib/hazo_connect_instance.server.ts +2 -2
- package/src/lib/hazo_connect_setup.server.ts +2 -2
- package/src/lib/index.ts +44 -0
- package/src/lib/login_config.server.ts +2 -2
- package/src/lib/messages_config.server.ts +1 -1
- package/src/lib/my_settings_config.server.ts +7 -7
- package/src/lib/password_requirements_config.server.ts +1 -1
- package/src/lib/profile_pic_menu_config.server.ts +1 -1
- package/src/lib/profile_picture_config.server.ts +2 -2
- package/src/lib/register_config.server.ts +4 -4
- package/src/lib/reset_password_config.server.ts +3 -3
- package/src/lib/services/email_service.ts +2 -2
- package/src/lib/services/email_verification_service.ts +3 -3
- package/src/lib/services/index.ts +15 -0
- package/src/lib/services/login_service.ts +3 -3
- package/src/lib/services/password_change_service.ts +3 -3
- package/src/lib/services/password_reset_service.ts +3 -3
- package/src/lib/services/profile_picture_remove_service.ts +3 -3
- package/src/lib/services/profile_picture_service.ts +5 -5
- package/src/lib/services/registration_service.ts +8 -8
- package/src/lib/services/token_service.ts +2 -2
- package/src/lib/services/user_profiles_service.ts +2 -2
- package/src/lib/services/user_update_service.ts +4 -4
- package/src/lib/ui_shell_config.server.ts +1 -1
- package/src/lib/ui_sizes_config.server.ts +1 -1
- package/src/lib/user_fields_config.server.ts +1 -1
- package/src/lib/user_management_config.server.ts +1 -2
- package/src/lib/utils/error_sanitizer.ts +1 -1
- package/src/routes/index.ts +34 -0
- package/src/server/config/config_loader.ts +2 -2
- package/src/server/index.ts +2 -2
- package/src/server/logging/logger_service.ts +1 -1
- package/src/server/server.ts +2 -2
- package/src/server/types/express.d.ts +1 -1
- package/tsconfig.build.json +39 -0
- package/tsconfig.json +5 -1
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
// file_description: User Management layout component with three tabs for managing users, roles, and permissions
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useState, useEffect, useCallback } from "react";
|
|
7
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "hazo_auth/components/ui/tabs";
|
|
8
|
+
import { use_hazo_auth } from "hazo_auth/components/layouts/shared/hooks/use_hazo_auth";
|
|
9
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "hazo_auth/components/ui/table";
|
|
10
|
+
import { Button } from "hazo_auth/components/ui/button";
|
|
11
|
+
import { Avatar, AvatarImage, AvatarFallback } from "hazo_auth/components/ui/avatar";
|
|
12
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "hazo_auth/components/ui/alert-dialog";
|
|
13
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "hazo_auth/components/ui/dialog";
|
|
14
|
+
import { Input } from "hazo_auth/components/ui/input";
|
|
15
|
+
import { Label } from "hazo_auth/components/ui/label";
|
|
16
|
+
import { RolesMatrix } from "hazo_auth/components/layouts/user_management/components/roles_matrix";
|
|
17
|
+
import { UserX, KeyRound, Edit, Trash2, Loader2, CircleCheck, CircleX, Plus, UserPlus } from "lucide-react";
|
|
18
|
+
import { toast } from "sonner";
|
|
19
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "hazo_auth/components/ui/tooltip";
|
|
20
|
+
// section: component
|
|
21
|
+
/**
|
|
22
|
+
* User Management layout component with three tabs
|
|
23
|
+
* Tab 1: Manage Users - data table with user details and actions
|
|
24
|
+
* Tab 2: Roles - roles-permissions matrix
|
|
25
|
+
* Tab 3: Permissions - manage permissions from DB and config
|
|
26
|
+
* @param props - Component props
|
|
27
|
+
* @returns User Management layout component
|
|
28
|
+
*/
|
|
29
|
+
export function UserManagementLayout({ className }) {
|
|
30
|
+
// Permission checks
|
|
31
|
+
const authResult = use_hazo_auth();
|
|
32
|
+
const hasUserManagementPermission = authResult.authenticated &&
|
|
33
|
+
authResult.permissions.includes("admin_user_management");
|
|
34
|
+
const hasRoleManagementPermission = authResult.authenticated &&
|
|
35
|
+
authResult.permissions.includes("admin_role_management");
|
|
36
|
+
const hasPermissionManagementPermission = authResult.authenticated &&
|
|
37
|
+
authResult.permissions.includes("admin_permission_management");
|
|
38
|
+
// Determine which tabs to show
|
|
39
|
+
const showUsersTab = hasUserManagementPermission;
|
|
40
|
+
const showRolesTab = hasRoleManagementPermission;
|
|
41
|
+
const showPermissionsTab = hasPermissionManagementPermission;
|
|
42
|
+
const hasAnyPermission = showUsersTab || showRolesTab || showPermissionsTab;
|
|
43
|
+
// Tab 1: Users state
|
|
44
|
+
const [users, setUsers] = useState([]);
|
|
45
|
+
const [usersLoading, setUsersLoading] = useState(true);
|
|
46
|
+
const [deactivateDialogOpen, setDeactivateDialogOpen] = useState(false);
|
|
47
|
+
const [resetPasswordDialogOpen, setResetPasswordDialogOpen] = useState(false);
|
|
48
|
+
const [userDetailDialogOpen, setUserDetailDialogOpen] = useState(false);
|
|
49
|
+
const [assignRolesDialogOpen, setAssignRolesDialogOpen] = useState(false);
|
|
50
|
+
const [selectedUser, setSelectedUser] = useState(null);
|
|
51
|
+
const [usersActionLoading, setUsersActionLoading] = useState(false);
|
|
52
|
+
// Tab 3: Permissions state
|
|
53
|
+
const [permissions, setPermissions] = useState([]);
|
|
54
|
+
const [permissionsLoading, setPermissionsLoading] = useState(true);
|
|
55
|
+
const [editPermissionDialogOpen, setEditPermissionDialogOpen] = useState(false);
|
|
56
|
+
const [addPermissionDialogOpen, setAddPermissionDialogOpen] = useState(false);
|
|
57
|
+
const [editingPermission, setEditingPermission] = useState(null);
|
|
58
|
+
const [editDescription, setEditDescription] = useState("");
|
|
59
|
+
const [newPermissionName, setNewPermissionName] = useState("");
|
|
60
|
+
const [newPermissionDescription, setNewPermissionDescription] = useState("");
|
|
61
|
+
const [permissionsActionLoading, setPermissionsActionLoading] = useState(false);
|
|
62
|
+
const [migrateLoading, setMigrateLoading] = useState(false);
|
|
63
|
+
// Load users function (reusable)
|
|
64
|
+
const loadUsers = useCallback(async () => {
|
|
65
|
+
setUsersLoading(true);
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch("/api/hazo_auth/user_management/users");
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
if (data.success) {
|
|
70
|
+
setUsers(data.users);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
toast.error("Failed to load users");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
toast.error("Failed to load users");
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
setUsersLoading(false);
|
|
81
|
+
}
|
|
82
|
+
}, []);
|
|
83
|
+
// Load users (only if user has permission)
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (!showUsersTab) {
|
|
86
|
+
setUsersLoading(false);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
void loadUsers();
|
|
90
|
+
}, [showUsersTab, loadUsers]);
|
|
91
|
+
// Load permissions (only if user has permission)
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (!showPermissionsTab) {
|
|
94
|
+
setPermissionsLoading(false);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const loadPermissions = async () => {
|
|
98
|
+
setPermissionsLoading(true);
|
|
99
|
+
try {
|
|
100
|
+
const response = await fetch("/api/hazo_auth/user_management/permissions");
|
|
101
|
+
const data = await response.json();
|
|
102
|
+
if (data.success) {
|
|
103
|
+
const db_perms = data.db_permissions.map((p) => ({
|
|
104
|
+
id: p.id,
|
|
105
|
+
permission_name: p.permission_name,
|
|
106
|
+
description: p.description,
|
|
107
|
+
source: "db",
|
|
108
|
+
}));
|
|
109
|
+
const config_perms = data.config_permissions.map((name) => ({
|
|
110
|
+
id: 0, // Temporary ID for config permissions
|
|
111
|
+
permission_name: name,
|
|
112
|
+
description: "",
|
|
113
|
+
source: "config",
|
|
114
|
+
}));
|
|
115
|
+
setPermissions([...db_perms, ...config_perms]);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
toast.error("Failed to load permissions");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
toast.error("Failed to load permissions");
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
setPermissionsLoading(false);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
void loadPermissions();
|
|
129
|
+
}, [showPermissionsTab]);
|
|
130
|
+
// Handle deactivate user
|
|
131
|
+
const handleDeactivateUser = async () => {
|
|
132
|
+
if (!selectedUser)
|
|
133
|
+
return;
|
|
134
|
+
setUsersActionLoading(true);
|
|
135
|
+
try {
|
|
136
|
+
const response = await fetch("/api/user_management/users", {
|
|
137
|
+
method: "PATCH",
|
|
138
|
+
headers: {
|
|
139
|
+
"Content-Type": "application/json",
|
|
140
|
+
},
|
|
141
|
+
body: JSON.stringify({
|
|
142
|
+
user_id: selectedUser.id,
|
|
143
|
+
is_active: false,
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
const data = await response.json();
|
|
147
|
+
if (data.success) {
|
|
148
|
+
toast.success("User deactivated successfully");
|
|
149
|
+
setDeactivateDialogOpen(false);
|
|
150
|
+
setSelectedUser(null);
|
|
151
|
+
// Reload users
|
|
152
|
+
const reload_response = await fetch("/api/user_management/users");
|
|
153
|
+
const reload_data = await reload_response.json();
|
|
154
|
+
if (reload_data.success) {
|
|
155
|
+
setUsers(reload_data.users);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
toast.error(data.error || "Failed to deactivate user");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
toast.error("Failed to deactivate user");
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
setUsersActionLoading(false);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
// Handle reset password
|
|
170
|
+
const handleResetPassword = async () => {
|
|
171
|
+
if (!selectedUser)
|
|
172
|
+
return;
|
|
173
|
+
setUsersActionLoading(true);
|
|
174
|
+
try {
|
|
175
|
+
const response = await fetch("/api/user_management/users", {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers: {
|
|
178
|
+
"Content-Type": "application/json",
|
|
179
|
+
},
|
|
180
|
+
body: JSON.stringify({
|
|
181
|
+
user_id: selectedUser.id,
|
|
182
|
+
}),
|
|
183
|
+
});
|
|
184
|
+
const data = await response.json();
|
|
185
|
+
if (data.success) {
|
|
186
|
+
toast.success("Password reset email sent successfully");
|
|
187
|
+
setResetPasswordDialogOpen(false);
|
|
188
|
+
setSelectedUser(null);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
toast.error(data.error || "Failed to send password reset email");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
toast.error("Failed to send password reset email");
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
setUsersActionLoading(false);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
// Handle migrate permissions
|
|
202
|
+
const handleMigratePermissions = async () => {
|
|
203
|
+
var _a, _b;
|
|
204
|
+
setMigrateLoading(true);
|
|
205
|
+
try {
|
|
206
|
+
const response = await fetch("/api/hazo_auth/user_management/permissions?action=migrate", {
|
|
207
|
+
method: "POST",
|
|
208
|
+
});
|
|
209
|
+
const data = await response.json();
|
|
210
|
+
if (data.success) {
|
|
211
|
+
const created_count = ((_a = data.created) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
212
|
+
const skipped_count = ((_b = data.skipped) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
213
|
+
if (created_count > 0) {
|
|
214
|
+
toast.success(`Migrated ${created_count} permission(s) to database. ${skipped_count} already existed.`);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
toast.info(`All permissions already exist in database. ${skipped_count} skipped.`);
|
|
218
|
+
}
|
|
219
|
+
// Show detailed list in toast if there are changes
|
|
220
|
+
if (data.created && data.created.length > 0) {
|
|
221
|
+
toast.info(`Created: ${data.created.join(", ")}`);
|
|
222
|
+
}
|
|
223
|
+
if (data.skipped && data.skipped.length > 0) {
|
|
224
|
+
toast.info(`Skipped: ${data.skipped.join(", ")}`);
|
|
225
|
+
}
|
|
226
|
+
// Reload permissions
|
|
227
|
+
const reload_response = await fetch("/api/user_management/permissions");
|
|
228
|
+
const reload_data = await reload_response.json();
|
|
229
|
+
if (reload_data.success) {
|
|
230
|
+
const db_perms = reload_data.db_permissions.map((p) => ({
|
|
231
|
+
id: p.id,
|
|
232
|
+
permission_name: p.permission_name,
|
|
233
|
+
description: p.description,
|
|
234
|
+
source: "db",
|
|
235
|
+
}));
|
|
236
|
+
const config_perms = reload_data.config_permissions.map((name) => ({
|
|
237
|
+
id: 0,
|
|
238
|
+
permission_name: name,
|
|
239
|
+
description: "",
|
|
240
|
+
source: "config",
|
|
241
|
+
}));
|
|
242
|
+
setPermissions([...db_perms, ...config_perms]);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
toast.error(data.error || "Failed to migrate permissions");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
toast.error("Failed to migrate permissions");
|
|
251
|
+
}
|
|
252
|
+
finally {
|
|
253
|
+
setMigrateLoading(false);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
// Handle edit permission
|
|
257
|
+
const handleEditPermission = async () => {
|
|
258
|
+
if (!editingPermission || editingPermission.source === "config")
|
|
259
|
+
return;
|
|
260
|
+
setPermissionsActionLoading(true);
|
|
261
|
+
try {
|
|
262
|
+
const response = await fetch("/api/user_management/permissions", {
|
|
263
|
+
method: "PUT",
|
|
264
|
+
headers: {
|
|
265
|
+
"Content-Type": "application/json",
|
|
266
|
+
},
|
|
267
|
+
body: JSON.stringify({
|
|
268
|
+
permission_id: editingPermission.id,
|
|
269
|
+
description: editDescription,
|
|
270
|
+
}),
|
|
271
|
+
});
|
|
272
|
+
const data = await response.json();
|
|
273
|
+
if (data.success) {
|
|
274
|
+
toast.success("Permission updated successfully");
|
|
275
|
+
setEditPermissionDialogOpen(false);
|
|
276
|
+
setEditingPermission(null);
|
|
277
|
+
setEditDescription("");
|
|
278
|
+
// Reload permissions
|
|
279
|
+
const reload_response = await fetch("/api/user_management/permissions");
|
|
280
|
+
const reload_data = await reload_response.json();
|
|
281
|
+
if (reload_data.success) {
|
|
282
|
+
const db_perms = reload_data.db_permissions.map((p) => ({
|
|
283
|
+
id: p.id,
|
|
284
|
+
permission_name: p.permission_name,
|
|
285
|
+
description: p.description,
|
|
286
|
+
source: "db",
|
|
287
|
+
}));
|
|
288
|
+
const config_perms = reload_data.config_permissions.map((name) => ({
|
|
289
|
+
id: 0,
|
|
290
|
+
permission_name: name,
|
|
291
|
+
description: "",
|
|
292
|
+
source: "config",
|
|
293
|
+
}));
|
|
294
|
+
setPermissions([...db_perms, ...config_perms]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
toast.error(data.error || "Failed to update permission");
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
toast.error("Failed to update permission");
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
setPermissionsActionLoading(false);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
// Handle add permission
|
|
309
|
+
const handleAddPermission = async () => {
|
|
310
|
+
if (!newPermissionName.trim()) {
|
|
311
|
+
toast.error("Permission name is required");
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
setPermissionsActionLoading(true);
|
|
315
|
+
try {
|
|
316
|
+
const response = await fetch("/api/user_management/permissions", {
|
|
317
|
+
method: "POST",
|
|
318
|
+
headers: {
|
|
319
|
+
"Content-Type": "application/json",
|
|
320
|
+
},
|
|
321
|
+
body: JSON.stringify({
|
|
322
|
+
permission_name: newPermissionName.trim(),
|
|
323
|
+
description: newPermissionDescription.trim(),
|
|
324
|
+
}),
|
|
325
|
+
});
|
|
326
|
+
const data = await response.json();
|
|
327
|
+
if (data.success) {
|
|
328
|
+
toast.success("Permission created successfully");
|
|
329
|
+
setAddPermissionDialogOpen(false);
|
|
330
|
+
setNewPermissionName("");
|
|
331
|
+
setNewPermissionDescription("");
|
|
332
|
+
// Reload permissions
|
|
333
|
+
const reload_response = await fetch("/api/user_management/permissions");
|
|
334
|
+
const reload_data = await reload_response.json();
|
|
335
|
+
if (reload_data.success) {
|
|
336
|
+
const db_perms = reload_data.db_permissions.map((p) => ({
|
|
337
|
+
id: p.id,
|
|
338
|
+
permission_name: p.permission_name,
|
|
339
|
+
description: p.description,
|
|
340
|
+
source: "db",
|
|
341
|
+
}));
|
|
342
|
+
const config_perms = reload_data.config_permissions.map((name) => ({
|
|
343
|
+
id: 0,
|
|
344
|
+
permission_name: name,
|
|
345
|
+
description: "",
|
|
346
|
+
source: "config",
|
|
347
|
+
}));
|
|
348
|
+
setPermissions([...db_perms, ...config_perms]);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
toast.error(data.error || "Failed to create permission");
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
toast.error("Failed to create permission");
|
|
357
|
+
}
|
|
358
|
+
finally {
|
|
359
|
+
setPermissionsActionLoading(false);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
// Handle delete permission
|
|
363
|
+
const handleDeletePermission = async (permission) => {
|
|
364
|
+
if (permission.source === "config")
|
|
365
|
+
return;
|
|
366
|
+
setPermissionsActionLoading(true);
|
|
367
|
+
try {
|
|
368
|
+
const response = await fetch(`/api/hazo_auth/user_management/permissions?permission_id=${permission.id}`, {
|
|
369
|
+
method: "DELETE",
|
|
370
|
+
});
|
|
371
|
+
const data = await response.json();
|
|
372
|
+
if (data.success) {
|
|
373
|
+
toast.success("Permission deleted successfully");
|
|
374
|
+
// Reload permissions
|
|
375
|
+
const reload_response = await fetch("/api/user_management/permissions");
|
|
376
|
+
const reload_data = await reload_response.json();
|
|
377
|
+
if (reload_data.success) {
|
|
378
|
+
const db_perms = reload_data.db_permissions.map((p) => ({
|
|
379
|
+
id: p.id,
|
|
380
|
+
permission_name: p.permission_name,
|
|
381
|
+
description: p.description,
|
|
382
|
+
source: "db",
|
|
383
|
+
}));
|
|
384
|
+
const config_perms = reload_data.config_permissions.map((name) => ({
|
|
385
|
+
id: 0,
|
|
386
|
+
permission_name: name,
|
|
387
|
+
description: "",
|
|
388
|
+
source: "config",
|
|
389
|
+
}));
|
|
390
|
+
setPermissions([...db_perms, ...config_perms]);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
toast.error(data.error || "Failed to delete permission");
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
toast.error("Failed to delete permission");
|
|
399
|
+
}
|
|
400
|
+
finally {
|
|
401
|
+
setPermissionsActionLoading(false);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
// Get user initials for avatar fallback
|
|
405
|
+
const getUserInitials = (user) => {
|
|
406
|
+
var _a, _b;
|
|
407
|
+
if (user.name) {
|
|
408
|
+
const parts = user.name.trim().split(" ");
|
|
409
|
+
if (parts.length >= 2) {
|
|
410
|
+
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
|
|
411
|
+
}
|
|
412
|
+
return ((_a = user.name[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || "";
|
|
413
|
+
}
|
|
414
|
+
if (user.email_address) {
|
|
415
|
+
return ((_b = user.email_address[0]) === null || _b === void 0 ? void 0 : _b.toUpperCase()) || "";
|
|
416
|
+
}
|
|
417
|
+
return "?";
|
|
418
|
+
};
|
|
419
|
+
return (_jsxs("div", { className: `cls_user_management_layout flex flex-col gap-4 w-full ${className || ""}`, children: [authResult.loading ? (_jsx("div", { className: "cls_user_management_permissions_loading flex items-center justify-center p-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : !hasAnyPermission ? (_jsxs("div", { className: "cls_user_management_no_permissions flex flex-col items-center justify-center p-8 gap-4", children: [_jsx("p", { className: "text-lg font-semibold text-slate-700", children: "Access Denied" }), _jsx("p", { className: "text-sm text-muted-foreground text-center", children: "You don't have permission to access User Management. Please contact your administrator." })] })) : (_jsxs(Tabs, { defaultValue: showUsersTab ? "users" :
|
|
420
|
+
showRolesTab ? "roles" :
|
|
421
|
+
showPermissionsTab ? "permissions" : "users", className: "cls_user_management_tabs w-full", children: [_jsxs(TabsList, { className: "cls_user_management_tabs_list flex w-full", children: [showUsersTab && (_jsx(TabsTrigger, { value: "users", className: "cls_user_management_tabs_trigger flex-1", children: "Manage Users" })), showRolesTab && (_jsx(TabsTrigger, { value: "roles", className: "cls_user_management_tabs_trigger flex-1", children: "Roles" })), showPermissionsTab && (_jsx(TabsTrigger, { value: "permissions", className: "cls_user_management_tabs_trigger flex-1", children: "Permissions" }))] }), showUsersTab && (_jsx(TabsContent, { value: "users", className: "cls_user_management_tab_users w-full", children: usersLoading ? (_jsx("div", { className: "cls_user_management_users_loading flex items-center justify-center p-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : (_jsx("div", { className: "cls_user_management_users_table_container border rounded-lg overflow-auto w-full", children: _jsxs(Table, { className: "cls_user_management_users_table w-full", children: [_jsx(TableHeader, { className: "cls_user_management_users_table_header", children: _jsxs(TableRow, { className: "cls_user_management_users_table_header_row", children: [_jsx(TableHead, { className: "cls_user_management_users_table_header_profile_pic w-16", children: "Photo" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_id", children: "ID" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_name", children: "Name" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_email", children: "Email" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_email_verified", children: "Email Verified" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_is_active", children: "Active" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_last_logon", children: "Last Logon" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_created_at", children: "Created At" }), _jsx(TableHead, { className: "cls_user_management_users_table_header_actions text-right", children: "Actions" })] }) }), _jsx(TableBody, { className: "cls_user_management_users_table_body", children: users.length === 0 ? (_jsx(TableRow, { className: "cls_user_management_users_table_row_empty", children: _jsx(TableCell, { colSpan: 9, className: "text-center text-muted-foreground py-8", children: "No users found." }) })) : (users.map((user) => (_jsxs(TableRow, { className: "cls_user_management_users_table_row cursor-pointer hover:bg-muted/50", onClick: () => {
|
|
422
|
+
setSelectedUser(user);
|
|
423
|
+
setUserDetailDialogOpen(true);
|
|
424
|
+
}, children: [_jsx(TableCell, { className: "cls_user_management_users_table_cell_profile_pic", children: _jsxs(Avatar, { className: "cls_user_management_users_table_avatar h-8 w-8", children: [_jsx(AvatarImage, { src: user.profile_picture_url || undefined, alt: user.name ? `Profile picture of ${user.name}` : "Profile picture", className: "cls_user_management_users_table_avatar_image" }), _jsx(AvatarFallback, { className: "cls_user_management_users_table_avatar_fallback bg-slate-200 text-slate-600 text-xs", children: getUserInitials(user) })] }) }), _jsxs(TableCell, { className: "cls_user_management_users_table_cell_id font-mono text-xs", children: [user.id.substring(0, 8), "..."] }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_name", children: user.name || "-" }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_email", children: user.email_address }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_email_verified", children: user.email_verified ? (_jsx("span", { className: "text-green-600", children: "Yes" })) : (_jsx("span", { className: "text-red-600", children: "No" })) }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_is_active", children: user.is_active ? (_jsx("span", { className: "text-green-600", children: "Active" })) : (_jsx("span", { className: "text-red-600", children: "Inactive" })) }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_last_logon", children: user.last_logon
|
|
425
|
+
? new Date(user.last_logon).toLocaleDateString()
|
|
426
|
+
: "-" }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_created_at", children: user.created_at
|
|
427
|
+
? new Date(user.created_at).toLocaleDateString()
|
|
428
|
+
: "-" }), _jsx(TableCell, { className: "cls_user_management_users_table_cell_actions text-right", children: _jsx(TooltipProvider, { children: _jsxs("div", { className: "cls_user_management_users_table_actions flex items-center justify-end gap-2", onClick: (e) => e.stopPropagation(), children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
429
|
+
setSelectedUser(user);
|
|
430
|
+
setAssignRolesDialogOpen(true);
|
|
431
|
+
}, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_assign_roles", children: _jsx(UserPlus, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Assign Roles" }) })] }), user.is_active && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
432
|
+
setSelectedUser(user);
|
|
433
|
+
setDeactivateDialogOpen(true);
|
|
434
|
+
}, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_deactivate", children: _jsx(UserX, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Deactivate" }) })] })), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Button, { onClick: () => {
|
|
435
|
+
setSelectedUser(user);
|
|
436
|
+
setResetPasswordDialogOpen(true);
|
|
437
|
+
}, variant: "outline", size: "sm", className: "cls_user_management_users_table_action_reset_password", children: _jsx(KeyRound, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: _jsx("p", { children: "Reset Password" }) })] })] }) }) })] }, user.id)))) })] }) })) })), showRolesTab && (_jsx(TabsContent, { value: "roles", className: "cls_user_management_tab_roles w-full", children: _jsx(RolesMatrix, { add_button_enabled: true, role_name_selection_enabled: false, onSave: (data) => {
|
|
438
|
+
// Data is already saved by RolesMatrix component
|
|
439
|
+
console.log("Roles saved:", data);
|
|
440
|
+
} }) })), showPermissionsTab && (_jsx(TabsContent, { value: "permissions", className: "cls_user_management_tab_permissions w-full", children: _jsxs("div", { className: "cls_user_management_permissions_container flex flex-col gap-4 w-full", children: [_jsxs("div", { className: "cls_user_management_permissions_header flex items-center justify-between", children: [_jsx("div", { className: "cls_user_management_permissions_header_left flex items-center gap-2", children: _jsxs(Button, { onClick: () => setAddPermissionDialogOpen(true), variant: "default", size: "sm", className: "cls_user_management_permissions_add_button", children: [_jsx(Plus, { className: "h-4 w-4 mr-2" }), "Add Permission"] }) }), _jsx("div", { className: "cls_user_management_permissions_header_right", children: _jsx(Button, { onClick: handleMigratePermissions, disabled: migrateLoading, variant: "default", size: "sm", className: "cls_user_management_permissions_migrate_button", children: migrateLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Migrating..."] })) : ("Migrate config to database") }) })] }), permissionsLoading ? (_jsx("div", { className: "cls_user_management_permissions_loading flex items-center justify-center p-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-slate-400" }) })) : (_jsx("div", { className: "cls_user_management_permissions_table_container border rounded-lg overflow-auto w-full", children: _jsxs(Table, { className: "cls_user_management_permissions_table w-full", children: [_jsx(TableHeader, { className: "cls_user_management_permissions_table_header", children: _jsxs(TableRow, { className: "cls_user_management_permissions_table_header_row", children: [_jsx(TableHead, { className: "cls_user_management_permissions_table_header_name", children: "Permission Name" }), _jsx(TableHead, { className: "cls_user_management_permissions_table_header_description", children: "Description" }), _jsx(TableHead, { className: "cls_user_management_permissions_table_header_source", children: "Source" }), _jsx(TableHead, { className: "cls_user_management_permissions_table_header_actions text-right", children: "Actions" })] }) }), _jsx(TableBody, { className: "cls_user_management_permissions_table_body", children: permissions.length === 0 ? (_jsx(TableRow, { className: "cls_user_management_permissions_table_row_empty", children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "No permissions found." }) })) : (permissions.map((permission) => (_jsxs(TableRow, { className: "cls_user_management_permissions_table_row", children: [_jsx(TableCell, { className: `cls_user_management_permissions_table_cell_name font-medium ${permission.source === "db" ? "text-blue-600" : "text-purple-600"}`, children: permission.permission_name }), _jsx(TableCell, { className: "cls_user_management_permissions_table_cell_description", children: permission.description || "-" }), _jsx(TableCell, { className: "cls_user_management_permissions_table_cell_source", children: _jsx("span", { className: `px-2 py-1 rounded text-xs font-medium ${permission.source === "db"
|
|
441
|
+
? "bg-blue-100 text-blue-700"
|
|
442
|
+
: "bg-purple-100 text-purple-700"}`, children: permission.source === "db" ? "Database" : "Config" }) }), _jsx(TableCell, { className: "cls_user_management_permissions_table_cell_actions text-right", children: _jsx("div", { className: "cls_user_management_permissions_table_actions flex items-center justify-end gap-2", children: permission.source === "db" && (_jsxs(_Fragment, { children: [_jsxs(Button, { onClick: () => {
|
|
443
|
+
setEditingPermission(permission);
|
|
444
|
+
setEditDescription(permission.description);
|
|
445
|
+
setEditPermissionDialogOpen(true);
|
|
446
|
+
}, variant: "outline", size: "sm", className: "cls_user_management_permissions_table_action_edit", children: [_jsx(Edit, { className: "h-4 w-4 mr-1" }), "Edit"] }), _jsxs(Button, { onClick: () => handleDeletePermission(permission), disabled: permissionsActionLoading, variant: "outline", size: "sm", className: "cls_user_management_permissions_table_action_delete text-destructive", children: [_jsx(Trash2, { className: "h-4 w-4 mr-1" }), "Delete"] })] })) }) })] }, `${permission.source}-${permission.id}-${permission.permission_name}`)))) })] }) }))] }) }))] })), _jsx(AlertDialog, { open: deactivateDialogOpen, onOpenChange: setDeactivateDialogOpen, children: _jsxs(AlertDialogContent, { className: "cls_user_management_deactivate_dialog", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Deactivate User" }), _jsxs(AlertDialogDescription, { children: ["Are you sure you want to deactivate ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), "? They will not be able to log in until reactivated."] })] }), _jsxs(AlertDialogFooter, { className: "cls_user_management_deactivate_dialog_footer", children: [_jsx(AlertDialogAction, { onClick: handleDeactivateUser, disabled: usersActionLoading, className: "cls_user_management_deactivate_dialog_confirm", children: usersActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Deactivating..."] })) : ("Deactivate") }), _jsx(AlertDialogCancel, { onClick: () => {
|
|
447
|
+
setDeactivateDialogOpen(false);
|
|
448
|
+
setSelectedUser(null);
|
|
449
|
+
}, className: "cls_user_management_deactivate_dialog_cancel", children: "Cancel" })] })] }) }), _jsx(AlertDialog, { open: resetPasswordDialogOpen, onOpenChange: setResetPasswordDialogOpen, children: _jsxs(AlertDialogContent, { className: "cls_user_management_reset_password_dialog", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Reset Password" }), _jsxs(AlertDialogDescription, { children: ["Send a password reset email to ", selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address, "? They will receive a link to reset their password."] })] }), _jsxs(AlertDialogFooter, { className: "cls_user_management_reset_password_dialog_footer", children: [_jsx(AlertDialogAction, { onClick: handleResetPassword, disabled: usersActionLoading, className: "cls_user_management_reset_password_dialog_confirm", children: usersActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Sending..."] })) : ("Send Reset Email") }), _jsx(AlertDialogCancel, { onClick: () => {
|
|
450
|
+
setResetPasswordDialogOpen(false);
|
|
451
|
+
setSelectedUser(null);
|
|
452
|
+
}, className: "cls_user_management_reset_password_dialog_cancel", children: "Cancel" })] })] }) }), _jsx(Dialog, { open: editPermissionDialogOpen, onOpenChange: setEditPermissionDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_edit_permission_dialog", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Edit Permission" }), _jsxs(DialogDescription, { children: ["Update the description for permission: ", editingPermission === null || editingPermission === void 0 ? void 0 : editingPermission.permission_name] })] }), _jsx("div", { className: "cls_user_management_edit_permission_dialog_content flex flex-col gap-4 py-4", children: _jsxs("div", { className: "cls_user_management_edit_permission_dialog_field flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "permission_description", className: "cls_user_management_edit_permission_dialog_label", children: "Description" }), _jsx(Input, { id: "permission_description", value: editDescription, onChange: (e) => setEditDescription(e.target.value), placeholder: "Enter permission description", className: "cls_user_management_edit_permission_dialog_input" })] }) }), _jsxs(DialogFooter, { className: "cls_user_management_edit_permission_dialog_footer", children: [_jsx(Button, { onClick: handleEditPermission, disabled: permissionsActionLoading, variant: "default", className: "cls_user_management_edit_permission_dialog_save", children: permissionsActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Saving..."] })) : (_jsxs(_Fragment, { children: [_jsx(CircleCheck, { className: "h-4 w-4 mr-2" }), "Save"] })) }), _jsxs(Button, { onClick: () => {
|
|
453
|
+
setEditPermissionDialogOpen(false);
|
|
454
|
+
setEditingPermission(null);
|
|
455
|
+
setEditDescription("");
|
|
456
|
+
}, variant: "outline", className: "cls_user_management_edit_permission_dialog_cancel", children: [_jsx(CircleX, { className: "h-4 w-4 mr-2" }), "Cancel"] })] })] }) }), _jsx(Dialog, { open: addPermissionDialogOpen, onOpenChange: setAddPermissionDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_add_permission_dialog", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Add New Permission" }), _jsx(DialogDescription, { children: "Create a new permission that can be assigned to roles." })] }), _jsxs("div", { className: "cls_user_management_add_permission_dialog_content flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "cls_user_management_add_permission_dialog_field flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "new_permission_name", className: "cls_user_management_add_permission_dialog_label", children: "Permission Name *" }), _jsx(Input, { id: "new_permission_name", value: newPermissionName, onChange: (e) => setNewPermissionName(e.target.value), placeholder: "Enter permission name (e.g., READ_USERS)", className: "cls_user_management_add_permission_dialog_input", onKeyDown: (e) => {
|
|
457
|
+
if (e.key === "Enter") {
|
|
458
|
+
handleAddPermission();
|
|
459
|
+
}
|
|
460
|
+
} })] }), _jsxs("div", { className: "cls_user_management_add_permission_dialog_field flex flex-col gap-2", children: [_jsx(Label, { htmlFor: "new_permission_description", className: "cls_user_management_add_permission_dialog_label", children: "Description" }), _jsx(Input, { id: "new_permission_description", value: newPermissionDescription, onChange: (e) => setNewPermissionDescription(e.target.value), placeholder: "Enter permission description (optional)", className: "cls_user_management_add_permission_dialog_input", onKeyDown: (e) => {
|
|
461
|
+
if (e.key === "Enter") {
|
|
462
|
+
handleAddPermission();
|
|
463
|
+
}
|
|
464
|
+
} })] })] }), _jsxs(DialogFooter, { className: "cls_user_management_add_permission_dialog_footer", children: [_jsx(Button, { onClick: handleAddPermission, disabled: permissionsActionLoading || !newPermissionName.trim(), variant: "default", className: "cls_user_management_add_permission_dialog_save", children: permissionsActionLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }), "Creating..."] })) : (_jsxs(_Fragment, { children: [_jsx(CircleCheck, { className: "h-4 w-4 mr-2" }), "Create Permission"] })) }), _jsxs(Button, { onClick: () => {
|
|
465
|
+
setAddPermissionDialogOpen(false);
|
|
466
|
+
setNewPermissionName("");
|
|
467
|
+
setNewPermissionDescription("");
|
|
468
|
+
}, variant: "outline", className: "cls_user_management_add_permission_dialog_cancel", children: [_jsx(CircleX, { className: "h-4 w-4 mr-2" }), "Cancel"] })] })] }) }), _jsx(Dialog, { open: userDetailDialogOpen, onOpenChange: setUserDetailDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_user_detail_dialog max-w-2xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "User Details" }), _jsxs(DialogDescription, { children: ["Complete information for ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address)] })] }), _jsx("div", { className: "cls_user_management_user_detail_dialog_content flex flex-col gap-4 py-4", children: selectedUser && (_jsxs("div", { className: "cls_user_management_user_detail_fields grid grid-cols-1 gap-4", children: [_jsxs("div", { className: "cls_user_management_user_detail_field_profile_pic flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Profile Picture" }), _jsxs("div", { className: "cls_user_management_user_detail_profile_pic_container flex items-center gap-4", children: [_jsxs(Avatar, { className: "cls_user_management_user_detail_avatar h-16 w-16", children: [_jsx(AvatarImage, { src: selectedUser.profile_picture_url || undefined, alt: selectedUser.name ? `Profile picture of ${selectedUser.name}` : "Profile picture", className: "cls_user_management_user_detail_avatar_image" }), _jsx(AvatarFallback, { className: "cls_user_management_user_detail_avatar_fallback bg-slate-200 text-slate-600 text-lg", children: getUserInitials(selectedUser) })] }), _jsxs("div", { className: "cls_user_management_user_detail_profile_pic_info flex flex-col gap-1", children: [_jsx("span", { className: "cls_user_management_user_detail_profile_pic_url text-sm text-muted-foreground", children: selectedUser.profile_picture_url || "No profile picture" }), _jsxs("span", { className: "cls_user_management_user_detail_profile_pic_source text-xs text-muted-foreground", children: ["Source: ", selectedUser.profile_source || "N/A"] })] })] })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_id flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "User ID" }), _jsx("div", { className: "cls_user_management_user_detail_id_value font-mono text-sm bg-muted p-2 rounded", children: selectedUser.id })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_name flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Name" }), _jsx("div", { className: "cls_user_management_user_detail_name_value text-sm", children: selectedUser.name || "-" })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_email flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Email Address" }), _jsx("div", { className: "cls_user_management_user_detail_email_value text-sm", children: selectedUser.email_address })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_email_verified flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Email Verified" }), _jsx("div", { className: "cls_user_management_user_detail_email_verified_value", children: selectedUser.email_verified ? (_jsx("span", { className: "text-green-600 font-medium", children: "Yes" })) : (_jsx("span", { className: "text-red-600 font-medium", children: "No" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_is_active flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Active Status" }), _jsx("div", { className: "cls_user_management_user_detail_is_active_value", children: selectedUser.is_active ? (_jsx("span", { className: "text-green-600 font-medium", children: "Active" })) : (_jsx("span", { className: "text-red-600 font-medium", children: "Inactive" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_last_logon flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Last Logon" }), _jsx("div", { className: "cls_user_management_user_detail_last_logon_value text-sm", children: selectedUser.last_logon ? (_jsx("span", { className: "font-medium", children: new Date(selectedUser.last_logon).toLocaleString(undefined, {
|
|
469
|
+
year: "numeric",
|
|
470
|
+
month: "long",
|
|
471
|
+
day: "numeric",
|
|
472
|
+
hour: "2-digit",
|
|
473
|
+
minute: "2-digit",
|
|
474
|
+
second: "2-digit",
|
|
475
|
+
timeZoneName: "short",
|
|
476
|
+
}) })) : (_jsx("span", { className: "text-muted-foreground", children: "Never" })) })] }), _jsxs("div", { className: "cls_user_management_user_detail_field_created_at flex flex-col gap-2", children: [_jsx(Label, { className: "cls_user_management_user_detail_label font-semibold", children: "Created At" }), _jsx("div", { className: "cls_user_management_user_detail_created_at_value text-sm", children: selectedUser.created_at ? (_jsx("span", { className: "font-medium", children: new Date(selectedUser.created_at).toLocaleString(undefined, {
|
|
477
|
+
year: "numeric",
|
|
478
|
+
month: "long",
|
|
479
|
+
day: "numeric",
|
|
480
|
+
hour: "2-digit",
|
|
481
|
+
minute: "2-digit",
|
|
482
|
+
second: "2-digit",
|
|
483
|
+
timeZoneName: "short",
|
|
484
|
+
}) })) : (_jsx("span", { className: "text-muted-foreground", children: "-" })) })] })] })) }), _jsx(DialogFooter, { className: "cls_user_management_user_detail_dialog_footer", children: _jsx(Button, { onClick: () => setUserDetailDialogOpen(false), variant: "outline", className: "cls_user_management_user_detail_dialog_close", children: "Close" }) })] }) }), _jsx(Dialog, { open: assignRolesDialogOpen, onOpenChange: setAssignRolesDialogOpen, children: _jsxs(DialogContent, { className: "cls_user_management_assign_roles_dialog max-w-4xl max-h-[80vh] overflow-y-auto", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Assign Roles to User" }), _jsxs(DialogDescription, { children: ["Select roles to assign to ", (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.name) || (selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.email_address), ". Check the roles you want to assign, then click Save."] })] }), _jsx("div", { className: "cls_user_management_assign_roles_dialog_content py-4", children: _jsx(RolesMatrix, { add_button_enabled: false, role_name_selection_enabled: true, permissions_read_only: true, show_save_cancel: true, user_id: selectedUser === null || selectedUser === void 0 ? void 0 : selectedUser.id, onSave: (data) => {
|
|
485
|
+
// Data is already saved by RolesMatrix component
|
|
486
|
+
console.log("User roles saved:", data);
|
|
487
|
+
// Refresh users list to show updated roles
|
|
488
|
+
void loadUsers();
|
|
489
|
+
setAssignRolesDialogOpen(false);
|
|
490
|
+
setSelectedUser(null);
|
|
491
|
+
}, onCancel: () => {
|
|
492
|
+
setAssignRolesDialogOpen(false);
|
|
493
|
+
setSelectedUser(null);
|
|
494
|
+
}, className: "cls_user_management_assign_roles_matrix" }) })] }) })] }));
|
|
495
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
3
|
+
declare const AlertDialog: React.FC<AlertDialogPrimitive.AlertDialogProps>;
|
|
4
|
+
declare const AlertDialogTrigger: React.ForwardRefExoticComponent<AlertDialogPrimitive.AlertDialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
declare const AlertDialogPortal: React.FC<AlertDialogPrimitive.AlertDialogPortalProps>;
|
|
6
|
+
declare const AlertDialogOverlay: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
declare const AlertDialogContent: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
declare const AlertDialogHeader: {
|
|
9
|
+
({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
displayName: string;
|
|
11
|
+
};
|
|
12
|
+
declare const AlertDialogFooter: {
|
|
13
|
+
({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
displayName: string;
|
|
15
|
+
};
|
|
16
|
+
declare const AlertDialogTitle: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
17
|
+
declare const AlertDialogDescription: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
18
|
+
declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
19
|
+
declare const AlertDialogCancel: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
20
|
+
export { AlertDialog, AlertDialogPortal, AlertDialogOverlay, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, };
|
|
21
|
+
//# sourceMappingURL=alert-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-dialog.d.ts","sourceRoot":"","sources":["../../../src/components/ui/alert-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,oBAAoB,MAAM,8BAA8B,CAAA;AAKpE,QAAA,MAAM,WAAW,iDAA4B,CAAA;AAE7C,QAAA,MAAM,kBAAkB,wHAA+B,CAAA;AAEvD,QAAA,MAAM,iBAAiB,uDAA8B,CAAA;AAErD,QAAA,MAAM,kBAAkB,wKAYtB,CAAA;AAGF,QAAA,MAAM,kBAAkB,wKAetB,CAAA;AAGF,QAAA,MAAM,iBAAiB;8BAGpB,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAQtC,CAAA;AAGD,QAAA,MAAM,iBAAiB;8BAGpB,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAQtC,CAAA;AAGD,QAAA,MAAM,gBAAgB,8KASpB,CAAA;AAGF,QAAA,MAAM,sBAAsB,wLAS1B,CAAA;AAIF,QAAA,MAAM,iBAAiB,6KASrB,CAAA;AAGF,QAAA,MAAM,iBAAiB,6KAarB,CAAA;AAGF,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
16
|
+
import { cn } from "hazo_auth/lib/utils";
|
|
17
|
+
import { buttonVariants } from "hazo_auth/components/ui/button";
|
|
18
|
+
const AlertDialog = AlertDialogPrimitive.Root;
|
|
19
|
+
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
20
|
+
const AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
21
|
+
const AlertDialogOverlay = React.forwardRef((_a, ref) => {
|
|
22
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
23
|
+
return (_jsx(AlertDialogPrimitive.Overlay, Object.assign({ className: cn("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className) }, props, { ref: ref })));
|
|
24
|
+
});
|
|
25
|
+
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
26
|
+
const AlertDialogContent = React.forwardRef((_a, ref) => {
|
|
27
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
28
|
+
return (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, Object.assign({ ref: ref, className: cn("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", className) }, props))] }));
|
|
29
|
+
});
|
|
30
|
+
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
|
|
31
|
+
const AlertDialogHeader = (_a) => {
|
|
32
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
33
|
+
return (_jsx("div", Object.assign({ className: cn("flex flex-col space-y-2 text-center sm:text-left", className) }, props)));
|
|
34
|
+
};
|
|
35
|
+
AlertDialogHeader.displayName = "AlertDialogHeader";
|
|
36
|
+
const AlertDialogFooter = (_a) => {
|
|
37
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
38
|
+
return (_jsx("div", Object.assign({ className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className) }, props)));
|
|
39
|
+
};
|
|
40
|
+
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
41
|
+
const AlertDialogTitle = React.forwardRef((_a, ref) => {
|
|
42
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
43
|
+
return (_jsx(AlertDialogPrimitive.Title, Object.assign({ ref: ref, className: cn("text-lg font-semibold", className) }, props)));
|
|
44
|
+
});
|
|
45
|
+
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
46
|
+
const AlertDialogDescription = React.forwardRef((_a, ref) => {
|
|
47
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
48
|
+
return (_jsx(AlertDialogPrimitive.Description, Object.assign({ ref: ref, className: cn("text-sm text-muted-foreground", className) }, props)));
|
|
49
|
+
});
|
|
50
|
+
AlertDialogDescription.displayName =
|
|
51
|
+
AlertDialogPrimitive.Description.displayName;
|
|
52
|
+
const AlertDialogAction = React.forwardRef((_a, ref) => {
|
|
53
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
54
|
+
return (_jsx(AlertDialogPrimitive.Action, Object.assign({ ref: ref, className: cn(buttonVariants(), className) }, props)));
|
|
55
|
+
});
|
|
56
|
+
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
57
|
+
const AlertDialogCancel = React.forwardRef((_a, ref) => {
|
|
58
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
59
|
+
return (_jsx(AlertDialogPrimitive.Cancel, Object.assign({ ref: ref, className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className) }, props)));
|
|
60
|
+
});
|
|
61
|
+
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
62
|
+
export { AlertDialog, AlertDialogPortal, AlertDialogOverlay, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel, };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
3
|
+
declare const Avatar: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
4
|
+
declare const AvatarImage: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React.RefAttributes<HTMLImageElement>, "ref"> & React.RefAttributes<HTMLImageElement>>;
|
|
5
|
+
declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
6
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
7
|
+
//# sourceMappingURL=avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/avatar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAA;AAIzD,QAAA,MAAM,MAAM,yJAYV,CAAA;AAGF,QAAA,MAAM,WAAW,gKASf,CAAA;AAGF,QAAA,MAAM,cAAc,iKAYlB,CAAA;AAGF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,CAAA"}
|