mirror of
https://github.com/makeplane/plane.git
synced 2026-02-10 08:09:25 -06:00
[WEB-4197] chore: auth forms semantics and accessibility #7128
This commit is contained in:
committed by
GitHub
parent
01b685ea57
commit
cb92108bf4
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Sbalit postranní panel",
|
||||
"expand_sidebar": "Rozbalit postranní panel",
|
||||
"edition_badge": "Otevřít modal placených plánů"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Vymazat e-mail",
|
||||
"show_password": "Zobrazit heslo",
|
||||
"hide_password": "Skrýt heslo",
|
||||
"close_alert": "Zavřít upozornění",
|
||||
"close_popover": "Zavřít vyskakovací okno"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Seitenleiste einklappen",
|
||||
"expand_sidebar": "Seitenleiste ausklappen",
|
||||
"edition_badge": "Modal für kostenpflichtige Pläne öffnen"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "E-Mail löschen",
|
||||
"show_password": "Passwort anzeigen",
|
||||
"hide_password": "Passwort verbergen",
|
||||
"close_alert": "Warnung schließen",
|
||||
"close_popover": "Popover schließen"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Collapse sidebar",
|
||||
"expand_sidebar": "Expand sidebar",
|
||||
"edition_badge": "Open paid plans' modal"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Clear email",
|
||||
"show_password": "Show password",
|
||||
"hide_password": "Hide password",
|
||||
"close_alert": "Close alert",
|
||||
"close_popover": "Close popover"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Colapsar barra lateral",
|
||||
"expand_sidebar": "Expandir barra lateral",
|
||||
"edition_badge": "Abrir modal de planes de pago"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Limpiar correo electrónico",
|
||||
"show_password": "Mostrar contraseña",
|
||||
"hide_password": "Ocultar contraseña",
|
||||
"close_alert": "Cerrar alerta",
|
||||
"close_popover": "Cerrar ventana emergente"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Réduire la barre latérale",
|
||||
"expand_sidebar": "Étendre la barre latérale",
|
||||
"edition_badge": "Ouvrir le modal des plans payants"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Effacer l'e-mail",
|
||||
"show_password": "Afficher le mot de passe",
|
||||
"hide_password": "Masquer le mot de passe",
|
||||
"close_alert": "Fermer l'alerte",
|
||||
"close_popover": "Fermer la fenêtre contextuelle"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Tutup sidebar",
|
||||
"expand_sidebar": "Perluas sidebar",
|
||||
"edition_badge": "Buka modal paket berbayar"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Hapus email",
|
||||
"show_password": "Tampilkan kata sandi",
|
||||
"hide_password": "Sembunyikan kata sandi",
|
||||
"close_alert": "Tutup peringatan",
|
||||
"close_popover": "Tutup popover"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Comprimi barra laterale",
|
||||
"expand_sidebar": "Espandi barra laterale",
|
||||
"edition_badge": "Apri modal piani a pagamento"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Cancella email",
|
||||
"show_password": "Mostra password",
|
||||
"hide_password": "Nascondi password",
|
||||
"close_alert": "Chiudi avviso",
|
||||
"close_popover": "Chiudi popover"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "サイドバーを折りたたむ",
|
||||
"expand_sidebar": "サイドバーを展開",
|
||||
"edition_badge": "有料プランのモーダルを開く"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "メールをクリア",
|
||||
"show_password": "パスワードを表示",
|
||||
"hide_password": "パスワードを非表示",
|
||||
"close_alert": "アラートを閉じる",
|
||||
"close_popover": "ポップオーバーを閉じる"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "사이드바 축소",
|
||||
"expand_sidebar": "사이드바 확장",
|
||||
"edition_badge": "유료 플랜 모달 열기"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "이메일 지우기",
|
||||
"show_password": "비밀번호 표시",
|
||||
"hide_password": "비밀번호 숨기기",
|
||||
"close_alert": "알림 닫기",
|
||||
"close_popover": "팝오버 닫기"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Zwiń pasek boczny",
|
||||
"expand_sidebar": "Rozwiń pasek boczny",
|
||||
"edition_badge": "Otwórz modal płatnych planów"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Wyczyść e-mail",
|
||||
"show_password": "Pokaż hasło",
|
||||
"hide_password": "Ukryj hasło",
|
||||
"close_alert": "Zamknij alert",
|
||||
"close_popover": "Zamknij popover"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Recolher barra lateral",
|
||||
"expand_sidebar": "Expandir barra lateral",
|
||||
"edition_badge": "Abrir modal de planos pagos"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Limpar e-mail",
|
||||
"show_password": "Mostrar senha",
|
||||
"hide_password": "Ocultar senha",
|
||||
"close_alert": "Fechar alerta",
|
||||
"close_popover": "Fechar popover"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Restrânge bara laterală",
|
||||
"expand_sidebar": "Extinde bara laterală",
|
||||
"edition_badge": "Deschide modalul planurilor plătite"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Șterge e-mailul",
|
||||
"show_password": "Afișează parola",
|
||||
"hide_password": "Ascunde parola",
|
||||
"close_alert": "Închide alerta",
|
||||
"close_popover": "Închide popover-ul"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Свернуть боковую панель",
|
||||
"expand_sidebar": "Развернуть боковую панель",
|
||||
"edition_badge": "Открыть модал платных планов"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Очистить email",
|
||||
"show_password": "Показать пароль",
|
||||
"hide_password": "Скрыть пароль",
|
||||
"close_alert": "Закрыть уведомление",
|
||||
"close_popover": "Закрыть всплывающее окно"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Zbaliť bočný panel",
|
||||
"expand_sidebar": "Rozbaliť bočný panel",
|
||||
"edition_badge": "Otvoriť modal platených plánov"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Vymazať e-mail",
|
||||
"show_password": "Zobraziť heslo",
|
||||
"hide_password": "Skryť heslo",
|
||||
"close_alert": "Zavrieť upozornenie",
|
||||
"close_popover": "Zavrieť vyskakovacie okno"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Kenar çubuğunu daralt",
|
||||
"expand_sidebar": "Kenar çubuğunu genişlet",
|
||||
"edition_badge": "Ücretli planlar modalını aç"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "E-postayı temizle",
|
||||
"show_password": "Şifreyi göster",
|
||||
"hide_password": "Şifreyi gizle",
|
||||
"close_alert": "Uyarıyı kapat",
|
||||
"close_popover": "Açılır pencereyi kapat"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Згорнути бічну панель",
|
||||
"expand_sidebar": "Розгорнути бічну панель",
|
||||
"edition_badge": "Відкрити модал платних планів"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Очистити email",
|
||||
"show_password": "Показати пароль",
|
||||
"hide_password": "Приховати пароль",
|
||||
"close_alert": "Закрити сповіщення",
|
||||
"close_popover": "Закрити спливаюче вікно"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "Thu gọn thanh bên",
|
||||
"expand_sidebar": "Mở rộng thanh bên",
|
||||
"edition_badge": "Mở modal gói trả phí"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "Xóa email",
|
||||
"show_password": "Hiển thị mật khẩu",
|
||||
"hide_password": "Ẩn mật khẩu",
|
||||
"close_alert": "Đóng cảnh báo",
|
||||
"close_popover": "Đóng popover"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "折叠侧边栏",
|
||||
"expand_sidebar": "展开侧边栏",
|
||||
"edition_badge": "打开付费计划模态框"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "清除邮箱",
|
||||
"show_password": "显示密码",
|
||||
"hide_password": "隐藏密码",
|
||||
"close_alert": "关闭警告",
|
||||
"close_popover": "关闭弹出框"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
"collapse_sidebar": "摺疊側邊欄",
|
||||
"expand_sidebar": "展開側邊欄",
|
||||
"edition_badge": "打開付費計劃模態框"
|
||||
},
|
||||
"auth_forms": {
|
||||
"clear_email": "清除電子郵件",
|
||||
"show_password": "顯示密碼",
|
||||
"hide_password": "隱藏密碼",
|
||||
"close_alert": "關閉警告",
|
||||
"close_popover": "關閉彈出框"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
"app-container"
|
||||
)}
|
||||
>
|
||||
<div className="w-full h-full overflow-hidden relative">{children}</div>
|
||||
<main className="w-full h-full overflow-hidden relative">{children}</main>
|
||||
</div>
|
||||
</AppProvider>
|
||||
</body>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { FC } from "react";
|
||||
import { Info, X } from "lucide-react";
|
||||
// plane imports
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// helpers
|
||||
import { TAuthErrorInfo } from "@/helpers/authentication.helper";
|
||||
|
||||
@@ -10,20 +12,28 @@ type TAuthBanner = {
|
||||
|
||||
export const AuthBanner: FC<TAuthBanner> = (props) => {
|
||||
const { bannerData, handleBannerData } = props;
|
||||
// translation
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!bannerData) return <></>;
|
||||
|
||||
return (
|
||||
<div className="relative flex items-center p-2 rounded-md gap-2 border border-custom-primary-100/50 bg-custom-primary-100/10">
|
||||
<div className="w-4 h-4 flex-shrink-0 relative flex justify-center items-center">
|
||||
<div
|
||||
role="alert"
|
||||
className="relative flex items-center p-2 rounded-md gap-2 border border-custom-primary-100/50 bg-custom-primary-100/10"
|
||||
>
|
||||
<div className="size-4 flex-shrink-0 grid place-items-center">
|
||||
<Info size={16} className="text-custom-primary-100" />
|
||||
</div>
|
||||
<div className="w-full text-sm font-medium text-custom-primary-100">{bannerData?.message}</div>
|
||||
<div
|
||||
className="relative ml-auto w-6 h-6 rounded-sm flex justify-center items-center transition-all cursor-pointer hover:bg-custom-primary-100/20 text-custom-primary-100/80"
|
||||
onClick={() => handleBannerData && handleBannerData(undefined)}
|
||||
<p className="w-full text-sm font-medium text-custom-primary-100">{bannerData?.message}</p>
|
||||
<button
|
||||
type="button"
|
||||
className="relative ml-auto size-6 rounded-sm grid place-items-center transition-all hover:bg-custom-primary-100/20 text-custom-primary-100/80"
|
||||
onClick={() => handleBannerData?.(undefined)}
|
||||
aria-label={t("aria_labels.auth_forms.close_alert")}
|
||||
>
|
||||
<X className="w-4 h-4 flex-shrink-0" />
|
||||
</div>
|
||||
<X className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -102,9 +102,9 @@ export const AuthHeader: FC<TAuthHeader> = observer((props) => {
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-1 text-center">
|
||||
<h3 className="text-3xl font-bold text-onboarding-text-100">
|
||||
<h1 className="text-3xl font-bold text-onboarding-text-100">
|
||||
{typeof header === "string" ? t(header) : header}
|
||||
</h3>
|
||||
</h1>
|
||||
<p className="font-medium text-onboarding-text-400">{t(subHeader)}</p>
|
||||
</div>
|
||||
{children}
|
||||
|
||||
@@ -47,7 +47,7 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
|
||||
return (
|
||||
<form onSubmit={handleFormSubmit} className="mt-5 space-y-4">
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="email">
|
||||
<label htmlFor="email" className="text-sm text-onboarding-text-300 font-medium">
|
||||
{t("auth.common.email.label")}
|
||||
</label>
|
||||
<div
|
||||
@@ -76,13 +76,17 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
|
||||
ref={inputRef}
|
||||
/>
|
||||
{email.length > 0 && (
|
||||
<XCircle
|
||||
className="h-[46px] w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs"
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setEmail("");
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
/>
|
||||
className="absolute right-3 size-5 grid place-items-center"
|
||||
aria-label={t("aria_labels.auth_forms.clear_email")}
|
||||
>
|
||||
<XCircle className="size-5 stroke-custom-text-400" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{emailError?.email && !isFocused && (
|
||||
|
||||
@@ -45,8 +45,13 @@ export const ForgotPasswordPopover = () => {
|
||||
>
|
||||
<span className="flex-shrink-0">🤥</span>
|
||||
<p className="text-xs">{t("auth.forgot_password.errors.smtp_not_enabled")}</p>
|
||||
<button type="button" className="flex-shrink-0" onClick={() => close()}>
|
||||
<X className="h-3 w-3 text-onboarding-text-200" />
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 size-3 grid place-items-center"
|
||||
onClick={() => close()}
|
||||
aria-label={t("aria_labels.auth_forms.close_popover")}
|
||||
>
|
||||
<X className="size-3 text-onboarding-text-200" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -167,7 +167,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
<input type="hidden" value={passwordFormData.email} name="email" />
|
||||
{nextPath && <input type="hidden" value={nextPath} name="next_path" />}
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium text-onboarding-text-300" htmlFor="email">
|
||||
<label htmlFor="email" className="text-sm font-medium text-onboarding-text-300">
|
||||
{t("auth.common.email.label")}
|
||||
</label>
|
||||
<div
|
||||
@@ -184,21 +184,26 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
disabled
|
||||
/>
|
||||
{passwordFormData.email.length > 0 && (
|
||||
<XCircle
|
||||
className="absolute right-3 h-5 w-5 stroke-custom-text-400 hover:cursor-pointer"
|
||||
<button
|
||||
type="button"
|
||||
className="absolute right-3 size-5"
|
||||
onClick={handleEmailClear}
|
||||
/>
|
||||
aria-label={t("aria_labels.auth_forms.clear_email")}
|
||||
>
|
||||
<XCircle className="size-5 stroke-custom-text-400" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="password">
|
||||
<label htmlFor="password" className="text-sm text-onboarding-text-300 font-medium">
|
||||
{mode === EAuthModes.SIGN_IN ? t("auth.common.password.label") : t("auth.common.password.set_password")}
|
||||
</label>
|
||||
<div className="relative flex items-center rounded-md bg-onboarding-background-200">
|
||||
<Input
|
||||
type={showPassword?.password ? "text" : "password"}
|
||||
id="password"
|
||||
name="password"
|
||||
value={passwordFormData.password}
|
||||
onChange={(e) => handleFormChange("password", e.target.value)}
|
||||
@@ -209,29 +214,33 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
/>
|
||||
{showPassword?.password ? (
|
||||
<EyeOff
|
||||
className="absolute right-3 h-5 w-5 stroke-custom-text-400 hover:cursor-pointer"
|
||||
onClick={() => handleShowPassword("password")}
|
||||
/>
|
||||
) : (
|
||||
<Eye
|
||||
className="absolute right-3 h-5 w-5 stroke-custom-text-400 hover:cursor-pointer"
|
||||
onClick={() => handleShowPassword("password")}
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleShowPassword("password")}
|
||||
className="absolute right-3 size-5 grid place-items-center"
|
||||
aria-label={t(
|
||||
showPassword?.password ? "aria_labels.auth_forms.hide_password" : "aria_labels.auth_forms.show_password"
|
||||
)}
|
||||
>
|
||||
{showPassword?.password ? (
|
||||
<EyeOff className="size-5 stroke-custom-text-400" />
|
||||
) : (
|
||||
<Eye className="size-5 stroke-custom-text-400" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{passwordSupport}
|
||||
</div>
|
||||
|
||||
{mode === EAuthModes.SIGN_UP && (
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm text-onboarding-text-300 font-medium" htmlFor="confirm_password">
|
||||
<label htmlFor="confirm-password" className="text-sm text-onboarding-text-300 font-medium">
|
||||
{t("auth.common.password.confirm_password.label")}
|
||||
</label>
|
||||
<div className="relative flex items-center rounded-md bg-onboarding-background-200">
|
||||
<Input
|
||||
type={showPassword?.retypePassword ? "text" : "password"}
|
||||
id="confirm-password"
|
||||
name="confirm_password"
|
||||
value={passwordFormData.confirm_password}
|
||||
onChange={(e) => handleFormChange("confirm_password", e.target.value)}
|
||||
@@ -240,17 +249,22 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
onFocus={() => setIsRetryPasswordInputFocused(true)}
|
||||
onBlur={() => setIsRetryPasswordInputFocused(false)}
|
||||
/>
|
||||
{showPassword?.retypePassword ? (
|
||||
<EyeOff
|
||||
className="absolute right-3 h-5 w-5 stroke-custom-text-400 hover:cursor-pointer"
|
||||
onClick={() => handleShowPassword("retypePassword")}
|
||||
/>
|
||||
) : (
|
||||
<Eye
|
||||
className="absolute right-3 h-5 w-5 stroke-custom-text-400 hover:cursor-pointer"
|
||||
onClick={() => handleShowPassword("retypePassword")}
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="absolute right-3 size-5 grid place-items-center"
|
||||
aria-label={t(
|
||||
showPassword?.retypePassword
|
||||
? "aria_labels.auth_forms.hide_password"
|
||||
: "aria_labels.auth_forms.show_password"
|
||||
)}
|
||||
onClick={() => handleShowPassword("retypePassword")}
|
||||
>
|
||||
{showPassword?.retypePassword ? (
|
||||
<EyeOff className="size-5 stroke-custom-text-400" />
|
||||
) : (
|
||||
<Eye className="size-5 stroke-custom-text-400" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{!!passwordFormData.confirm_password &&
|
||||
passwordFormData.password !== passwordFormData.confirm_password &&
|
||||
|
||||
@@ -96,7 +96,7 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
<input type="hidden" value={uniqueCodeFormData.email} name="email" />
|
||||
{nextPath && <input type="hidden" value={nextPath} name="next_path" />}
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium text-onboarding-text-300" htmlFor="email">
|
||||
<label htmlFor="email" className="text-sm font-medium text-onboarding-text-300">
|
||||
{t("auth.common.email.label")}
|
||||
</label>
|
||||
<div
|
||||
@@ -109,25 +109,30 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
value={uniqueCodeFormData.email}
|
||||
onChange={(e) => handleFormChange("email", e.target.value)}
|
||||
placeholder={t("auth.common.email.placeholder")}
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-onboarding-text-400 border-0`}
|
||||
className="disable-autofill-style h-[46px] w-full placeholder:text-onboarding-text-400 border-0"
|
||||
autoComplete="on"
|
||||
disabled
|
||||
/>
|
||||
{uniqueCodeFormData.email.length > 0 && (
|
||||
<XCircle
|
||||
className="absolute right-3 h-5 w-5 stroke-custom-text-400 hover:cursor-pointer"
|
||||
<button
|
||||
type="button"
|
||||
className="absolute right-3 size-5 grid place-items-center"
|
||||
aria-label={t("aria_labels.auth_forms.clear_email")}
|
||||
onClick={handleEmailClear}
|
||||
/>
|
||||
>
|
||||
<XCircle className="size-5 stroke-custom-text-400" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
<label className="text-sm font-medium text-onboarding-text-300" htmlFor="code">
|
||||
<label htmlFor="unique-code" className="text-sm font-medium text-onboarding-text-300">
|
||||
{t("auth.common.unique_code.label")}
|
||||
</label>
|
||||
<Input
|
||||
name="code"
|
||||
id="unique-code"
|
||||
value={uniqueCodeFormData.code}
|
||||
onChange={(e) => handleFormChange("code", e.target.value)}
|
||||
placeholder={t("auth.common.unique_code.placeholder")}
|
||||
@@ -142,11 +147,11 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => generateNewCode(uniqueCodeFormData.email)}
|
||||
className={`${
|
||||
className={
|
||||
isRequestNewCodeDisabled
|
||||
? "text-onboarding-text-400"
|
||||
: "font-medium text-custom-primary-300 hover:text-custom-primary-200"
|
||||
}`}
|
||||
}
|
||||
disabled={isRequestNewCodeDisabled}
|
||||
>
|
||||
{resendTimerCode > 0
|
||||
@@ -160,7 +165,13 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
|
||||
<div className="space-y-2.5">
|
||||
<Button type="submit" variant="primary" className="w-full" size="lg" disabled={isButtonDisabled}>
|
||||
{isRequestingNewCode ? t("auth.common.unique_code.sending_code") : isSubmitting ? <Spinner height="20px" width="20px" /> : t("common.continue")}
|
||||
{isRequestingNewCode ? (
|
||||
t("auth.common.unique_code.sending_code")
|
||||
) : isSubmitting ? (
|
||||
<Spinner height="20px" width="20px" />
|
||||
) : (
|
||||
t("common.continue")
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -8,7 +8,7 @@ type Props = {
|
||||
export const TermsAndConditions: FC<Props> = (props) => {
|
||||
const { isSignUp = false } = props;
|
||||
return (
|
||||
<span className="flex items-center justify-center py-6">
|
||||
<div className="flex items-center justify-center py-6">
|
||||
<p className="text-center text-sm text-onboarding-text-200 whitespace-pre-line">
|
||||
{isSignUp ? "By creating an account" : "By signing in"}, you agree to our{" \n"}
|
||||
<Link href="https://plane.so/legals/terms-and-conditions" target="_blank" rel="noopener noreferrer">
|
||||
@@ -20,6 +20,6 @@ export const TermsAndConditions: FC<Props> = (props) => {
|
||||
</Link>
|
||||
{"."}
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user