@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.
@@ -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={(_user: User, token: string) => {
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
- ) : showOtpForm ? (
486
+ ) : (
594
487
  <>
595
- <div className="memori--login-drawer--otp-container">
596
- <h3>{t('login.otpTitle')}</h3>
597
- <p className="memori--login-drawer--otp-description">
598
- {t('login.otpDescription')}
599
- </p>
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
- <div className={cx('memori--login-drawer--otp-form', { loading })}>
602
- <label htmlFor="otp-username">
603
- <span>{t('login.userName')}</span>
604
- <input
605
- id="otp-username"
606
- type="text"
607
- className="memori--login-drawer--otp-username-input"
608
- value={otpUserName}
609
- onChange={e => handleUserNameChange(e.target.value)}
610
- placeholder={t('login.userName') || 'Username'}
611
- required
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
- <div className="memori--login-drawer--otp-actions">
643
- <Button
644
- outlined
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
- <div className="memori--login-drawer--otp-info">
685
- <div className="memori--login-drawer--otp-info-item">
686
- <span className="memori--login-drawer--otp-info-number">1</span>
687
- <span>{t('login.otpStep1')}</span>
688
- </div>
689
- <div className="memori--login-drawer--otp-info-item">
690
- <span className="memori--login-drawer--otp-info-number">2</span>
691
- <span>{t('login.otpStep2')}</span>
692
- </div>
693
- <div className="memori--login-drawer--otp-info-item">
694
- <span className="memori--login-drawer--otp-info-number">3</span>
695
- <span>{t('login.otpStep3')}</span>
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
- </div>
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;
@@ -3379,7 +3379,6 @@ const MemoriWidget = ({
3379
3379
  tenant={tenant}
3380
3380
  apiClient={client}
3381
3381
  open={!!showLoginDrawer}
3382
- baseURL={baseUrl}
3383
3382
  user={user}
3384
3383
  loginToken={loginToken}
3385
3384
  onClose={() => setShowLoginDrawer(false)}
@@ -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
- .memori-chat-layout--controls .memori-chat--wrapper {
153
- height: calc(75vh - 1rem);
154
- }
155
+
155
156
 
156
157
  .memori-chat-layout .memori-chat--content {
157
158
  padding: 0;