@micha.bigler/ui-core-micha 1.4.29 → 1.4.31

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.
Files changed (35) hide show
  1. package/dist/components/AccessCodeManager.js +0 -1
  2. package/dist/components/LoginForm.js +5 -5
  3. package/dist/components/MFAComponent.js +3 -3
  4. package/dist/components/MfaLoginComponent.js +3 -3
  5. package/dist/components/PasskeysComponent.js +3 -3
  6. package/dist/components/PasswordChangeForm.js +3 -3
  7. package/dist/components/PasswordResetRequestForm.js +3 -3
  8. package/dist/components/PasswordSetForm.js +3 -3
  9. package/dist/components/ProfileComponent.js +0 -1
  10. package/dist/components/SecurityComponent.js +8 -8
  11. package/dist/components/SocialLoginButtons.js +3 -3
  12. package/dist/components/SupportRecoveryRequestsTab.js +3 -3
  13. package/dist/pages/LoginPage.js +2 -3
  14. package/dist/pages/PasswordChangePage.js +1 -2
  15. package/dist/pages/PasswordInvitePage.js +1 -2
  16. package/dist/pages/PasswordResetRequestPage.js +1 -2
  17. package/dist/pages/SignUpPage.js +0 -1
  18. package/package.json +1 -1
  19. package/src/components/AccessCodeManager.jsx +0 -1
  20. package/src/components/LoginForm.jsx +3 -5
  21. package/src/components/MFAComponent.jsx +2 -2
  22. package/src/components/MfaLoginComponent.jsx +1 -2
  23. package/src/components/PasskeysComponent.jsx +1 -2
  24. package/src/components/PasswordChangeForm.jsx +1 -2
  25. package/src/components/PasswordResetRequestForm.jsx +1 -2
  26. package/src/components/PasswordSetForm.jsx +1 -2
  27. package/src/components/ProfileComponent.jsx +0 -2
  28. package/src/components/SecurityComponent.jsx +6 -7
  29. package/src/components/SocialLoginButtons.jsx +1 -2
  30. package/src/components/SupportRecoveryRequestsTab.jsx +1 -2
  31. package/src/pages/LoginPage.jsx +3 -5
  32. package/src/pages/PasswordChangePage.jsx +1 -4
  33. package/src/pages/PasswordInvitePage.jsx +1 -3
  34. package/src/pages/PasswordResetRequestPage.jsx +1 -3
  35. package/src/pages/SignUpPage.jsx +0 -2
@@ -98,4 +98,3 @@ export function AccessCodeManager() {
98
98
  ? t('Auth.SAVE_BUTTON_LOADING')
99
99
  : t('Auth.ACCESS_CODE_GENERATE_BUTTON') })] }), _jsxs(Box, { sx: { mb: 2, maxWidth: 360 }, children: [_jsx(Typography, { variant: "subtitle1", gutterBottom: true, children: t('Auth.ACCESS_CODE_SECTION_MANUAL') }), _jsxs(Box, { sx: { display: 'flex', gap: 1 }, children: [_jsx(TextField, { label: t('Auth.ACCESS_CODE_LABEL'), fullWidth: true, value: manualCode, onChange: (e) => setManualCode(e.target.value), disabled: submitting }), _jsx(Button, { variant: "outlined", onClick: handleAddManual, disabled: submitting, children: t('Auth.ACCESS_CODE_ADD_BUTTON') })] })] })] }));
100
100
  }
101
- export default AccessCodeManager;
@@ -2,9 +2,9 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import React, { useState, useEffect } from 'react';
3
3
  import { Box, TextField, Button, Typography, Divider, } from '@mui/material';
4
4
  import { useTranslation } from 'react-i18next';
5
- import SocialLoginButtons from './SocialLoginButtons';
6
- const LoginForm = ({ onSubmit, onForgotPassword, onSocialLogin, onPasskeyLogin, onSignUp, error, // bereits übersetzter Text oder t(errorKey) aus dem Parent
7
- disabled = false, initialIdentifier = '', }) => {
5
+ import { SocialLoginButtons } from './SocialLoginButtons';
6
+ export function LoginForm({ onSubmit, onForgotPassword, onSocialLogin, onPasskeyLogin, onSignUp, error, // bereits übersetzter Text oder t(errorKey) aus dem Parent
7
+ disabled = false, initialIdentifier = '', }) {
8
8
  const { t } = useTranslation();
9
9
  const [identifier, setIdentifier] = useState(initialIdentifier);
10
10
  const [password, setPassword] = useState('');
@@ -22,5 +22,5 @@ disabled = false, initialIdentifier = '', }) => {
22
22
  typeof window !== 'undefined' &&
23
23
  !!window.PublicKeyCredential;
24
24
  return (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [error && (_jsx(Typography, { color: "error", gutterBottom: true, children: error })), supportsPasskey && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "contained", fullWidth: true, type: "button", onClick: onPasskeyLogin, disabled: disabled, children: t('Auth.LOGIN_USE_PASSKEY_BUTTON') }), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') })] })), _jsxs(Box, { component: "form", onSubmit: handleSubmit, sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(TextField, { label: t('Auth.EMAIL_LABEL'), type: "email", required: true, fullWidth: true, value: identifier, onChange: (e) => setIdentifier(e.target.value), disabled: disabled }), _jsx(TextField, { label: t('Auth.LOGIN_PASSWORD_LABEL'), type: "password", required: true, fullWidth: true, value: password, onChange: (e) => setPassword(e.target.value), disabled: disabled }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: disabled, children: t('Auth.PAGE_LOGIN_TITLE') })] }), _jsxs(Box, { children: [_jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') }), _jsx(SocialLoginButtons, { onProviderClick: onSocialLogin })] }), _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: t('Auth.LOGIN_ACCOUNT_RECOVERY_TITLE') }), _jsxs(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: [onSignUp && (_jsx(Button, { type: "button", variant: "outlined", onClick: onSignUp, disabled: disabled, children: t('Auth.LOGIN_SIGNUP_BUTTON') })), _jsx(Button, { type: "button", variant: "outlined", onClick: onForgotPassword, disabled: disabled, children: t('Auth.LOGIN_FORGOT_PASSWORD_BUTTON') })] })] })] }));
