Skip to content

Commit 8e11adf

Browse files
committed
frontend: make email verification a dismissable modal
1 parent c84f285 commit 8e11adf

21 files changed

+201
-127
lines changed

src/packages/frontend/app/page.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ export const Page: React.FC = () => {
117117
const is_anonymous = useTypedRedux("account", "is_anonymous");
118118
const when_account_created = useTypedRedux("account", "created");
119119
const groups = useTypedRedux("account", "groups");
120-
const show_verify_email: boolean = useShowVerifyEmail();
121120
const show_i18n = useShowI18NBanner();
122121

123122
const is_commercial = useTypedRedux("customize", "is_commercial");
@@ -375,7 +374,7 @@ export const Page: React.FC = () => {
375374
{cookie_warning && <CookieWarning />}
376375
{local_storage_warning && <LocalStorageWarning />}
377376
{show_i18n && <I18NBanner />}
378-
{show_verify_email && <VerifyEmail />}
377+
<VerifyEmail />
379378
{!fullscreen && (
380379
<nav className="smc-top-bar" style={topBarStyle}>
381380
<AppLogo size={pageStyle.height} />

src/packages/frontend/app/verify-email-banner.tsx

Lines changed: 109 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,55 @@
33
* License: MS-RSL – see LICENSE.md for details
44
*/
55

6-
import { Space } from "antd";
6+
import { Modal, Space } from "antd";
77
import { FormattedMessage, useIntl } from "react-intl";
88

99
import { emailVerificationMsg } from "@cocalc/frontend/account/settings/email-verification";
1010
import { Button } from "@cocalc/frontend/antd-bootstrap";
1111
import {
12-
CSS,
1312
redux,
1413
useActions,
1514
useAsyncEffect,
1615
useState,
1716
useTypedRedux,
1817
} from "@cocalc/frontend/app-framework";
19-
import { CloseX2, HelpIcon, Icon, Text } from "@cocalc/frontend/components";
18+
import { Icon, Paragraph, Text } from "@cocalc/frontend/components";
2019
import { labels } from "@cocalc/frontend/i18n";
2120
import * as LS from "@cocalc/frontend/misc/local-storage-typed";
2221
import { webapp_client } from "@cocalc/frontend/webapp-client";
2322
import { once } from "@cocalc/util/async-utils";
24-
import { COLORS } from "@cocalc/util/theme";
25-
26-
const VERIFY_EMAIL_STYLE: CSS = {
27-
width: "100%",
28-
padding: "5px",
29-
borderBottom: `1px solid ${COLORS.GRAY_D}`,
30-
background: COLORS.ANTD_BG_RED_L,
31-
} as const;
3223

3324
const DISMISSED_KEY_LS = "verify-email-dismissed";
3425

3526
export function VerifyEmail() {
27+
const [hide, setHide] = useState<boolean>(false);
28+
const show = useShowVerifyEmail();
29+
30+
function doDismiss(save = true) {
31+
if (save) {
32+
const now = webapp_client.server_time().getTime();
33+
LS.set(DISMISSED_KEY_LS, now);
34+
}
35+
setHide(true);
36+
}
37+
38+
if (show && !hide) {
39+
return <VerifyEmailModal doDismiss={doDismiss} />;
40+
} else {
41+
return null;
42+
}
43+
}
44+
45+
function VerifyEmailModal({
46+
doDismiss,
47+
}: {
48+
doDismiss: (save?: boolean) => void;
49+
}) {
3650
const intl = useIntl();
3751
const page_actions = useActions("page");
3852
const email_address = useTypedRedux("account", "email_address");
3953

4054
const [error, setError] = useState<string>("");
41-
const [show, setShow] = useState<boolean>(true);
4255
const [sending, setSending] = useState<boolean>(false);
4356
const [sent, setSent] = useState<boolean>(false);
4457

@@ -56,80 +69,107 @@ export function VerifyEmail() {
5669

5770
// TODO: at one point this should be a popup to just edit the email address
5871
function edit() {
72+
doDismiss(false);
5973
page_actions.set_active_tab("account");
6074
}
6175

62-
function dismiss() {
63-
const now = webapp_client.server_time().getTime();
64-
LS.set(DISMISSED_KEY_LS, now);
65-
setShow(false);
66-
}
67-
6876
function renderBanner() {
6977
if (error) {
7078
return <Text type="danger">{error}</Text>;
7179
}
7280
return (
73-
<Text strong>
74-
<Icon name="mail" />{" "}
75-
<FormattedMessage
76-
id="app.verify-email-banner.text"
77-
defaultMessage={`{sent, select,
78-
true {Sent! Please check your email inbox (and maybe spam) and click on the confirmation link.}
79-
other {Please check and verify your email address: <code>{email}</code>}}`}
80-
values={{
81-
sent,
82-
email: email_address,
83-
code: (c) => <Text code>{c}</Text>,
84-
}}
85-
/>{" "}
86-
{sent ? (
87-
<Button
88-
onClick={() => setShow(false)}
89-
bsStyle="success"
90-
bsSize={"xsmall"}
91-
>
92-
{intl.formatMessage(labels.close)}
93-
</Button>
94-
) : (
95-
<Space size={"small"}>
96-
<Button bsSize={"xsmall"} onClick={edit}>
97-
<Icon name="pencil" /> {intl.formatMessage(labels.edit)}
98-
</Button>
99-
<Button
100-
onClick={verify}
101-
bsStyle="success"
102-
disabled={sent || sending}
103-
bsSize={"xsmall"}
104-
>
105-
{intl.formatMessage(emailVerificationMsg, {
106-
disabled_button: sent,
107-
})}
108-
</Button>
109-
<HelpIcon
110-
title={intl.formatMessage({
111-
id: "app.verify-email-banner.help.title",
112-
defaultMessage: "Email Verification",
113-
})}
114-
>
81+
<>
82+
<Paragraph strong>
83+
<FormattedMessage
84+
id="app.verify-email-banner.text"
85+
defaultMessage={`{sent, select,
86+
true {Email Sent! Please check your email inbox (and maybe spam) and click on the confirmation link.}
87+
other {Please check and verify your email address:}}`}
88+
values={{
89+
sent,
90+
code: (c) => <Text code>{c}</Text>,
91+
}}
92+
/>
93+
</Paragraph>
94+
{!sent ? (
95+
<>
96+
<Paragraph code style={{ textAlign: "center" }}>
97+
{email_address}
98+
</Paragraph>
99+
<Paragraph type="secondary">
115100
<FormattedMessage
116101
id="app.verify-email-banner.help.text"
117-
defaultMessage="It's important to have a working email address. We use this for password resets, sending messages, billing notifications, and support. Please ensure your email is correct to stay informed."
102+
defaultMessage="It's important to have a working email address. We use it for password resets, sending messages, billing notifications, and support. Please ensure your email is correct to stay informed."
118103
/>
119-
</HelpIcon>
120-
</Space>
121-
)}
122-
</Text>
104+
</Paragraph>
105+
<Paragraph type="secondary">
106+
<FormattedMessage
107+
id="app.verify-email-banner.edit"
108+
defaultMessage="If the email address is wrong, please <E>edit</E> it in the account settings."
109+
values={{
110+
E: (text) => (
111+
<Button onClick={edit} bsSize="xsmall">
112+
<Icon name="pencil" /> {text}
113+
</Button>
114+
),
115+
}}
116+
/>
117+
</Paragraph>
118+
</>
119+
) : null}
120+
</>
123121
);
124122
}
125123

126-
if (!show) return;
124+
function renderFooter() {
125+
if (sent) {
126+
return (
127+
<Button onClick={() => doDismiss()} bsStyle="success">
128+
{intl.formatMessage(labels.close)}
129+
</Button>
130+
);
131+
}
132+
133+
return (
134+
<Space>
135+
<Button onClick={() => doDismiss()}>
136+
{intl.formatMessage(labels.close)}
137+
</Button>
138+
<Button
139+
onClick={verify}
140+
bsStyle="success"
141+
active={!sent && sending}
142+
disabled={sent || sending}
143+
>
144+
{intl.formatMessage(emailVerificationMsg, {
145+
disabled_button: sent,
146+
})}
147+
</Button>
148+
</Space>
149+
);
150+
}
151+
152+
function renderTitle() {
153+
return (
154+
<>
155+
<Icon name="mail" />{" "}
156+
{intl.formatMessage({
157+
id: "app.verify-email-banner.title",
158+
defaultMessage: "Verify Your Email Address",
159+
})}
160+
</>
161+
);
162+
}
127163

128164
return (
129-
<div style={VERIFY_EMAIL_STYLE}>
165+
<Modal
166+
title={renderTitle()}
167+
open={true}
168+
onCancel={() => doDismiss()}
169+
footer={renderFooter()}
170+
>
130171
{renderBanner()}
131-
<CloseX2 close={dismiss} />
132-
</div>
172+
</Modal>
133173
);
134174
}
135175

src/packages/frontend/i18n/trans/ar_EG.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"account.other-settings.filename_generator.description": "اختر كيفية توليد أسماء الملفات التلقائية. بشكل خاص، لجعلها فريدة أو لتضمين الوقت الحالي.",
7272
"account.other-settings.filename_generator.label": "مولد اسم الملف",
7373
"account.other-settings.global_banner": "<strong>عرض لافتة الإعلان</strong>: يظهر فقط إذا كان هناك رسالة",
74+
"account.other-settings.hide_navbar_balance": "<strong>إخفاء رصيد الحساب</strong> في شريط التنقل",
7475
"account.other-settings.katex": "<strong>KaTeX:</strong> محاولة عرض الصيغ باستخدام {katex} (أسرع بكثير، ولكن بدون خيارات قائمة السياق)",
7576
"account.other-settings.llm.default_llm": "نموذج اللغة الافتراضي AI",
7677
"account.other-settings.llm.disable_all": "<strong>تعطيل جميع تكاملات الذكاء الاصطناعي</strong>، مثل أزرار توليد أو شرح الأكواد في Jupyter، وذكر @chatgpt، إلخ.",
@@ -128,9 +129,10 @@
128129
"ai-generate-document.modal.title": "إنشاء مستند {docName} باستخدام الذكاء الاصطناعي",
129130
"ai-generator.select_llm": "اختر نموذج اللغة",
130131
"app.fullscreen-button.tooltip": "وضع الشاشة الكاملة، يركز على المستند أو الصفحة الحالية.",
131-
"app.verify-email-banner.help.text": "من المهم أن يكون لديك عنوان بريد إلكتروني صالح. نستخدمه لإعادة تعيين كلمة المرور، إرسال الرسائل، إشعارات الفواتير، والدعم. يرجى التأكد من صحة بريدك الإلكتروني للبقاء على اطلاع.",
132-
"app.verify-email-banner.help.title": "التحقق من البريد الإلكتروني",
133-
"app.verify-email-banner.text": "{sent, select, true {تم الإرسال! يرجى التحقق من صندوق البريد الإلكتروني الخاص بك (ربما البريد العشوائي) والنقر على رابط التأكيد.} other {يرجى التحقق من عنوان بريدك الإلكتروني وتأكيده: <code>{email}</code>}}",
132+
"app.verify-email-banner.edit": "إذا كانت عنوان البريد الإلكتروني خاطئة، يرجى <E>تعديله</E> في إعدادات الحساب.",
133+
"app.verify-email-banner.help.text": "من المهم أن يكون لديك عنوان بريد إلكتروني يعمل. نستخدمه لإعادة تعيين كلمة المرور، وإرسال الرسائل، وإشعارات الفوترة، والدعم. يرجى التأكد من صحة بريدك الإلكتروني للبقاء على اطلاع.",
134+
"app.verify-email-banner.text": "{sent, select, true {تم إرسال البريد الإلكتروني! يرجى التحقق من صندوق البريد الإلكتروني (وربما الرسائل غير المرغوب فيها) والنقر على رابط التأكيد.} other {يرجى التحقق من عنوان بريدك الإلكتروني وتأكيده:}}",
135+
"app.verify-email-banner.title": "تحقق من عنوان بريدك الإلكتروني",
134136
"chat.chat-indicator.tooltip": "إخفاء أو إظهار محادثة المستندات",
135137
"chat.input.placeholder": "اكتب رسالة جديدة ({have_llm, select, true {الدردشة مع الذكاء الاصطناعي أو } other {}}إخطار زميل بكتابة @)...",
136138
"chatroom.chat_input.preview_button.label": "عرض",

src/packages/frontend/i18n/trans/de_DE.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"account.other-settings.filename_generator.description": "Wählen Sie aus, wie automatisch generierte Dateinamen erstellt werden. Insbesondere, um sie einzigartig zu machen oder die aktuelle Uhrzeit einzubeziehen.",
7272
"account.other-settings.filename_generator.label": "Dateinamengenerator",
7373
"account.other-settings.global_banner": "<strong>Ankündigungsbanner anzeigen</strong>: wird nur angezeigt, wenn eine Nachricht vorhanden ist",
74+
"account.other-settings.hide_navbar_balance": "<strong>Kontostand verbergen</strong> in der Navigationsleiste",
7475
"account.other-settings.katex": "<strong>KaTeX:</strong> Versuch, Formeln mit {katex} zu rendern (viel schneller, aber ohne Kontextmenüoptionen)",
7576
"account.other-settings.llm.default_llm": "Standard-AI-Sprachmodell",
7677
"account.other-settings.llm.disable_all": "<strong>Alle KI-Integrationen deaktivieren</strong>, z.B. Code-Generierungs- oder Erklärungsbuttons in Jupyter, @chatgpt-Erwähnungen usw.",
@@ -128,9 +129,10 @@
128129
"ai-generate-document.modal.title": "Erzeuge ein {docName} Dokument mit KI",
129130
"ai-generator.select_llm": "Sprachmodell auswählen",
130131
"app.fullscreen-button.tooltip": "Vollbildmodus, fokussiert auf das aktuelle Dokument oder die aktuelle Seite",
131-
"app.verify-email-banner.help.text": "Es ist wichtig, eine funktionierende E-Mail-Adresse zu haben. Wir verwenden diese für Passwortzurücksetzungen, zum Versenden von Nachrichten, für Abrechnungsbenachrichtigungen und Support. Bitte stellen Sie sicher, dass Ihre E-Mail-Adresse korrekt ist, um informiert zu bleiben.",
132-
"app.verify-email-banner.help.title": "E-Mail-Verifizierung",
133-
"app.verify-email-banner.text": "{sent, select, true {Gesendet! Bitte überprüfen Sie Ihren E-Mail-Posteingang (vielleicht Spam) und klicken Sie auf den Bestätigungslink.} other {Bitte überprüfen und bestätigen Sie Ihre E-Mail-Adresse: <code>{email}</code>}}",
132+
"app.verify-email-banner.edit": "Wenn die E-Mail-Adresse falsch ist, bitte <E>bearbeiten</E> Sie sie in den Kontoeinstellungen.",
133+
"app.verify-email-banner.help.text": "Es ist wichtig, eine funktionierende E-Mail-Adresse zu haben. Wir verwenden sie für das Zurücksetzen von Passwörtern, das Senden von Nachrichten, Abrechnungsbenachrichtigungen und Unterstützung. Bitte stellen Sie sicher, dass Ihre E-Mail korrekt ist, um informiert zu bleiben.",
134+
"app.verify-email-banner.text": "{sent, select, true {E-Mail gesendet! Bitte überprüfen Sie Ihren E-Mail-Posteingang (und vielleicht Spam) und klicken Sie auf den Bestätigungslink.} other {Bitte überprüfen und verifizieren Sie Ihre E-Mail-Adresse:}}",
135+
"app.verify-email-banner.title": "Bestätigen Sie Ihre E-Mail-Adresse",
134136
"chat.chat-indicator.tooltip": "Dokument-Chat ausblenden oder anzeigen",
135137
"chat.input.placeholder": "Schreib eine neue Nachricht ({have_llm, select, true {sprich mit einer KI oder } other {}}kontaktiere eine/n Mitarbeiter/in durch Erwähnen mit einem @)...",
136138
"chatroom.chat_input.preview_button.label": "Vorschau",

src/packages/frontend/i18n/trans/es_ES.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"account.other-settings.filename_generator.description": "Seleccione cómo se generan los nombres de archivo automáticamente. En particular, para hacerlos únicos o incluir la hora actual.",
7272
"account.other-settings.filename_generator.label": "Generador de nombres de archivo",
7373
"account.other-settings.global_banner": "<strong>Mostrar banner de anuncio</strong>: solo aparece si hay un mensaje",
74+
"account.other-settings.hide_navbar_balance": "<strong>Ocultar saldo de cuenta</strong> en la barra de navegación",
7475
"account.other-settings.katex": "<strong>KaTeX:</strong> intento de renderizar fórmulas usando {katex} (mucho más rápido, pero sin opciones de menú contextual)",
7576
"account.other-settings.llm.default_llm": "Modelo de Lenguaje AI Predeterminado",
7677
"account.other-settings.llm.disable_all": "<strong>Desactivar todas las integraciones de IA</strong>, por ejemplo, botones de generación de código o explicación en Jupyter, menciones de @chatgpt, etc.",
@@ -128,9 +129,10 @@
128129
"ai-generate-document.modal.title": "Generar un documento {docName} usando IA",
129130
"ai-generator.select_llm": "Seleccionar modelo de idioma",
130131
"app.fullscreen-button.tooltip": "Modo de pantalla completa, centrado en el documento o página actual.",
131-
"app.verify-email-banner.help.text": "Es importante tener una dirección de correo electrónico funcional. Usamos esto para restablecer contraseñas, enviar mensajes, notificaciones de facturación y soporte. Por favor, asegúrate de que tu correo electrónico sea correcto para mantenerte informado.",
132-
"app.verify-email-banner.help.title": "Verificación de Email",
133-
"app.verify-email-banner.text": "{sent, select, true {¡Enviado! Por favor, revisa tu bandeja de entrada de correo electrónico (tal vez spam) y haz clic en el enlace de confirmación.} other {Por favor, revisa y verifica tu dirección de correo electrónico: <code>{email}</code>}}",
132+
"app.verify-email-banner.edit": "Si la dirección de correo electrónico es incorrecta, por favor <E>edítala</E> en la configuración de la cuenta.",
133+
"app.verify-email-banner.help.text": "Es importante tener una dirección de correo electrónico funcional. La usamos para restablecer contraseñas, enviar mensajes, notificaciones de facturación y soporte. Por favor, asegúrate de que tu correo electrónico sea correcto para mantenerte informado.",
134+
"app.verify-email-banner.text": "{sent, select, true {¡Correo electrónico enviado! Por favor, revisa tu bandeja de entrada de correo (y quizá el spam) y haz clic en el enlace de confirmación.} other {Por favor, revisa y verifica tu dirección de correo electrónico:}}",
135+
"app.verify-email-banner.title": "Verifica tu dirección de correo electrónico",
134136
"chat.chat-indicator.tooltip": "Ocultar o Mostrar Chat del Documento",
135137
"chat.input.placeholder": "Escribe un nuevo mensaje ({have_llm, select, true {chatea con AI o } other {}}notifica a un colaborador escribiendo @)...",
136138
"chatroom.chat_input.preview_button.label": "Vista previa",

src/packages/frontend/i18n/trans/fr_FR.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"account.other-settings.filename_generator.description": "Sélectionnez comment les noms de fichiers générés automatiquement sont créés. En particulier, pour les rendre uniques ou inclure l'heure actuelle.",
7272
"account.other-settings.filename_generator.label": "Générateur de nom de fichier",
7373
"account.other-settings.global_banner": "<strong>Afficher la bannière d'annonce</strong> : s'affiche uniquement s'il y a un message",
74+
"account.other-settings.hide_navbar_balance": "<strong>Cacher le solde du compte</strong> dans la barre de navigation",
7475
"account.other-settings.katex": "<strong>KaTeX :</strong> tentative de rendu des formules en utilisant {katex} (beaucoup plus rapide, mais sans options du menu contextuel)",
7576
"account.other-settings.llm.default_llm": "Modèle de Langage IA par Défaut",
7677
"account.other-settings.llm.disable_all": "<strong>Désactiver toutes les intégrations d'IA</strong>, par exemple, boutons de génération de code ou d'explication dans Jupyter, mentions @chatgpt, etc.",
@@ -128,9 +129,10 @@
128129
"ai-generate-document.modal.title": "Générer un document {docName} en utilisant l'IA",
129130
"ai-generator.select_llm": "Sélectionner le modèle de langue",
130131
"app.fullscreen-button.tooltip": "Mode plein écran, concentré sur le document ou la page actuelle.",
132+
"app.verify-email-banner.edit": "Si l'adresse e-mail est incorrecte, veuillez <E>la modifier</E> dans les paramètres du compte.",
131133
"app.verify-email-banner.help.text": "Il est important d'avoir une adresse e-mail fonctionnelle. Nous l'utilisons pour les réinitialisations de mot de passe, l'envoi de messages, les notifications de facturation et le support. Veuillez vous assurer que votre e-mail est correct pour rester informé.",
132-
"app.verify-email-banner.help.title": "Vérification de l'email",
133-
"app.verify-email-banner.text": "{sent, select, true {Envoyé ! Veuillez vérifier votre boîte de réception (peut-être les spams) et cliquer sur le lien de confirmation.} other {Veuillez vérifier et confirmer votre adresse e-mail : <code>{email}</code>}}",
134+
"app.verify-email-banner.text": "{sent, select, true {Email envoyé ! Veuillez vérifier votre boîte de réception (et peut-être les spams) et cliquez sur le lien de confirmation.} other {Veuillez vérifier et confirmer votre adresse e-mail :}}",
135+
"app.verify-email-banner.title": "Vérifiez votre adresse e-mail",
134136
"chat.chat-indicator.tooltip": "Masquer ou Afficher le Chat du Document",
135137
"chat.input.placeholder": "Tapez un nouveau message ({have_llm, select, true {discutez avec l'IA ou } other {}}notifiez un collaborateur en tapant @)...",
136138
"chatroom.chat_input.preview_button.label": "Aperçu",

0 commit comments

Comments
 (0)