hazo_auth 1.2.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 +39 -2
- package/scripts/init_users.ts +9 -9
- 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,19 @@
|
|
|
1
|
+
export type EditableFieldProps = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
type?: "text" | "email" | "tel" | "url";
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
onSave: (value: string) => Promise<void>;
|
|
7
|
+
onCancel?: () => void;
|
|
8
|
+
validation?: (value: string) => string | null;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
ariaLabel?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Editable field component with pencil icon for edit mode
|
|
14
|
+
* Shows check (green) and cancel (red) icons when in edit mode
|
|
15
|
+
* @param props - Component props including label, value, onSave callback, etc.
|
|
16
|
+
* @returns Editable field component
|
|
17
|
+
*/
|
|
18
|
+
export declare function EditableField({ label, value, type, placeholder, onSave, onCancel, validation, disabled, ariaLabel, }: EditableFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=editable_field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editable_field.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/components/editable_field.tsx"],"names":[],"mappings":"AAYA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,IAAa,EACb,WAAW,EACX,MAAM,EACN,QAAQ,EACR,UAAU,EACV,QAAgB,EAChB,SAAS,GACV,EAAE,kBAAkB,2CAsIpB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// file_description: reusable component for editable fields with pencil/edit/check/cancel icons
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { Input } from "hazo_auth/components/ui/input";
|
|
8
|
+
import { Label } from "hazo_auth/components/ui/label";
|
|
9
|
+
import { Button } from "hazo_auth/components/ui/button";
|
|
10
|
+
import { Pencil, CheckCircle2, XCircle } from "lucide-react";
|
|
11
|
+
// section: component
|
|
12
|
+
/**
|
|
13
|
+
* Editable field component with pencil icon for edit mode
|
|
14
|
+
* Shows check (green) and cancel (red) icons when in edit mode
|
|
15
|
+
* @param props - Component props including label, value, onSave callback, etc.
|
|
16
|
+
* @returns Editable field component
|
|
17
|
+
*/
|
|
18
|
+
export function EditableField({ label, value, type = "text", placeholder, onSave, onCancel, validation, disabled = false, ariaLabel, }) {
|
|
19
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
20
|
+
const [editValue, setEditValue] = useState(value);
|
|
21
|
+
const [error, setError] = useState(null);
|
|
22
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
23
|
+
const handleEdit = () => {
|
|
24
|
+
if (disabled)
|
|
25
|
+
return;
|
|
26
|
+
setIsEditing(true);
|
|
27
|
+
setEditValue(value);
|
|
28
|
+
setError(null);
|
|
29
|
+
};
|
|
30
|
+
const handleCancel = () => {
|
|
31
|
+
setIsEditing(false);
|
|
32
|
+
setEditValue(value);
|
|
33
|
+
setError(null);
|
|
34
|
+
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
35
|
+
};
|
|
36
|
+
const handleSave = async () => {
|
|
37
|
+
// Validate if validation function provided
|
|
38
|
+
if (validation) {
|
|
39
|
+
const validationError = validation(editValue);
|
|
40
|
+
if (validationError) {
|
|
41
|
+
setError(validationError);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Check if value changed
|
|
46
|
+
if (editValue === value) {
|
|
47
|
+
setIsEditing(false);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
setIsSaving(true);
|
|
51
|
+
setError(null);
|
|
52
|
+
try {
|
|
53
|
+
await onSave(editValue);
|
|
54
|
+
setIsEditing(false);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to save";
|
|
58
|
+
setError(errorMessage);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
setIsSaving(false);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const handleKeyDown = (e) => {
|
|
65
|
+
if (e.key === "Enter") {
|
|
66
|
+
void handleSave();
|
|
67
|
+
}
|
|
68
|
+
else if (e.key === "Escape") {
|
|
69
|
+
handleCancel();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return (_jsxs("div", { className: "cls_editable_field flex flex-col gap-2", children: [_jsx(Label, { htmlFor: `editable-field-${label}`, className: "cls_editable_field_label text-sm font-medium text-slate-700", children: label }), _jsx("div", { className: "cls_editable_field_input_container flex items-center gap-2", children: isEditing ? (_jsxs(_Fragment, { children: [_jsx(Input, { id: `editable-field-${label}`, type: type, value: editValue, onChange: (e) => setEditValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, disabled: isSaving, "aria-label": ariaLabel || label, className: "cls_editable_field_input flex-1" }), _jsx(Button, { type: "button", onClick: handleSave, disabled: isSaving, variant: "ghost", size: "icon", className: "cls_editable_field_save_button text-green-600 hover:text-green-700 hover:bg-green-50", "aria-label": "Save changes", children: _jsx(CheckCircle2, { className: "h-5 w-5", "aria-hidden": "true" }) }), _jsx(Button, { type: "button", onClick: handleCancel, disabled: isSaving, variant: "ghost", size: "icon", className: "cls_editable_field_cancel_button text-red-600 hover:text-red-700 hover:bg-red-50", "aria-label": "Cancel editing", children: _jsx(XCircle, { className: "h-5 w-5", "aria-hidden": "true" }) })] })) : (_jsxs(_Fragment, { children: [_jsx(Input, { id: `editable-field-${label}`, type: type, value: value || "", readOnly: true, disabled: true, placeholder: value ? undefined : placeholder || "Not set", "aria-label": ariaLabel || label, className: "cls_editable_field_display flex-1 bg-slate-50 cursor-not-allowed" }), !disabled && (_jsx(Button, { type: "button", onClick: handleEdit, variant: "ghost", size: "icon", className: "cls_editable_field_edit_button text-slate-600 hover:text-slate-700 hover:bg-slate-50", "aria-label": `Edit ${label}`, children: _jsx(Pencil, { className: "h-5 w-5", "aria-hidden": "true" }) }))] })) }), error && (_jsx("p", { className: "cls_editable_field_error text-sm text-red-600", role: "alert", children: error }))] }));
|
|
73
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { PasswordRequirementOptions } from "hazo_auth/components/layouts/shared/config/layout_customization";
|
|
2
|
+
export type ButtonPalette = {
|
|
3
|
+
submitBackground: string;
|
|
4
|
+
submitText: string;
|
|
5
|
+
cancelBorder: string;
|
|
6
|
+
cancelText: string;
|
|
7
|
+
};
|
|
8
|
+
export type PasswordChangeDialogProps = {
|
|
9
|
+
open: boolean;
|
|
10
|
+
onOpenChange: (open: boolean) => void;
|
|
11
|
+
onSave: (currentPassword: string, newPassword: string) => Promise<void>;
|
|
12
|
+
passwordRequirements: PasswordRequirementOptions;
|
|
13
|
+
buttonPalette?: ButtonPalette;
|
|
14
|
+
currentPasswordLabel?: string;
|
|
15
|
+
newPasswordLabel?: string;
|
|
16
|
+
confirmPasswordLabel?: string;
|
|
17
|
+
saveButtonLabel?: string;
|
|
18
|
+
cancelButtonLabel?: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Dialog component for changing password
|
|
22
|
+
* Shows current password, new password, and confirm password fields
|
|
23
|
+
* Validates password requirements and ensures passwords match
|
|
24
|
+
* @param props - Component props including open state, onSave callback, password requirements
|
|
25
|
+
* @returns Password change dialog component
|
|
26
|
+
*/
|
|
27
|
+
export declare function PasswordChangeDialog({ open, onOpenChange, onSave, passwordRequirements, buttonPalette, currentPasswordLabel, newPasswordLabel, confirmPasswordLabel, saveButtonLabel, cancelButtonLabel, }: PasswordChangeDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
//# sourceMappingURL=password_change_dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password_change_dialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/components/password_change_dialog.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iEAAiE,CAAC;AAGlH,MAAM,MAAM,aAAa,GAAG;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,oBAAoB,EAAE,0BAA0B,CAAC;IACjD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAGF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,oBAAoB,EACpB,aAAa,EACb,oBAAyC,EACzC,gBAAiC,EACjC,oBAA6C,EAC7C,eAAwB,EACxB,iBAA4B,GAC7B,EAAE,yBAAyB,2CAiP3B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// file_description: dialog component for changing password with current/new/confirm password fields
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "hazo_auth/components/ui/dialog";
|
|
8
|
+
import { Button } from "hazo_auth/components/ui/button";
|
|
9
|
+
import { PasswordField } from "hazo_auth/components/layouts/shared/components/password_field";
|
|
10
|
+
import { FormFieldWrapper } from "hazo_auth/components/layouts/shared/components/form_field_wrapper";
|
|
11
|
+
// section: component
|
|
12
|
+
/**
|
|
13
|
+
* Dialog component for changing password
|
|
14
|
+
* Shows current password, new password, and confirm password fields
|
|
15
|
+
* Validates password requirements and ensures passwords match
|
|
16
|
+
* @param props - Component props including open state, onSave callback, password requirements
|
|
17
|
+
* @returns Password change dialog component
|
|
18
|
+
*/
|
|
19
|
+
export function PasswordChangeDialog({ open, onOpenChange, onSave, passwordRequirements, buttonPalette, currentPasswordLabel = "Current password", newPasswordLabel = "New password", confirmPasswordLabel = "Confirm new password", saveButtonLabel = "Save", cancelButtonLabel = "Cancel", }) {
|
|
20
|
+
const [currentPassword, setCurrentPassword] = useState("");
|
|
21
|
+
const [newPassword, setNewPassword] = useState("");
|
|
22
|
+
const [confirmPassword, setConfirmPassword] = useState("");
|
|
23
|
+
const [currentPasswordVisible, setCurrentPasswordVisible] = useState(false);
|
|
24
|
+
const [newPasswordVisible, setNewPasswordVisible] = useState(false);
|
|
25
|
+
const [confirmPasswordVisible, setConfirmPasswordVisible] = useState(false);
|
|
26
|
+
const [errors, setErrors] = useState({});
|
|
27
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
28
|
+
const validatePassword = (password) => {
|
|
29
|
+
if (!password || password.length < passwordRequirements.minimum_length) {
|
|
30
|
+
return `Password must be at least ${passwordRequirements.minimum_length} characters long`;
|
|
31
|
+
}
|
|
32
|
+
const errors = [];
|
|
33
|
+
if (passwordRequirements.require_uppercase && !/[A-Z]/.test(password)) {
|
|
34
|
+
errors.push("uppercase letter");
|
|
35
|
+
}
|
|
36
|
+
if (passwordRequirements.require_lowercase && !/[a-z]/.test(password)) {
|
|
37
|
+
errors.push("lowercase letter");
|
|
38
|
+
}
|
|
39
|
+
if (passwordRequirements.require_number && !/[0-9]/.test(password)) {
|
|
40
|
+
errors.push("number");
|
|
41
|
+
}
|
|
42
|
+
if (passwordRequirements.require_special && !/[^A-Za-z0-9]/.test(password)) {
|
|
43
|
+
errors.push("special character");
|
|
44
|
+
}
|
|
45
|
+
if (errors.length > 0) {
|
|
46
|
+
return `Password must contain at least one: ${errors.join(", ")}`;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
const validateForm = () => {
|
|
51
|
+
const newErrors = {};
|
|
52
|
+
if (!currentPassword) {
|
|
53
|
+
newErrors.currentPassword = "Current password is required";
|
|
54
|
+
}
|
|
55
|
+
const newPasswordError = validatePassword(newPassword);
|
|
56
|
+
if (newPasswordError) {
|
|
57
|
+
newErrors.newPassword = newPasswordError;
|
|
58
|
+
}
|
|
59
|
+
if (!confirmPassword) {
|
|
60
|
+
newErrors.confirmPassword = "Please confirm your new password";
|
|
61
|
+
}
|
|
62
|
+
else if (newPassword !== confirmPassword) {
|
|
63
|
+
newErrors.confirmPassword = "Passwords do not match";
|
|
64
|
+
}
|
|
65
|
+
setErrors(newErrors);
|
|
66
|
+
return Object.keys(newErrors).length === 0;
|
|
67
|
+
};
|
|
68
|
+
const handleSave = async () => {
|
|
69
|
+
if (!validateForm()) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
setIsSubmitting(true);
|
|
73
|
+
setErrors({});
|
|
74
|
+
try {
|
|
75
|
+
await onSave(currentPassword, newPassword);
|
|
76
|
+
// Reset form on success
|
|
77
|
+
setCurrentPassword("");
|
|
78
|
+
setNewPassword("");
|
|
79
|
+
setConfirmPassword("");
|
|
80
|
+
onOpenChange(false);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to change password";
|
|
84
|
+
setErrors({ currentPassword: errorMessage });
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
setIsSubmitting(false);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const handleCancel = () => {
|
|
91
|
+
setCurrentPassword("");
|
|
92
|
+
setNewPassword("");
|
|
93
|
+
setConfirmPassword("");
|
|
94
|
+
setErrors({});
|
|
95
|
+
onOpenChange(false);
|
|
96
|
+
};
|
|
97
|
+
// Format password requirements for display
|
|
98
|
+
const getPasswordRequirements = () => {
|
|
99
|
+
const requirements = [];
|
|
100
|
+
requirements.push(`At least ${passwordRequirements.minimum_length} characters`);
|
|
101
|
+
if (passwordRequirements.require_uppercase) {
|
|
102
|
+
requirements.push("One uppercase letter");
|
|
103
|
+
}
|
|
104
|
+
if (passwordRequirements.require_lowercase) {
|
|
105
|
+
requirements.push("One lowercase letter");
|
|
106
|
+
}
|
|
107
|
+
if (passwordRequirements.require_number) {
|
|
108
|
+
requirements.push("One number");
|
|
109
|
+
}
|
|
110
|
+
if (passwordRequirements.require_special) {
|
|
111
|
+
requirements.push("One special character");
|
|
112
|
+
}
|
|
113
|
+
return requirements;
|
|
114
|
+
};
|
|
115
|
+
const passwordRequirementsList = getPasswordRequirements();
|
|
116
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "cls_password_change_dialog max-w-md", children: [_jsxs(DialogHeader, { className: "cls_password_change_dialog_header", children: [_jsx(DialogTitle, { className: "cls_password_change_dialog_title", children: "Change Password" }), _jsx(DialogDescription, { className: "cls_password_change_dialog_description", children: "Enter your current password and choose a new password." })] }), _jsxs("div", { className: "cls_password_change_dialog_content flex flex-col gap-4 py-4", children: [_jsx(FormFieldWrapper, { fieldId: "current-password", label: currentPasswordLabel, input: _jsx(PasswordField, { inputId: "current-password", ariaLabel: currentPasswordLabel, value: currentPassword, placeholder: "Enter your current password", autoComplete: "current-password", isVisible: currentPasswordVisible, onChange: (value) => {
|
|
117
|
+
setCurrentPassword(value);
|
|
118
|
+
if (errors.currentPassword) {
|
|
119
|
+
setErrors(Object.assign(Object.assign({}, errors), { currentPassword: undefined }));
|
|
120
|
+
}
|
|
121
|
+
}, onToggleVisibility: () => setCurrentPasswordVisible(!currentPasswordVisible), errorMessage: errors.currentPassword }) }), _jsx(FormFieldWrapper, { fieldId: "new-password", label: newPasswordLabel, input: _jsx(PasswordField, { inputId: "new-password", ariaLabel: newPasswordLabel, value: newPassword, placeholder: "Enter your new password", autoComplete: "new-password", isVisible: newPasswordVisible, onChange: (value) => {
|
|
122
|
+
setNewPassword(value);
|
|
123
|
+
if (errors.newPassword) {
|
|
124
|
+
setErrors(Object.assign(Object.assign({}, errors), { newPassword: undefined }));
|
|
125
|
+
}
|
|
126
|
+
}, onToggleVisibility: () => setNewPasswordVisible(!newPasswordVisible), errorMessage: errors.newPassword }) }), passwordRequirementsList.length > 0 && (_jsxs("div", { className: "cls_password_change_dialog_requirements text-xs text-slate-600", children: [_jsx("p", { className: "cls_password_change_dialog_requirements_label font-medium mb-1", children: "Password requirements:" }), _jsx("ul", { className: "cls_password_change_dialog_requirements_list list-disc list-inside space-y-0.5", children: passwordRequirementsList.map((req, index) => (_jsx("li", { children: req }, index))) })] })), _jsx(FormFieldWrapper, { fieldId: "confirm-password", label: confirmPasswordLabel, input: _jsx(PasswordField, { inputId: "confirm-password", ariaLabel: confirmPasswordLabel, value: confirmPassword, placeholder: "Confirm your new password", autoComplete: "new-password", isVisible: confirmPasswordVisible, onChange: (value) => {
|
|
127
|
+
setConfirmPassword(value);
|
|
128
|
+
if (errors.confirmPassword) {
|
|
129
|
+
setErrors(Object.assign(Object.assign({}, errors), { confirmPassword: undefined }));
|
|
130
|
+
}
|
|
131
|
+
}, onToggleVisibility: () => setConfirmPasswordVisible(!confirmPasswordVisible), errorMessage: errors.confirmPassword }) })] }), _jsxs("div", { className: "cls_password_change_dialog_actions flex justify-end gap-3 pt-4 border-t", children: [_jsx(Button, { type: "button", onClick: handleSave, disabled: isSubmitting, className: "cls_password_change_dialog_save_button", style: buttonPalette ? {
|
|
132
|
+
backgroundColor: buttonPalette.submitBackground,
|
|
133
|
+
color: buttonPalette.submitText,
|
|
134
|
+
} : undefined, "aria-label": saveButtonLabel, children: saveButtonLabel }), _jsx(Button, { type: "button", onClick: handleCancel, disabled: isSubmitting, variant: "outline", className: "cls_password_change_dialog_cancel_button", style: buttonPalette ? {
|
|
135
|
+
borderColor: buttonPalette.cancelBorder,
|
|
136
|
+
color: buttonPalette.cancelText,
|
|
137
|
+
} : undefined, "aria-label": cancelButtonLabel, children: cancelButtonLabel })] })] }) }));
|
|
138
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type ProfilePictureDialogProps = {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
onSave: (profilePictureUrl: string, profileSource: "upload" | "library" | "gravatar") => Promise<void>;
|
|
5
|
+
email: string;
|
|
6
|
+
allowPhotoUpload: boolean;
|
|
7
|
+
maxPhotoSize: number;
|
|
8
|
+
libraryPhotoPath: string;
|
|
9
|
+
currentProfilePictureUrl?: string;
|
|
10
|
+
currentProfileSource?: "upload" | "library" | "gravatar" | "custom";
|
|
11
|
+
saveButtonLabel?: string;
|
|
12
|
+
cancelButtonLabel?: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
messages: {
|
|
15
|
+
photo_upload_disabled_message: string;
|
|
16
|
+
gravatar_setup_message: string;
|
|
17
|
+
gravatar_no_account_message: string;
|
|
18
|
+
library_tooltip_message: string;
|
|
19
|
+
};
|
|
20
|
+
uiSizes: {
|
|
21
|
+
gravatar_size: number;
|
|
22
|
+
profile_picture_size: number;
|
|
23
|
+
tooltip_icon_size_default: number;
|
|
24
|
+
tooltip_icon_size_small: number;
|
|
25
|
+
library_photo_grid_columns: number;
|
|
26
|
+
library_photo_preview_size: number;
|
|
27
|
+
image_compression_max_dimension: number;
|
|
28
|
+
upload_file_hard_limit_bytes: number;
|
|
29
|
+
};
|
|
30
|
+
fileTypes: {
|
|
31
|
+
allowed_image_extensions: string[];
|
|
32
|
+
allowed_image_mime_types: string[];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Profile picture dialog component with tabs for Upload, Library, and Gravatar
|
|
37
|
+
* Only one switch can be active at a time
|
|
38
|
+
* @param props - Component props including open state, save handler, and configuration
|
|
39
|
+
* @returns Profile picture dialog component
|
|
40
|
+
*/
|
|
41
|
+
export declare function ProfilePictureDialog({ open, onOpenChange, onSave, email, allowPhotoUpload, maxPhotoSize, libraryPhotoPath, currentProfilePictureUrl, currentProfileSource, saveButtonLabel, cancelButtonLabel, disabled, messages, uiSizes, fileTypes, }: ProfilePictureDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
//# sourceMappingURL=profile_picture_dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_picture_dialog.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/components/profile_picture_dialog.tsx"],"names":[],"mappings":"AAsBA,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvG,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE;QACR,6BAA6B,EAAE,MAAM,CAAC;QACtC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,2BAA2B,EAAE,MAAM,CAAC;QACpC,uBAAuB,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;QAClC,uBAAuB,EAAE,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,CAAC;QACnC,0BAA0B,EAAE,MAAM,CAAC;QACnC,+BAA+B,EAAE,MAAM,CAAC;QACxC,4BAA4B,EAAE,MAAM,CAAC;KACtC,CAAC;IACF,SAAS,EAAE;QACT,wBAAwB,EAAE,MAAM,EAAE,CAAC;QACnC,wBAAwB,EAAE,MAAM,EAAE,CAAC;KACpC,CAAC;CACH,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,eAAwB,EACxB,iBAA4B,EAC5B,QAAgB,EAChB,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE,yBAAyB,2CA+S3B"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// file_description: profile picture dialog component with tabs for Upload, Library, and Gravatar
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useState, useEffect } from "react";
|
|
7
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "hazo_auth/components/ui/dialog";
|
|
8
|
+
import { Button } from "hazo_auth/components/ui/button";
|
|
9
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "hazo_auth/components/ui/tabs";
|
|
10
|
+
import { ProfilePictureUploadTab } from "hazo_auth/components/layouts/my_settings/components/profile_picture_upload_tab";
|
|
11
|
+
import { ProfilePictureLibraryTab } from "hazo_auth/components/layouts/my_settings/components/profile_picture_library_tab";
|
|
12
|
+
import { ProfilePictureGravatarTab } from "hazo_auth/components/layouts/my_settings/components/profile_picture_gravatar_tab";
|
|
13
|
+
import { toast } from "sonner";
|
|
14
|
+
import { cn } from "hazo_auth/lib/utils";
|
|
15
|
+
// section: component
|
|
16
|
+
/**
|
|
17
|
+
* Profile picture dialog component with tabs for Upload, Library, and Gravatar
|
|
18
|
+
* Only one switch can be active at a time
|
|
19
|
+
* @param props - Component props including open state, save handler, and configuration
|
|
20
|
+
* @returns Profile picture dialog component
|
|
21
|
+
*/
|
|
22
|
+
export function ProfilePictureDialog({ open, onOpenChange, onSave, email, allowPhotoUpload, maxPhotoSize, libraryPhotoPath, currentProfilePictureUrl, currentProfileSource, saveButtonLabel = "Save", cancelButtonLabel = "Cancel", disabled = false, messages, uiSizes, fileTypes, }) {
|
|
23
|
+
const [useUpload, setUseUpload] = useState(false);
|
|
24
|
+
const [useLibrary, setUseLibrary] = useState(false);
|
|
25
|
+
const [useGravatar, setUseGravatar] = useState(false);
|
|
26
|
+
const [selectedPhotoUrl, setSelectedPhotoUrl] = useState(null);
|
|
27
|
+
const [selectedSource, setSelectedSource] = useState(null);
|
|
28
|
+
const [uploadedFile, setUploadedFile] = useState(null);
|
|
29
|
+
const [uploading, setUploading] = useState(false);
|
|
30
|
+
const [activeTab, setActiveTab] = useState(allowPhotoUpload ? "upload" : "library");
|
|
31
|
+
// Initialize state based on current profile picture
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (open) {
|
|
34
|
+
// Determine default active tab (skip upload if not enabled)
|
|
35
|
+
const defaultTab = allowPhotoUpload ? "upload" : "library";
|
|
36
|
+
// Handle current profile source (may be "upload", "library", "gravatar", or "custom")
|
|
37
|
+
// "custom" should be treated as "upload" for backwards compatibility
|
|
38
|
+
const normalizedSource = currentProfileSource === "custom" ? "upload" : currentProfileSource;
|
|
39
|
+
if (normalizedSource === "upload" && allowPhotoUpload) {
|
|
40
|
+
setUseUpload(true);
|
|
41
|
+
setUseLibrary(false);
|
|
42
|
+
setUseGravatar(false);
|
|
43
|
+
setSelectedSource("upload");
|
|
44
|
+
setSelectedPhotoUrl(currentProfilePictureUrl || null); // Set current image for upload tab
|
|
45
|
+
setActiveTab("upload");
|
|
46
|
+
}
|
|
47
|
+
else if (normalizedSource === "library") {
|
|
48
|
+
setUseUpload(false);
|
|
49
|
+
setUseLibrary(true);
|
|
50
|
+
setUseGravatar(false);
|
|
51
|
+
setSelectedSource("library");
|
|
52
|
+
setSelectedPhotoUrl(currentProfilePictureUrl || null);
|
|
53
|
+
setActiveTab("library");
|
|
54
|
+
}
|
|
55
|
+
else if (normalizedSource === "gravatar") {
|
|
56
|
+
setUseUpload(false);
|
|
57
|
+
setUseLibrary(false);
|
|
58
|
+
setUseGravatar(true);
|
|
59
|
+
setSelectedSource("gravatar");
|
|
60
|
+
setActiveTab("gravatar");
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Reset to defaults
|
|
64
|
+
setUseUpload(false);
|
|
65
|
+
setUseLibrary(false);
|
|
66
|
+
setUseGravatar(false);
|
|
67
|
+
setSelectedSource(null);
|
|
68
|
+
setSelectedPhotoUrl(null);
|
|
69
|
+
setUploadedFile(null);
|
|
70
|
+
setActiveTab(defaultTab);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}, [open, currentProfileSource, currentProfilePictureUrl, allowPhotoUpload]);
|
|
74
|
+
const handleUseUploadChange = (use) => {
|
|
75
|
+
if (!allowPhotoUpload) {
|
|
76
|
+
return; // Prevent changes if upload is not enabled
|
|
77
|
+
}
|
|
78
|
+
setUseUpload(use);
|
|
79
|
+
if (use) {
|
|
80
|
+
setUseLibrary(false);
|
|
81
|
+
setUseGravatar(false);
|
|
82
|
+
setSelectedPhotoUrl(null); // Clear library photo URL when upload is selected
|
|
83
|
+
setSelectedSource("upload");
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
setSelectedSource(null);
|
|
87
|
+
setUploadedFile(null);
|
|
88
|
+
setSelectedPhotoUrl(null);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const handleUseLibraryChange = (use) => {
|
|
92
|
+
setUseLibrary(use);
|
|
93
|
+
if (use) {
|
|
94
|
+
if (allowPhotoUpload) {
|
|
95
|
+
setUseUpload(false);
|
|
96
|
+
setUploadedFile(null);
|
|
97
|
+
}
|
|
98
|
+
setUseGravatar(false);
|
|
99
|
+
setSelectedSource("library");
|
|
100
|
+
// Note: selectedPhotoUrl should already be set when a photo is selected
|
|
101
|
+
// If no photo is selected yet, the first photo in the category will be auto-selected
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
setSelectedSource(null);
|
|
105
|
+
setSelectedPhotoUrl(null);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const handleUseGravatarChange = (use) => {
|
|
109
|
+
setUseGravatar(use);
|
|
110
|
+
if (use) {
|
|
111
|
+
if (allowPhotoUpload) {
|
|
112
|
+
setUseUpload(false);
|
|
113
|
+
setUploadedFile(null);
|
|
114
|
+
}
|
|
115
|
+
setUseLibrary(false);
|
|
116
|
+
setSelectedPhotoUrl(null); // Clear library photo URL when Gravatar is selected
|
|
117
|
+
setSelectedSource("gravatar");
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
setSelectedSource(null);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const handleFileSelect = async (file) => {
|
|
124
|
+
setUploadedFile(file);
|
|
125
|
+
setUploading(true);
|
|
126
|
+
try {
|
|
127
|
+
const formData = new FormData();
|
|
128
|
+
formData.append("file", file);
|
|
129
|
+
const response = await fetch("/api/hazo_auth/upload_profile_picture", {
|
|
130
|
+
method: "POST",
|
|
131
|
+
credentials: "include",
|
|
132
|
+
body: formData,
|
|
133
|
+
});
|
|
134
|
+
const data = await response.json();
|
|
135
|
+
if (!response.ok || !data.success) {
|
|
136
|
+
const errorMessage = data.error || "Failed to upload photo";
|
|
137
|
+
toast.error(errorMessage);
|
|
138
|
+
setUploadedFile(null);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
setSelectedPhotoUrl(data.profile_picture_url);
|
|
142
|
+
toast.success("Photo uploaded successfully");
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to upload photo";
|
|
146
|
+
toast.error(errorMessage);
|
|
147
|
+
setUploadedFile(null);
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
setUploading(false);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const handlePhotoSelect = (photoUrl) => {
|
|
154
|
+
setSelectedPhotoUrl(photoUrl);
|
|
155
|
+
// Automatically enable library photo when a photo is selected
|
|
156
|
+
if (!useLibrary) {
|
|
157
|
+
handleUseLibraryChange(true);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const handleSave = async () => {
|
|
161
|
+
if (!selectedSource) {
|
|
162
|
+
toast.error("Please select a profile picture source");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (selectedSource === "upload" && !selectedPhotoUrl) {
|
|
166
|
+
toast.error("Please upload a photo first");
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (selectedSource === "library" && !selectedPhotoUrl) {
|
|
170
|
+
toast.error("Please select a photo from the library");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (selectedSource === "gravatar") {
|
|
174
|
+
// For Gravatar, generate the URL client-side using gravatar-url
|
|
175
|
+
// The onSave handler will use this URL directly
|
|
176
|
+
const gravatarUrlModule = await import("gravatar-url");
|
|
177
|
+
const gravatarUrl = gravatarUrlModule.default(email, {
|
|
178
|
+
size: 200,
|
|
179
|
+
default: "identicon",
|
|
180
|
+
});
|
|
181
|
+
await onSave(gravatarUrl, "gravatar");
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (selectedPhotoUrl) {
|
|
185
|
+
await onSave(selectedPhotoUrl, selectedSource);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const handleCancel = () => {
|
|
189
|
+
setUseUpload(false);
|
|
190
|
+
setUseLibrary(false);
|
|
191
|
+
setUseGravatar(false);
|
|
192
|
+
setSelectedPhotoUrl(null);
|
|
193
|
+
setSelectedSource(null);
|
|
194
|
+
setUploadedFile(null);
|
|
195
|
+
onOpenChange(false);
|
|
196
|
+
};
|
|
197
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "cls_profile_picture_dialog max-w-4xl max-h-[90vh] overflow-y-auto", children: [_jsxs(DialogHeader, { className: "cls_profile_picture_dialog_header", children: [_jsx(DialogTitle, { className: "cls_profile_picture_dialog_title", children: "Change Profile Picture" }), _jsx(DialogDescription, { className: "cls_profile_picture_dialog_description", children: "Choose how you want to set your profile picture" })] }), _jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "cls_profile_picture_dialog_tabs", children: [_jsxs(TabsList, { className: "cls_profile_picture_dialog_tabs_list", children: [allowPhotoUpload && (_jsx(TabsTrigger, { value: "upload", className: cn("cls_profile_picture_dialog_tabs_trigger", useUpload && "!text-blue-600 font-semibold data-[state=active]:!text-blue-600"), children: "Upload" })), _jsx(TabsTrigger, { value: "library", className: cn("cls_profile_picture_dialog_tabs_trigger", useLibrary && "!text-blue-600 font-semibold data-[state=active]:!text-blue-600"), children: "Library" }), _jsx(TabsTrigger, { value: "gravatar", className: cn("cls_profile_picture_dialog_tabs_trigger", useGravatar && "!text-blue-600 font-semibold data-[state=active]:!text-blue-600"), children: "Gravatar" })] }), allowPhotoUpload && (_jsx(TabsContent, { value: "upload", className: "cls_profile_picture_dialog_tabs_content", children: _jsx(ProfilePictureUploadTab, { useUpload: useUpload, onUseUploadChange: handleUseUploadChange, onFileSelect: handleFileSelect, maxSize: maxPhotoSize, uploadEnabled: allowPhotoUpload, disabled: disabled || uploading, currentPreview: currentProfilePictureUrl || selectedPhotoUrl || undefined, photoUploadDisabledMessage: messages.photo_upload_disabled_message, imageCompressionMaxDimension: uiSizes.image_compression_max_dimension, uploadFileHardLimitBytes: uiSizes.upload_file_hard_limit_bytes, allowedImageMimeTypes: fileTypes.allowed_image_mime_types }) })), _jsx(TabsContent, { value: "library", className: "cls_profile_picture_dialog_tabs_content", children: _jsx(ProfilePictureLibraryTab, { useLibrary: useLibrary, onUseLibraryChange: handleUseLibraryChange, onPhotoSelect: handlePhotoSelect, disabled: disabled, libraryPhotoPath: libraryPhotoPath, currentPhotoUrl: selectedPhotoUrl || undefined, libraryTooltipMessage: messages.library_tooltip_message, tooltipIconSizeSmall: uiSizes.tooltip_icon_size_small, libraryPhotoGridColumns: uiSizes.library_photo_grid_columns, libraryPhotoPreviewSize: uiSizes.library_photo_preview_size }) }), _jsx(TabsContent, { value: "gravatar", className: "cls_profile_picture_dialog_tabs_content", children: _jsx(ProfilePictureGravatarTab, { email: email, useGravatar: useGravatar, onUseGravatarChange: handleUseGravatarChange, disabled: disabled, gravatarSetupMessage: messages.gravatar_setup_message, gravatarNoAccountMessage: messages.gravatar_no_account_message, gravatarSize: uiSizes.gravatar_size }) })] }), _jsxs("div", { className: "cls_profile_picture_dialog_actions flex justify-end gap-3 pt-4 border-t", children: [_jsx(Button, { type: "button", onClick: handleSave, disabled: disabled || uploading || !selectedSource, className: "cls_profile_picture_dialog_save_button", "aria-label": saveButtonLabel, children: saveButtonLabel }), _jsx(Button, { type: "button", onClick: handleCancel, disabled: disabled || uploading, variant: "outline", className: "cls_profile_picture_dialog_cancel_button", "aria-label": cancelButtonLabel, children: cancelButtonLabel })] })] }) }));
|
|
198
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ProfilePictureDisplayProps = {
|
|
2
|
+
profilePictureUrl?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
email?: string;
|
|
5
|
+
onEdit?: () => void;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Profile picture display component
|
|
10
|
+
* Shows profile picture with fallback to initials or default icon
|
|
11
|
+
* Displays pencil icon for editing (functionality to be implemented later)
|
|
12
|
+
* @param props - Component props including profile picture URL, name, email, onEdit callback
|
|
13
|
+
* @returns Profile picture display component
|
|
14
|
+
*/
|
|
15
|
+
export declare function ProfilePictureDisplay({ profilePictureUrl, name, email, onEdit, disabled, }: ProfilePictureDisplayProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=profile_picture_display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_picture_display.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/components/profile_picture_display.tsx"],"names":[],"mappings":"AAUA,MAAM,MAAM,0BAA0B,GAAG;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAGF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,iBAAiB,EACjB,IAAI,EACJ,KAAK,EACL,MAAM,EACN,QAAgB,GACjB,EAAE,0BAA0B,2CAgC5B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// file_description: component for displaying and editing profile picture (edit functionality to be implemented later)
|
|
2
|
+
// section: client_directive
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { Avatar, AvatarImage, AvatarFallback } from "hazo_auth/components/ui/avatar";
|
|
7
|
+
// section: component
|
|
8
|
+
/**
|
|
9
|
+
* Profile picture display component
|
|
10
|
+
* Shows profile picture with fallback to initials or default icon
|
|
11
|
+
* Displays pencil icon for editing (functionality to be implemented later)
|
|
12
|
+
* @param props - Component props including profile picture URL, name, email, onEdit callback
|
|
13
|
+
* @returns Profile picture display component
|
|
14
|
+
*/
|
|
15
|
+
export function ProfilePictureDisplay({ profilePictureUrl, name, email, onEdit, disabled = false, }) {
|
|
16
|
+
// Get initials from name or email
|
|
17
|
+
const getInitials = () => {
|
|
18
|
+
var _a, _b;
|
|
19
|
+
if (name) {
|
|
20
|
+
const parts = name.trim().split(" ");
|
|
21
|
+
if (parts.length >= 2) {
|
|
22
|
+
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
|
|
23
|
+
}
|
|
24
|
+
return ((_a = name[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || "";
|
|
25
|
+
}
|
|
26
|
+
if (email) {
|
|
27
|
+
return ((_b = email[0]) === null || _b === void 0 ? void 0 : _b.toUpperCase()) || "";
|
|
28
|
+
}
|
|
29
|
+
return "?";
|
|
30
|
+
};
|
|
31
|
+
const initials = getInitials();
|
|
32
|
+
return (_jsx("div", { className: "cls_profile_picture_display", children: _jsxs(Avatar, { className: "cls_profile_picture_display_avatar h-32 w-32", children: [_jsx(AvatarImage, { src: profilePictureUrl, alt: name ? `Profile picture of ${name}` : "Profile picture", className: "cls_profile_picture_display_image" }), _jsx(AvatarFallback, { className: "cls_profile_picture_display_fallback bg-slate-200 text-slate-600 text-3xl", children: initials })] }) }));
|
|
33
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ProfilePictureGravatarTabProps = {
|
|
2
|
+
email: string;
|
|
3
|
+
useGravatar: boolean;
|
|
4
|
+
onUseGravatarChange: (use: boolean) => void;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
gravatarSetupMessage: string;
|
|
7
|
+
gravatarNoAccountMessage: string;
|
|
8
|
+
gravatarSize: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Gravatar tab component for profile picture dialog
|
|
12
|
+
* Shows Gravatar preview and setup instructions
|
|
13
|
+
* @param props - Component props including email, useGravatar state, and change handler
|
|
14
|
+
* @returns Gravatar tab component
|
|
15
|
+
*/
|
|
16
|
+
export declare function ProfilePictureGravatarTab({ email, useGravatar, onUseGravatarChange, disabled, gravatarSetupMessage, gravatarNoAccountMessage, gravatarSize, }: ProfilePictureGravatarTabProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=profile_picture_gravatar_tab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile_picture_gravatar_tab.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/components/profile_picture_gravatar_tab.tsx"],"names":[],"mappings":"AAaA,MAAM,MAAM,8BAA8B,GAAG;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wBAAwB,EAAE,MAAM,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,WAAW,EACX,mBAAmB,EACnB,QAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,YAAY,GACb,EAAE,8BAA8B,2CAuGhC"}
|