25
- };
26
- export default LoginForm;
25
+ }
26
+ ;
@@ -7,7 +7,7 @@ import DeleteIcon from '@mui/icons-material/Delete';
7
7
  import ContentCopyIcon from '@mui/icons-material/ContentCopy';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { fetchAuthenticators, requestTotpKey, activateTotp, deactivateTotp, fetchRecoveryCodes, generateRecoveryCodes } from '../auth/authApi';
10
- const MFAComponent = () => {
10
+ export function MFAComponent() {
11
11
  const { t } = useTranslation();
12
12
  const [authenticators, setAuthenticators] = useState([]);
13
13
  const [loading, setLoading] = useState(true);
@@ -162,5 +162,5 @@ const MFAComponent = () => {
162
162
  alignItems: 'center',
163
163
  gap: 1,
164
164
  }, children: [code, _jsx(Tooltip, { title: t('Auth.MFA_RECOVERY_COPY_TOOLTIP'), children: _jsx(IconButton, { size: "small", onClick: () => handleCopyCode(code), children: _jsx(ContentCopyIcon, { fontSize: "small" }) }) })] }, code))) }), _jsx(Button, { sx: { mt: 2 }, size: "small", onClick: handleGenerateNewRecoveryCodes, children: t('Auth.MFA_RECOVERY_GENERATE_NEW') })] }))] }));
165
- };
166
- export default MFAComponent;
165
+ }
166
+ ;
@@ -5,7 +5,7 @@ import { Box, Typography, TextField, Button, Stack, Alert, Divider, Dialog, Dial
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { authenticateWithMFA, fetchCurrentUser, requestMfaSupportHelp } from '../auth/authApi';
7
7
  import { loginWithPasskey } from '../utils/authService';
8
- const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel }) => {
8
+ export function MfaLoginComponent({ availableTypes, identifier, onSuccess, onCancel }) {
9
9
  const { t } = useTranslation();
10
10
  const [code, setCode] = useState('');
11
11
  const [submitting, setSubmitting] = useState(false);
@@ -78,5 +78,5 @@ const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel })
78
78
  }
79
79
  };
80
80
  return (_jsxs(Box, { children: [_jsx(Typography, { variant: "body2", sx: { mb: 2 }, children: t('Auth.MFA_SUBTITLE', 'Please confirm your login using one of the available methods.') }), errorKey && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: t(errorKey) })), infoKey && (_jsx(Alert, { severity: "info", sx: { mb: 2 }, children: t(infoKey) })), _jsxs(Stack, { spacing: 2, children: [supportsWebauthn && (_jsx(Button, { variant: "contained", fullWidth: true, onClick: handlePasskey, disabled: submitting || helpRequested, children: t('Auth.LOGIN_USE_PASSKEY_BUTTON', 'Use passkey / security key') })), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') }), supportsTotpOrRecovery && (_jsxs(Box, { component: "form", onSubmit: handleSubmitCode, children: [_jsx(TextField, { label: t('Auth.MFA_CODE_LABEL', 'Authenticator code (or recovery code)'), value: code, onChange: (e) => setCode(e.target.value), fullWidth: true, disabled: submitting || helpRequested, autoComplete: "one-time-code", sx: { mb: 2 } }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: submitting || !code.trim() || helpRequested, children: t('Auth.MFA_VERIFY', 'Verify') })] })), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') }), _jsxs(Stack, { direction: "row", spacing: 1, sx: { mt: 1 }, children: [_jsx(Button, { fullWidth: true, size: "small", variant: "outlined", onClick: onCancel, disabled: submitting, children: t('Auth.MFA_BACK_TO_LOGIN', 'Back to login') }), _jsx(Button, { fullWidth: true, size: "small", variant: "outlined", color: "secondary", onClick: openHelpDialog, disabled: submitting || helpRequested, children: t('Auth.MFA_NEED_HELP', "I can't use any of these methods") })] })] }), _jsxs(Dialog, { open: helpDialogOpen, onClose: () => setHelpDialogOpen(false), fullWidth: true, maxWidth: "sm", children: [_jsx(DialogTitle, { children: t('Auth.MFA_HELP_DIALOG_TITLE', 'Need help with sign-in') }), _jsxs(DialogContent, { dividers: true, children: [_jsx(Typography, { variant: "body2", sx: { mb: 2 }, children: t('Auth.MFA_HELP_DIALOG_DESCRIPTION', 'Describe briefly why you cannot use the available methods. A support person will review your request.') }), _jsx(TextField, { label: t('Auth.MFA_HELP_MESSAGE_LABEL', 'Your message to support'), multiline: true, minRows: 3, fullWidth: true, value: helpMessage, onChange: (e) => setHelpMessage(e.target.value), disabled: submitting })] }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setHelpDialogOpen(false), disabled: submitting, children: t('Common.CANCEL', 'Cancel') }), _jsx(Button, { onClick: handleNeedHelp, disabled: submitting, variant: "contained", children: t('Auth.MFA_HELP_SUBMIT', 'Send request') })] })] })] }));
