@memori.ai/memori-react 8.4.1 → 8.4.2
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/CHANGELOG.md +8 -0
- package/dist/components/LoginDrawer/LoginDrawer.d.ts +1 -2
- package/dist/components/LoginDrawer/LoginDrawer.js +2 -105
- package/dist/components/LoginDrawer/LoginDrawer.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/layouts/chat.css +7 -6
- package/esm/components/LoginDrawer/LoginDrawer.d.ts +1 -2
- package/esm/components/LoginDrawer/LoginDrawer.js +3 -106
- package/esm/components/LoginDrawer/LoginDrawer.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/layouts/chat.css +7 -6
- package/package.json +1 -1
- package/src/components/LoginDrawer/LoginDrawer.tsx +46 -221
- package/src/components/MemoriWidget/MemoriWidget.tsx +0 -1
- package/src/components/layouts/chat.css +7 -6
|
@@ -20,7 +20,6 @@ export interface Props {
|
|
|
20
20
|
onLogout: () => void;
|
|
21
21
|
tenant: Tenant;
|
|
22
22
|
apiClient: ReturnType<typeof memoriApiClient>;
|
|
23
|
-
baseURL?: string;
|
|
24
23
|
__TEST__signup?: boolean;
|
|
25
24
|
__TEST__needMissingData?: boolean;
|
|
26
25
|
__TEST__waitingForOtp?: boolean;
|
|
@@ -36,7 +35,6 @@ const LoginDrawer = ({
|
|
|
36
35
|
loginToken,
|
|
37
36
|
tenant,
|
|
38
37
|
apiClient,
|
|
39
|
-
baseURL,
|
|
40
38
|
__TEST__signup = false,
|
|
41
39
|
__TEST__needMissingData = false,
|
|
42
40
|
__TEST__waitingForOtp = false,
|
|
@@ -52,13 +50,6 @@ const LoginDrawer = ({
|
|
|
52
50
|
const [loading, setLoading] = useState(false);
|
|
53
51
|
const [error, setError] = useState<string | null>(null);
|
|
54
52
|
|
|
55
|
-
// OTP-related state
|
|
56
|
-
const [otpCode, setOtpCode] = useState<string>('');
|
|
57
|
-
const [otpUserName, setOtpUserName] = useState<string>('');
|
|
58
|
-
const [otpError, setOtpError] = useState<string | null>(null);
|
|
59
|
-
const [showOtpForm, setShowOtpForm] = useState(false);
|
|
60
|
-
const [otpTimer, setOtpTimer] = useState<number | null>(null);
|
|
61
|
-
|
|
62
53
|
const [showSignup, setShowSignup] = useState(__TEST__signup);
|
|
63
54
|
const [userMustChangePwd, setUserMustChangePwd] = useState<User | undefined>(
|
|
64
55
|
__TEST__changePwd
|
|
@@ -85,96 +76,6 @@ const LoginDrawer = ({
|
|
|
85
76
|
: ({} as any)
|
|
86
77
|
);
|
|
87
78
|
|
|
88
|
-
// OTP timer effect
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
let interval: NodeJS.Timeout;
|
|
91
|
-
if (otpTimer && otpTimer > 0) {
|
|
92
|
-
interval = setInterval(() => {
|
|
93
|
-
setOtpTimer(prev => (prev && prev > 0 ? prev - 1 : 0));
|
|
94
|
-
}, 1000);
|
|
95
|
-
}
|
|
96
|
-
return () => {
|
|
97
|
-
if (interval) clearInterval(interval);
|
|
98
|
-
};
|
|
99
|
-
}, [otpTimer]);
|
|
100
|
-
|
|
101
|
-
// OTP validation function
|
|
102
|
-
const validateOtp = async (otp: string) => {
|
|
103
|
-
if (!otp || otp.length !== 4) {
|
|
104
|
-
setOtpError(t('login.otpInvalidFormat'));
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!otpUserName || otpUserName.trim().length === 0) {
|
|
109
|
-
setOtpError(t('login.userNameRequired'));
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
setLoading(true);
|
|
114
|
-
setOtpError(null);
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const response = await fetch(`${baseURL}/api/validate-otp`, {
|
|
118
|
-
method: 'POST',
|
|
119
|
-
headers: {
|
|
120
|
-
'Content-Type': 'application/json',
|
|
121
|
-
},
|
|
122
|
-
body: JSON.stringify({
|
|
123
|
-
otp: otp,
|
|
124
|
-
userName: otpUserName.trim(),
|
|
125
|
-
}),
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const data = await response.json();
|
|
129
|
-
|
|
130
|
-
if (response.status == 200 && data.user && data.loginToken) {
|
|
131
|
-
toast.success(t('login.otpSuccess'));
|
|
132
|
-
setShowOtpForm(false);
|
|
133
|
-
setOtpCode('');
|
|
134
|
-
setOtpUserName('');
|
|
135
|
-
|
|
136
|
-
if (!data.user?.tnCAndPPAccepted || !data.user?.birthDate) {
|
|
137
|
-
setNeedsMissingData({
|
|
138
|
-
token: data.loginToken,
|
|
139
|
-
birthDate: !data.user.birthDate,
|
|
140
|
-
tnCAndPPAccepted: !data.user.tnCAndPPAccepted,
|
|
141
|
-
});
|
|
142
|
-
} else {
|
|
143
|
-
onLogin(data.user as User, data.loginToken);
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
setOtpError(data.resultMessage || t('login.otpInvalid'));
|
|
147
|
-
}
|
|
148
|
-
} catch (err) {
|
|
149
|
-
console.error('[OTP VALIDATION]', err);
|
|
150
|
-
setOtpError(t('login.otpError'));
|
|
151
|
-
} finally {
|
|
152
|
-
setLoading(false);
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
// Handle OTP input change
|
|
157
|
-
const handleOtpChange = (value: string) => {
|
|
158
|
-
const numericValue = value.replace(/\D/g, '').slice(0, 4);
|
|
159
|
-
setOtpCode(numericValue);
|
|
160
|
-
setOtpError(null);
|
|
161
|
-
|
|
162
|
-
if (numericValue.length === 4 && otpUserName.trim().length > 0) {
|
|
163
|
-
validateOtp(numericValue);
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
// Handle username input change
|
|
168
|
-
const handleUserNameChange = (value: string) => {
|
|
169
|
-
setOtpUserName(value);
|
|
170
|
-
setOtpError(null);
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// Start OTP timer
|
|
174
|
-
const startOtpTimer = () => {
|
|
175
|
-
setOtpTimer(60);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
79
|
const login = (e: React.FormEvent<HTMLFormElement>) => {
|
|
179
80
|
e.preventDefault();
|
|
180
81
|
const form = e.currentTarget as HTMLFormElement;
|
|
@@ -578,135 +479,59 @@ const LoginDrawer = ({
|
|
|
578
479
|
<SignupForm
|
|
579
480
|
tenant={tenant}
|
|
580
481
|
apiClient={apiClient}
|
|
581
|
-
onLogin={
|
|
582
|
-
// Force all signup users to go through missing data flow
|
|
583
|
-
// This ensures consistent user experience and data collection
|
|
584
|
-
setNeedsMissingData({
|
|
585
|
-
token: token,
|
|
586
|
-
birthDate: true, // Always require birth date for new users
|
|
587
|
-
tnCAndPPAccepted: true, // Always require terms acceptance for new users
|
|
588
|
-
});
|
|
589
|
-
}}
|
|
482
|
+
onLogin={onLogin}
|
|
590
483
|
goToLogin={() => setShowSignup(false)}
|
|
591
484
|
__TEST__waitingForOtp={__TEST__waitingForOtp}
|
|
592
485
|
/>
|
|
593
|
-
) :
|
|
486
|
+
) : (
|
|
594
487
|
<>
|
|
595
|
-
<
|
|
596
|
-
<
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
488
|
+
<form className="memori--login-drawer--form" onSubmit={login}>
|
|
489
|
+
<label htmlFor="#userNameOrEmail">
|
|
490
|
+
{t('login.userNameOrEmail')}
|
|
491
|
+
<input
|
|
492
|
+
id="userNameOrEmail"
|
|
493
|
+
name="userNameOrEmail"
|
|
494
|
+
required
|
|
495
|
+
autoComplete="email"
|
|
496
|
+
placeholder="Username/email"
|
|
497
|
+
/>
|
|
498
|
+
</label>
|
|
600
499
|
|
|
601
|
-
<
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
autoComplete="username"
|
|
613
|
-
disabled={loading}
|
|
614
|
-
/>
|
|
615
|
-
</label>
|
|
616
|
-
|
|
617
|
-
<label htmlFor="otp-code">
|
|
618
|
-
<span>{t('login.otpCode')}</span>
|
|
619
|
-
<input
|
|
620
|
-
id="otp-code"
|
|
621
|
-
type="text"
|
|
622
|
-
className={cx('memori--login-drawer--otp-input', {
|
|
623
|
-
success: otpCode.length === 4 && !otpError,
|
|
624
|
-
})}
|
|
625
|
-
value={otpCode}
|
|
626
|
-
onChange={e => handleOtpChange(e.target.value)}
|
|
627
|
-
placeholder="0000"
|
|
628
|
-
maxLength={4}
|
|
629
|
-
autoComplete="one-time-code"
|
|
630
|
-
required
|
|
631
|
-
disabled={loading}
|
|
632
|
-
/>
|
|
633
|
-
</label>
|
|
634
|
-
</div>
|
|
635
|
-
|
|
636
|
-
{otpTimer && otpTimer > 0 && (
|
|
637
|
-
<p className="memori--login-drawer--otp-timer">
|
|
638
|
-
{t('login.otpTimer', { seconds: otpTimer })}
|
|
639
|
-
</p>
|
|
640
|
-
)}
|
|
500
|
+
<label htmlFor="#password">
|
|
501
|
+
Password
|
|
502
|
+
<input
|
|
503
|
+
id="password"
|
|
504
|
+
name="password"
|
|
505
|
+
type="password"
|
|
506
|
+
required
|
|
507
|
+
autoComplete="password"
|
|
508
|
+
placeholder="Password"
|
|
509
|
+
/>
|
|
510
|
+
</label>
|
|
641
511
|
|
|
642
|
-
<
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
onClick={() => {
|
|
646
|
-
setShowOtpForm(false);
|
|
647
|
-
setOtpCode('');
|
|
648
|
-
setOtpUserName('');
|
|
649
|
-
setOtpError(null);
|
|
650
|
-
}}
|
|
651
|
-
>
|
|
652
|
-
{t('login.backToLogin')}
|
|
653
|
-
</Button>
|
|
654
|
-
|
|
655
|
-
<Button
|
|
656
|
-
primary
|
|
657
|
-
onClick={() => {
|
|
658
|
-
window.open(
|
|
659
|
-
'http://localhost:3000/it/account?t=account',
|
|
660
|
-
'_blank'
|
|
661
|
-
);
|
|
662
|
-
startOtpTimer();
|
|
663
|
-
}}
|
|
664
|
-
>
|
|
665
|
-
{t('login.generateOtp')}
|
|
666
|
-
</Button>
|
|
667
|
-
</div>
|
|
668
|
-
|
|
669
|
-
{otpError && (
|
|
670
|
-
<p role="alert" className="memori--login-drawer--otp-error">
|
|
671
|
-
{otpError}
|
|
672
|
-
</p>
|
|
673
|
-
)}
|
|
674
|
-
</div>
|
|
675
|
-
</>
|
|
676
|
-
) : (
|
|
677
|
-
<>
|
|
678
|
-
<div className="memori--login-drawer--welcome">
|
|
679
|
-
<h3>{t('login.welcomeTitle')}</h3>
|
|
680
|
-
<p className="memori--login-drawer--welcome-description">
|
|
681
|
-
{t('login.welcomeDescription')}
|
|
682
|
-
</p>
|
|
512
|
+
<Button htmlType="submit" primary loading={loading}>
|
|
513
|
+
{t('login.login')}
|
|
514
|
+
</Button>
|
|
683
515
|
|
|
684
|
-
|
|
685
|
-
<
|
|
686
|
-
|
|
687
|
-
<
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
<
|
|
695
|
-
|
|
516
|
+
{!tenant?.disableRegistration ? (
|
|
517
|
+
<p className="memori--login-drawer--signup">
|
|
518
|
+
{t('login.newUserSignUp')}{' '}
|
|
519
|
+
<Button outlined onClick={() => setShowSignup(true)}>
|
|
520
|
+
{t('login.signUp')}
|
|
521
|
+
</Button>
|
|
522
|
+
</p>
|
|
523
|
+
) : tenant.adminEmail ? (
|
|
524
|
+
<div className="memori--login-drawer--signup">
|
|
525
|
+
<p>{t('login.registrationDisabled')}</p>
|
|
526
|
+
<p>
|
|
527
|
+
{t('login.contactAdmin')}:{' '}
|
|
528
|
+
<a href={`mailto:${tenant.adminEmail}`}>
|
|
529
|
+
{tenant.adminEmail}
|
|
530
|
+
</a>
|
|
531
|
+
</p>
|
|
696
532
|
</div>
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
<Button
|
|
700
|
-
primary
|
|
701
|
-
onClick={() => {
|
|
702
|
-
setShowOtpForm(true);
|
|
703
|
-
startOtpTimer();
|
|
704
|
-
}}
|
|
705
|
-
className="memori--login-drawer--start-otp-button"
|
|
706
|
-
>
|
|
707
|
-
{t('login.startOtpLogin')}
|
|
708
|
-
</Button>
|
|
709
|
-
</div>
|
|
533
|
+
) : null}
|
|
534
|
+
</form>
|
|
710
535
|
|
|
711
536
|
{error && (
|
|
712
537
|
<p role="alert" className="memori--login-drawer--error">
|
|
@@ -719,4 +544,4 @@ const LoginDrawer = ({
|
|
|
719
544
|
);
|
|
720
545
|
};
|
|
721
546
|
|
|
722
|
-
export default LoginDrawer;
|
|
547
|
+
export default LoginDrawer;
|
|
@@ -12,9 +12,6 @@
|
|
|
12
12
|
flex-direction: column;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
.memori-chat-layout--main, .memori-chat-layout--controls{
|
|
16
|
-
min-height: calc(100% - 25px);
|
|
17
|
-
}
|
|
18
15
|
|
|
19
16
|
.memori-chat-layout--header {
|
|
20
17
|
text-align: right;
|
|
@@ -62,6 +59,8 @@
|
|
|
62
59
|
z-index: 5;
|
|
63
60
|
overflow: hidden;
|
|
64
61
|
min-width: 0;
|
|
62
|
+
height: calc(100% - 50px);
|
|
63
|
+
max-height: calc(100% - 50px);
|
|
65
64
|
flex: 1;
|
|
66
65
|
transition: all 0.05s ease-in-out;
|
|
67
66
|
}
|
|
@@ -134,6 +133,10 @@
|
|
|
134
133
|
bottom: auto;
|
|
135
134
|
}
|
|
136
135
|
|
|
136
|
+
.memori-chat-layout--controls .memori-chat--wrapper {
|
|
137
|
+
height: calc(100% - 1rem);
|
|
138
|
+
}
|
|
139
|
+
|
|
137
140
|
@media (max-width: 870px) {
|
|
138
141
|
.memori-chat-layout .memori--powered-by {
|
|
139
142
|
top: 3.5rem;
|
|
@@ -149,9 +152,7 @@
|
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
|
|
152
|
-
|
|
153
|
-
height: calc(75vh - 1rem);
|
|
154
|
-
}
|
|
155
|
+
|
|
155
156
|
|
|
156
157
|
.memori-chat-layout .memori-chat--content {
|
|
157
158
|
padding: 0;
|