81
- };
82
- export default MfaLoginComponent;
81
+ }
82
+ ;
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
7
7
  import { fetchPasskeys, deletePasskey } from '../auth/authApi';
8
8
  import { registerPasskey } from '../utils/authService';
9
9
  import { FEATURES } from '../auth/authConfig';
10
- const PasskeysComponent = () => {
10
+ export function PasskeysComponent() {
11
11
  const { t } = useTranslation();
12
12
  const [passkeys, setPasskeys] = useState([]);
13
13
  const [loading, setLoading] = useState(true);
@@ -97,5 +97,5 @@ const PasskeysComponent = () => {
97
97
  value: pk.created_at,
98
98
  })
99
99
  : undefined }), _jsx(ListItemSecondaryAction, { children: _jsx(Tooltip, { title: t('Auth.PASSKEY_DELETE_TOOLTIP'), children: _jsx("span", { children: _jsx(IconButton, { edge: "end", "aria-label": "delete", onClick: () => handleDelete(pk.id), disabled: deletingIds.has(pk.id), size: "small", children: deletingIds.has(pk.id) ? (_jsx(CircularProgress, { size: 18 })) : (_jsx(DeleteIcon, { fontSize: "small" })) }) }) }) })] }, pk.id))) }))] }))] }));
100
- };
101
- export default PasskeysComponent;
100
+ }
101
+ ;
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
  * A simplified form to handle password changes.
7
7
  * Does not require password confirmation.
8
8
  */
9
- const PasswordChangeForm = ({ onSubmit, submitting = false }) => {
9
+ export function PasswordChangeForm({ onSubmit, submitting = false }) {
10
10
  const { t } = useTranslation();
11
11
  const [currentPassword, setCurrentPassword] = useState('');
12
12
  const [newPassword, setNewPassword] = useState('');
@@ -23,5 +23,5 @@ const PasswordChangeForm = ({ onSubmit, submitting = false }) => {
23
23
  return (_jsx(Box, { component: "form", onSubmit: handleSubmit, sx: { maxWidth: 500 }, children: _jsxs(Stack, { spacing: 2, children: [_jsx(TextField, { label: t('Auth.CURRENT_PASSWORD_LABEL'), type: "password", value: currentPassword, onChange: (e) => setCurrentPassword(e.target.value), required: true, fullWidth: true, disabled: submitting }), _jsx(TextField, { label: t('Auth.NEW_PASSWORD_LABEL'), type: "password", value: newPassword, onChange: (e) => setNewPassword(e.target.value), required: true, fullWidth: true, disabled: submitting }), _jsx(Box, { children: _jsx(Button, { type: "submit", variant: "contained", disabled: submitting, children: submitting
24
24
  ? t('Auth.CHANGE_PASSWORD_BUTTON_LOADING')
25
25
  : t('Auth.CHANGE_PASSWORD_BUTTON') }) })] }) }));
26
- };
27
- export default PasswordChangeForm;
26
+ }
27
+ ;
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { useState } from 'react';
4
4
  import { Box, TextField, Button } from '@mui/material';
5
5
  import { useTranslation } from 'react-i18next';
6
- const PasswordResetRequestForm = ({ onSubmit, submitting = false }) => {
6
+ export function PasswordResetRequestForm({ onSubmit, submitting = false }) {
7
7
  const { t } = useTranslation();
8
8
  const [email, setEmail] = useState('');
9
9
  const handleSubmit = (event) => {
@@ -15,5 +15,5 @@ const PasswordResetRequestForm = ({ onSubmit, submitting = false }) => {
15
15
  return (_jsxs(Box, { component: "form", onSubmit: handleSubmit, sx: { display: 'flex', flexDirection: 'column', gap: 2, mt: 2 }, children: [_jsx(TextField, { label: t('Auth.EMAIL_LABEL'), type: "email", required: true, fullWidth: true, value: email, onChange: (e) => setEmail(e.target.value), disabled: submitting }), _jsx(Button, { type: "submit", variant: "contained", disabled: submitting, children: submitting
16
16
  ? t('Auth.RESET_REQUEST_BUTTON_LOADING')
17
17
  : t('Auth.RESET_REQUEST_BUTTON') })] }));
18
- };
19
- export default PasswordResetRequestForm;
18
+ }
19
+ ;
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
7
7
  * Simple form to set a new password (once, with confirmation).
8
8
  * Caller passes onSubmit(newPassword) and handles redirect / API call.
9
9
  */
10
- const PasswordSetForm = ({ onSubmit, submitting = false }) => {
10
+ export function PasswordSetForm({ onSubmit, submitting = false }) {
11
11
  const { t } = useTranslation();
12
12
  const [password1, setPassword1] = useState('');
13
13
  const [password2, setPassword2] = useState('');
@@ -30,5 +30,5 @@ const PasswordSetForm = ({ onSubmit, submitting = false }) => {
30
30
  return (_jsxs(Box, { component: "form", onSubmit: handleSubmit, sx: { display: 'flex', flexDirection: 'column', gap: 2, mt: 2 }, children: [localErrorKey && (_jsx(Box, { sx: { color: 'error.main', fontSize: 14 }, children: t(localErrorKey) })), _jsx(TextField, { label: t('Auth.NEW_PASSWORD_LABEL'), type: "password", fullWidth: true, autoComplete: "new-password", value: password1, onChange: (e) => setPassword1(e.target.value), disabled: submitting }), _jsx(TextField, { label: t('Auth.PASSWORD_CONFIRM_LABEL'), type: "password", fullWidth: true, autoComplete: "new-password", value: password2, onChange: (e) => setPassword2(e.target.value), disabled: submitting }), _jsx(Button, { type: "submit", variant: "contained", disabled: submitting, children: submitting
31
31
  ? t('Auth.PASSWORD_SET_BUTTON_LOADING')
32
32
  : t('Auth.PASSWORD_SET_BUTTON') })] }));
33
- };
34
- export default PasswordSetForm;
33
+ }
34
+ ;
@@ -70,4 +70,3 @@ export function ProfileComponent({ onSubmit, submitText, showName = true, showPr
70
70
  const submitLabelLoading = t('Profile.SAVE_BUTTON_LOADING');
71
71
  return (_jsxs(Box, { component: "form", onSubmit: handleSubmit, sx: { maxWidth: 600, display: 'flex', flexDirection: 'column', gap: 2 }, children: [errorKey && (_jsx(Alert, { severity: "error", children: t(errorKey) })), successKey && (_jsx(Alert, { severity: "success", children: t(successKey) })), _jsxs(Stack, { spacing: 2, children: [_jsx(TextField, { label: t('Profile.USERNAME_LABEL'), value: username, fullWidth: true, disabled: true }), _jsx(TextField, { label: t('Auth.EMAIL_LABEL'), type: "email", value: email, fullWidth: true, disabled: true })] }), showName && (_jsxs(Stack, { spacing: 2, direction: { xs: 'column', sm: 'row' }, children: [_jsx(TextField, { label: t('Profile.FIRST_NAME_LABEL'), value: firstName, onChange: (e) => setFirstName(e.target.value), fullWidth: true }), _jsx(TextField, { label: t('Profile.LAST_NAME_LABEL'), value: lastName, onChange: (e) => setLastName(e.target.value), fullWidth: true })] })), (showPrivacy || showCookies) && (_jsxs(Box, { sx: { mt: 1 }, children: [_jsx(Typography, { variant: "subtitle1", gutterBottom: true, children: t('Profile.PRIVACY_SECTION_TITLE') }), _jsxs(Stack, { spacing: 1, children: [showPrivacy && (_jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: acceptedPrivacy, onChange: (e) => setAcceptedPrivacy(e.target.checked) }), label: t('Profile.ACCEPT_PRIVACY_LABEL') })), showCookies && (_jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: acceptedCookies, onChange: (e) => setAcceptedCookies(e.target.checked) }), label: t('Profile.ACCEPT_COOKIES_LABEL') }))] })] })), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { type: "submit", variant: "contained", disabled: saving, children: saving ? submitLabelLoading : submitLabel }) })] }));
72
72
  }
73
- export default ProfileComponent;
@@ -3,14 +3,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { useState } from 'react';
4
4
  import { Box, Typography, Divider, Alert, } from '@mui/material';
5
5
  import { useTranslation } from 'react-i18next';
6
- import PasswordChangeForm from './PasswordChangeForm';
7
- import SocialLoginButtons from './SocialLoginButtons';
8
- import PasskeysComponent from './PasskeysComponent';
9
- import MFAComponent from './MFAComponent';
6
+ import { PasswordChangeForm } from './PasswordChangeForm';
7
+ import { SocialLoginButtons } from './SocialLoginButtons';
8
+ import { PasskeysComponent } from './PasskeysComponent';
9
+ import { MFAComponent } from './MFAComponent';
10
10
  import { changePassword } from '../auth/authApi';
11
11
  import { startSocialLogin } from '../utils/authService';
12
- const SecurityComponent = ({ fromRecovery = false, fromWeakLogin = false, // optional: wenn du später weak-login-Redirect nutzt
13
- }) => {
12
+ export function SecurityComponent({ fromRecovery = false, fromWeakLogin = false, // optional: wenn du später weak-login-Redirect nutzt
13
+ }) {
14
14
  const { t } = useTranslation();
15
15
  const [messageKey, setMessageKey] = useState(null);
16
16
  const [errorKey, setErrorKey] = useState(null);
@@ -37,5 +37,5 @@ const SecurityComponent = ({ fromRecovery = false, fromWeakLogin = false, // opt
37
37
  }
38
38
  };
39
39
  return (_jsxs(Box, { children: [fromRecovery && (_jsx(Alert, { severity: "warning", sx: { mb: 2 }, children: t('Security.RECOVERY_LOGIN_WARNING') })), fromWeakLogin && (_jsx(Alert, { severity: "warning", sx: { mb: 2 }, children: t('Security.WEAK_LOGIN_WARNING') })), messageKey && (_jsx(Alert, { severity: "success", sx: { mb: 2 }, children: t(messageKey) })), errorKey && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: t(errorKey) })), _jsx(Typography, { variant: "h6", gutterBottom: true, children: t('Security.LOGIN_PASSWORD_LABEL') }), _jsx(PasswordChangeForm, { onSubmit: handlePasswordChange }), _jsx(Divider, { sx: { my: 3 } }), _jsx(Typography, { variant: "h6", gutterBottom: true, children: t('Security.SOCIAL_SECTION_TITLE') }), _jsx(Typography, { variant: "body2", sx: { mb: 1 }, children: t('Security.SOCIAL_SECTION_DESCRIPTION') }), _jsx(SocialLoginButtons, { onProviderClick: handleSocialClick }), _jsx(Divider, { sx: { my: 3 } }), _jsx(PasskeysComponent, {}), _jsx(Divider, { sx: { my: 3 } }), _jsx(MFAComponent, {})] }));
40
- };
41
- export { SecurityComponent };
40
+ }
41
+ ;
@@ -8,7 +8,7 @@ import { SOCIAL_PROVIDERS } from '../auth/authConfig';
8
8
  * Renders buttons for social login providers.
9
9
  * The caller passes a handler that receives the provider key.
10
10
  */
11
- const SocialLoginButtons = ({ onProviderClick }) => {
11
+ export function SocialLoginButtons({ onProviderClick }) {
12
12
  const { t } = useTranslation();
13
13
  const handleClick = (provider) => {
14
14
  if (onProviderClick) {
@@ -33,5 +33,5 @@ const SocialLoginButtons = ({ onProviderClick }) => {
33
33
  gridTemplateRows: '1fr 1fr',
34
34
  gap: '1px',
35
35
  }, children: [_jsx(Box, { sx: { bgcolor: 'primary.main', opacity: 0.9 } }), _jsx(Box, { sx: { bgcolor: 'primary.main', opacity: 0.7 } }), _jsx(Box, { sx: { bgcolor: 'primary.main', opacity: 0.7 } }), _jsx(Box, { sx: { bgcolor: 'primary.main', opacity: 0.9 } })] }), children: t('Auth.LOGIN_SOCIAL_MICROSOFT') })] }));
36
- };
37
- export default SocialLoginButtons;
36
+ }
37
+ ;
@@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react';
4
4
  import { Box, Typography, Table, TableHead, TableBody, TableRow, TableCell, TableContainer, Paper, Button, CircularProgress, Alert, Stack, Dialog, DialogTitle, DialogContent, DialogActions, TextField, } from '@mui/material';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { fetchRecoveryRequests, approveRecoveryRequest, rejectRecoveryRequest } from '../auth/authApi';
7
- const SupportRecoveryRequestsTab = () => {
7
+ export function SupportRecoveryRequestsTab() {
8
8
  const { t } = useTranslation();
9
9
  const [requests, setRequests] = useState([]);
10
10
  const [loading, setLoading] = useState(true);
@@ -83,5 +83,5 @@ const SupportRecoveryRequestsTab = () => {
83
83
  whiteSpace: 'pre-wrap',
84
84
  fontSize: '0.875rem',
85
85
  }, children: selectedRequest.message || t('Support.RECOVERY_NO_MESSAGE', 'No message provided.') })] })), _jsx(TextField, { label: t('Support.RECOVERY_NOTE_LABEL', 'Reason for your decision'), helperText: t('Support.RECOVERY_NOTE_HELP', 'Explain briefly why you approve or reject this request.'), multiline: true, minRows: 3, fullWidth: true, value: dialogNote, onChange: (e) => setDialogNote(e.target.value) })] }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: closeDialog, children: t('Support.CANCEL', 'Cancel') }), _jsx(Button, { onClick: handleReject, color: "error", disabled: !dialogNote.trim(), children: t('Support.RECOVERY_REJECT_SUBMIT', 'Reject request') }), _jsx(Button, { onClick: handleApprove, variant: "contained", disabled: !dialogNote.trim(), children: t('Support.RECOVERY_APPROVE_SUBMIT', 'Approve and send link') })] })] })] }));
86
- };
87
- export default SupportRecoveryRequestsTab;
86
+ }
87
+ ;
@@ -11,8 +11,8 @@ import { AuthContext } from '../auth/AuthContext';
11
11
  import { loginWithRecoveryPassword, loginWithPassword } from '../auth/authApi';
12
12
  import { loginWithPasskey, startSocialLogin } from '../utils/authService';
13
13
  // Components
14
- import LoginForm from '../components/LoginForm';
15
- import MfaLoginComponent from '../components/MfaLoginComponent';
14
+ import { LoginForm } from '../components/LoginForm';
15
+ import { MfaLoginComponent } from '../components/MfaLoginComponent';
16
16
  export function LoginPage() {
17
17
  const navigate = useNavigate();
18
18
  const location = useLocation();
@@ -112,4 +112,3 @@ export function LoginPage() {
112
112
  // --- Render ---
113
113
  return (_jsxs(NarrowPage, { title: t('Auth.PAGE_LOGIN_TITLE'), subtitle: t('Auth.PAGE_LOGIN_SUBTITLE'), children: [_jsx(Helmet, { children: _jsxs("title", { children: [t('App.NAME'), " \u2013 ", t('Auth.PAGE_LOGIN_TITLE')] }) }), errorKey && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: t(errorKey) })), recoveryToken && !errorKey && (_jsx(Alert, { severity: "info", sx: { mb: 2 }, children: t('Auth.RECOVERY_LOGIN_WARNING', 'Recovery link validated. Please enter your password.') })), step === 'credentials' && (_jsx(LoginForm, { onSubmit: handleSubmitCredentials, onForgotPassword: () => navigate('/reset-request-password'), onSocialLogin: (provider) => startSocialLogin(provider), onPasskeyLogin: handlePasskeyLoginInitial, onSignUp: () => navigate('/signup'), disabled: submitting, initialIdentifier: recoveryEmail })), step === 'mfa' && mfaState && (_jsx(Box, { children: _jsx(MfaLoginComponent, { availableTypes: mfaState.availableTypes, identifier: mfaState.identifier, onSuccess: handleMfaSuccess, onCancel: handleMfaCancel }) }))] }));
114
114
  }
115
- export default LoginPage;
@@ -5,7 +5,7 @@ import { Helmet } from 'react-helmet';
5
5
  import { Typography } from '@mui/material';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { NarrowPage } from '../layout/PageLayout';
8
- import PasswordChangeForm from '../components/PasswordChangeForm';
8
+ import { PasswordChangeForm } from '../components/PasswordChangeForm';
9
9
  import { changePassword } from '../auth/authApi';
10
10
  export function PasswordChangePage() {
11
11
  const { t } = useTranslation();
@@ -29,4 +29,3 @@ export function PasswordChangePage() {
29
29
  };
30
30
  return (_jsxs(NarrowPage, { title: t('Auth.CHANGE_PASSWORD_BUTTON'), subtitle: t('Auth.PAGE_CHANGE_PASSWORD_SUBTITLE'), children: [_jsx(Helmet, { children: _jsxs("title", { children: [t('App.NAME'), " \u2013 ", t('Auth.CHANGE_PASSWORD_BUTTON')] }) }), successKey && (_jsx(Typography, { color: "primary", gutterBottom: true, children: t(successKey) })), errorKey && (_jsx(Typography, { color: "error", gutterBottom: true, children: t(errorKey) })), _jsx(PasswordChangeForm, { onSubmit: handleSubmit, submitting: submitting })] }));
31
31
  }
32
- export default PasswordChangePage;
@@ -6,7 +6,7 @@ import { Helmet } from 'react-helmet';
6
6
  import { Typography } from '@mui/material';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { NarrowPage } from '../layout/PageLayout';
9
- import PasswordSetForm from '../components/PasswordSetForm';
9
+ import { PasswordSetForm } from '../components/PasswordSetForm';
10
10
  import { verifyResetToken, setNewPassword } from '../auth/authApi';
11
11
  export function PasswordInvitePage() {
12
12
  const { uid, token } = useParams();
@@ -72,4 +72,3 @@ export function PasswordInvitePage() {
72
72
  }
73
73
  return (_jsxs(NarrowPage, { title: t(pageTitleKey), subtitle: t(pageSubtitleKey), children: [_jsx(Helmet, { children: _jsxs("title", { children: [t('App.NAME'), " \u2013 ", t(pageTitleKey)] }) }), errorKey && (_jsx(Typography, { color: "error", gutterBottom: true, children: t(errorKey) })), successKey && (_jsx(Typography, { color: "primary", gutterBottom: true, children: t(successKey) })), !successKey && !errorKey && (_jsx(PasswordSetForm, { onSubmit: handleSubmit, submitting: submitting }))] }));
74
74
  }
75
- export default PasswordInvitePage;
@@ -6,7 +6,7 @@ import { Typography } from '@mui/material';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { NarrowPage } from '../layout/PageLayout';
8
8
  import { requestPasswordReset } from '../auth/authApi';
9
- import PasswordResetRequestForm from '../components/PasswordResetRequestForm';
9
+ import { PasswordResetRequestForm } from '../components/PasswordResetRequestForm';
10
10
  export function PasswordResetRequestPage() {
11
11
  const { t } = useTranslation();
12
12
  const [submitting, setSubmitting] = useState(false);
@@ -34,4 +34,3 @@ export function PasswordResetRequestPage() {
34
34
  };
35
35
  return (_jsxs(NarrowPage, { title: t('Auth.PAGE_RESET_PASSWORD_TITLE'), subtitle: t('Auth.PAGE_RESET_REQUEST_SUBTITLE'), children: [_jsx(Helmet, { children: _jsxs("title", { children: [t('App.NAME'), " \u2013 ", t('Auth.PAGE_RESET_PASSWORD_TITLE')] }) }), successKey && (_jsx(Typography, { color: "primary", gutterBottom: true, children: t(successKey) })), errorKey && (_jsx(Typography, { color: "error", gutterBottom: true, children: t(errorKey) })), _jsx(PasswordResetRequestForm, { onSubmit: handleSubmit, submitting: submitting })] }));
36
36
  }
37
- export default PasswordResetRequestPage;
@@ -54,4 +54,3 @@ export function SignUpPage() {
54
54
  ? t('Auth.SIGNUP_SUBMITTING')
55
55
  : t('Auth.SIGNUP_SUBMIT') })] }), _jsx(Box, { sx: { mt: 3 }, children: _jsxs(Typography, { variant: "body2", children: [t('Auth.SIGNUP_ALREADY_HAVE_ACCOUNT'), ' ', _jsx(Button, { onClick: handleGoToLogin, variant: "text", size: "small", children: t('Auth.SIGNUP_GO_TO_LOGIN') })] }) })] }));
56
56
  }
57
- export default SignUpPage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micha.bigler/ui-core-micha",
3
- "version": "1.4.29",
3
+ "version": "1.4.31",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "private": false,
@@ -219,4 +219,3 @@ export function AccessCodeManager() {
219
219
  );
220
220
  }
221
221
 
222
- export default AccessCodeManager;
@@ -7,9 +7,9 @@ import {
7
7
  Divider,
8
8
  } from '@mui/material';
9
9
  import { useTranslation } from 'react-i18next';
10
- import SocialLoginButtons from './SocialLoginButtons';
10
+ import { SocialLoginButtons } from './SocialLoginButtons';
11
11
 
12
- const LoginForm = ({
12
+ export function LoginForm({
13
13
  onSubmit,
14
14
  onForgotPassword,
15
15
  onSocialLogin,
@@ -18,7 +18,7 @@ const LoginForm = ({
18
18
  error, // bereits übersetzter Text oder t(errorKey) aus dem Parent
19
19
  disabled = false,
20
20
  initialIdentifier = '',
21
- }) => {
21
+ }) {
22
22
  const { t } = useTranslation();
23
23
 
24
24
  const [identifier, setIdentifier] = useState(initialIdentifier);
@@ -142,5 +142,3 @@ const LoginForm = ({
142
142
  </Box>
143
143
  );
144
144
  };
145
-
146
- export default LoginForm;
@@ -20,7 +20,7 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
20
20
  import { useTranslation } from 'react-i18next';
21
21
  import { fetchAuthenticators, requestTotpKey, activateTotp, deactivateTotp, fetchRecoveryCodes, generateRecoveryCodes } from '../auth/authApi';
22
22
 
23
- const MFAComponent = () => {
23
+ export function MFAComponent() {
24
24
  const { t } = useTranslation();
25
25
 
26
26
  const [authenticators, setAuthenticators] = useState([]);
@@ -338,4 +338,4 @@ const MFAComponent = () => {
338
338
  );
339
339
  };
340
340
 
341
- export default MFAComponent;
341
+
@@ -17,7 +17,7 @@ import { useTranslation } from 'react-i18next';
17
17
  import { authenticateWithMFA, fetchCurrentUser, requestMfaSupportHelp } from '../auth/authApi';
18
18
  import { loginWithPasskey } from '../utils/authService';
19
19
 
20
- const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel }) => {
20
+ export function MfaLoginComponent({ availableTypes, identifier, onSuccess, onCancel }) {
21
21
  const { t } = useTranslation();
22
22
  const [code, setCode] = useState('');
23
23
  const [submitting, setSubmitting] = useState(false);
@@ -237,4 +237,3 @@ const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel })
237
237
  };
238
238
 
239
239
 
240
- export default MfaLoginComponent;
@@ -22,7 +22,7 @@ import { fetchPasskeys, deletePasskey } from '../auth/authApi';
22
22
  import { registerPasskey } from '../utils/authService';
23
23
  import { FEATURES } from '../auth/authConfig';
24
24
 
25
- const PasskeysComponent = () => {
25
+ export function PasskeysComponent() {
26
26
  const { t } = useTranslation();
27
27
 
28
28
  const [passkeys, setPasskeys] = useState([]);
@@ -246,4 +246,3 @@ const PasskeysComponent = () => {
246
246
  );
247
247
  };
248
248
 
249
- export default PasskeysComponent;
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
  * A simplified form to handle password changes.
7
7
  * Does not require password confirmation.
8
8
  */
9
- const PasswordChangeForm = ({ onSubmit, submitting = false }) => {
9
+ export function PasswordChangeForm({ onSubmit, submitting = false }) {
10
10
  const { t } = useTranslation();
11
11
  const [currentPassword, setCurrentPassword] = useState('');
12
12
  const [newPassword, setNewPassword] = useState('');
@@ -60,4 +60,3 @@ const PasswordChangeForm = ({ onSubmit, submitting = false }) => {
60
60
  );
61
61
  };
62
62
 
63
- export default PasswordChangeForm;
@@ -3,7 +3,7 @@ import React, { useState } from 'react';
3
3
  import { Box, TextField, Button } from '@mui/material';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
- const PasswordResetRequestForm = ({ onSubmit, submitting = false }) => {
6
+ export function PasswordResetRequestForm({ onSubmit, submitting = false }) {
7
7
  const { t } = useTranslation();
8
8
  const [email, setEmail] = useState('');
9
9
 
@@ -41,4 +41,3 @@ const PasswordResetRequestForm = ({ onSubmit, submitting = false }) => {
41
41
  );
42
42
  };
43
43
 
44
- export default PasswordResetRequestForm;
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
7
7
  * Simple form to set a new password (once, with confirmation).
8
8
  * Caller passes onSubmit(newPassword) and handles redirect / API call.
9
9
  */
10
- const PasswordSetForm = ({ onSubmit, submitting = false }) => {
10
+ export function PasswordSetForm({ onSubmit, submitting = false }) {
11
11
  const { t } = useTranslation();
12
12
 
13
13
  const [password1, setPassword1] = useState('');
@@ -78,4 +78,3 @@ const PasswordSetForm = ({ onSubmit, submitting = false }) => {
78
78
  );
79
79
  };
80
80
 
81
- export default PasswordSetForm;
@@ -198,5 +198,3 @@ export function ProfileComponent({
198
198
  </Box>
199
199
  );
200
200
  }
201
-
202
- export default ProfileComponent;
@@ -7,17 +7,17 @@ import {
7
7
  Alert,
8
8
  } from '@mui/material';
9
9
  import { useTranslation } from 'react-i18next';
10
- import PasswordChangeForm from './PasswordChangeForm';
11
- import SocialLoginButtons from './SocialLoginButtons';
12
- import PasskeysComponent from './PasskeysComponent';
13
- import MFAComponent from './MFAComponent';
10
+ import { PasswordChangeForm } from './PasswordChangeForm';
11
+ import { SocialLoginButtons } from './SocialLoginButtons';
12
+ import { PasskeysComponent } from './PasskeysComponent';
13
+ import { MFAComponent } from './MFAComponent';
14
14
  import { changePassword } from '../auth/authApi';
15
15
  import { startSocialLogin } from '../utils/authService';
16
16
 
17
- const SecurityComponent = ({
17
+ export function SecurityComponent({
18
18
  fromRecovery = false,
19
19
  fromWeakLogin = false, // optional: wenn du später weak-login-Redirect nutzt
20
- }) => {
20
+ }) {
21
21
  const { t } = useTranslation();
22
22
 
23
23
  const [messageKey, setMessageKey] = useState(null);
@@ -102,4 +102,3 @@ const SecurityComponent = ({
102
102
  );
103
103
  };
104
104
 
105
- export { SecurityComponent };
@@ -8,7 +8,7 @@ import { SOCIAL_PROVIDERS } from '../auth/authConfig';
8
8
  * Renders buttons for social login providers.
9
9
  * The caller passes a handler that receives the provider key.
10
10
  */
11
- const SocialLoginButtons = ({ onProviderClick }) => {
11
+ export function SocialLoginButtons({ onProviderClick }) {
12
12
  const { t } = useTranslation();
13
13
 
14
14
  const handleClick = (provider) => {
@@ -72,4 +72,3 @@ const SocialLoginButtons = ({ onProviderClick }) => {
72
72
  );
73
73
  };
74
74
 
75
- export default SocialLoginButtons;
@@ -23,7 +23,7 @@ import {
23
23
  import { useTranslation } from 'react-i18next';
24
24
  import { fetchRecoveryRequests, approveRecoveryRequest, rejectRecoveryRequest } from '../auth/authApi';
25
25
 
26
- const SupportRecoveryRequestsTab = () => {
26
+ export function SupportRecoveryRequestsTab() {
27
27
  const { t } = useTranslation();
28
28
 
29
29
  const [requests, setRequests] = useState([]);
@@ -281,4 +281,3 @@ const SupportRecoveryRequestsTab = () => {
281
281
  );
282
282
  };
283
283
 
284
- export default SupportRecoveryRequestsTab
@@ -13,8 +13,8 @@ import { loginWithRecoveryPassword, loginWithPassword } from '../auth/authApi';
13
13
  import { loginWithPasskey, startSocialLogin } from '../utils/authService';
14
14
 
15
15
  // Components
16
- import LoginForm from '../components/LoginForm';
17
- import MfaLoginComponent from '../components/MfaLoginComponent';
16
+ import { LoginForm } from '../components/LoginForm';
17
+ import { MfaLoginComponent } from '../components/MfaLoginComponent';
18
18
 
19
19
  export function LoginPage() {
20
20
  const navigate = useNavigate();
@@ -169,6 +169,4 @@ export function LoginPage() {
169
169
  )}
170
170
  </NarrowPage>
171
171
  );
172
- }
173
-
174
- export default LoginPage;
172
+ }
@@ -4,7 +4,7 @@ import { Helmet } from 'react-helmet';
4
4
  import { Typography } from '@mui/material';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { NarrowPage } from '../layout/PageLayout';
7
- import PasswordChangeForm from '../components/PasswordChangeForm';
7
+ import { PasswordChangeForm } from '../components/PasswordChangeForm';
8
8
  import { changePassword } from '../auth/authApi';
9
9
 
10
10
  export function PasswordChangePage() {
@@ -59,6 +59,3 @@ export function PasswordChangePage() {
59
59
  </NarrowPage>
60
60
  );
61
61
  }
62
-
63
-
64
- export default PasswordChangePage;
@@ -5,7 +5,7 @@ import { Helmet } from 'react-helmet';
5
5
  import { Typography } from '@mui/material';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { NarrowPage } from '../layout/PageLayout';
8
- import PasswordSetForm from '../components/PasswordSetForm';
8
+ import { PasswordSetForm } from '../components/PasswordSetForm';
9
9
  import { verifyResetToken, setNewPassword } from '../auth/authApi';
10
10
 
11
11
  export function PasswordInvitePage() {
@@ -114,5 +114,3 @@ export function PasswordInvitePage() {
114
114
  </NarrowPage>
115
115
  );
116
116
  }
117
-
118
- export default PasswordInvitePage;
@@ -5,7 +5,7 @@ import { Typography } from '@mui/material';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { NarrowPage } from '../layout/PageLayout';
7
7
  import { requestPasswordReset } from '../auth/authApi';
8
- import PasswordResetRequestForm from '../components/PasswordResetRequestForm';
8
+ import {PasswordResetRequestForm } from '../components/PasswordResetRequestForm';
9
9
 
10
10
  export function PasswordResetRequestPage() {
11
11
  const { t } = useTranslation();
@@ -65,5 +65,3 @@ export function PasswordResetRequestPage() {
65
65
  </NarrowPage>
66
66
  );
67
67
  }
68
-
69
- export default PasswordResetRequestPage;
@@ -137,5 +137,3 @@ export function SignUpPage() {
137
137
  </NarrowPage>
138
138
  );
139
139
  }
140
-
141
- export default SignUpPage;