mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 14:01:45 +02:00
[WEB-4613] chore: mobile auth and minor improvements (#3801)
This commit is contained in:
committed by
GitHub
parent
14297cef00
commit
6c9fff1331
@@ -68,7 +68,7 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="name@company.com"
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-onboarding-text-400 autofill:bg-red-500 border-0 focus:bg-none active:bg-transparent`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-onboarding-text-400 autofill:bg-red-500 border-0 focus:bg-none active:bg-transparent`}
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
ref={inputRef}
|
||||
@@ -83,7 +83,7 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
|
||||
}}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<XCircle className="h-[46px] w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs" />
|
||||
<XCircle className="h-10 w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -130,7 +130,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
value={passwordFormData.email}
|
||||
onChange={(e) => handleFormChange("email", e.target.value)}
|
||||
placeholder="name@company.com"
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-onboarding-text-400 border-0`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-onboarding-text-400 border-0`}
|
||||
disabled
|
||||
/>
|
||||
{passwordFormData.email.length > 0 && (
|
||||
@@ -153,7 +153,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
value={passwordFormData.password}
|
||||
onChange={(e) => handleFormChange("password", e.target.value)}
|
||||
placeholder="Enter password"
|
||||
className="disable-autofill-style h-[46px] w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
|
||||
onFocus={() => setIsPasswordInputFocused(true)}
|
||||
onBlur={() => setIsPasswordInputFocused(false)}
|
||||
autoComplete="on"
|
||||
@@ -186,7 +186,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
value={passwordFormData.confirm_password}
|
||||
onChange={(e) => handleFormChange("confirm_password", e.target.value)}
|
||||
placeholder="Confirm password"
|
||||
className="disable-autofill-style h-[46px] w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
|
||||
onFocus={() => setIsRetryPasswordInputFocused(true)}
|
||||
onBlur={() => setIsRetryPasswordInputFocused(false)}
|
||||
/>
|
||||
|
||||
@@ -94,7 +94,7 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
value={uniqueCodeFormData.email}
|
||||
onChange={(e) => handleFormChange("email", e.target.value)}
|
||||
placeholder="name@company.com"
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-onboarding-text-400 border-0`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-onboarding-text-400 border-0`}
|
||||
disabled
|
||||
/>
|
||||
{uniqueCodeFormData.email.length > 0 && (
|
||||
@@ -115,7 +115,7 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
value={uniqueCodeFormData.code}
|
||||
onChange={(e) => handleFormChange("code", e.target.value)}
|
||||
placeholder="gets-sets-flys"
|
||||
className="disable-autofill-style h-[46px] w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400"
|
||||
autoFocus
|
||||
/>
|
||||
<div className="flex w-full items-center justify-between px-1 text-xs pt-1">
|
||||
|
||||
@@ -2,32 +2,20 @@
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Image from "next/image";
|
||||
import { useTheme } from "next-themes";
|
||||
import { TInstanceConfig } from "@plane/types";
|
||||
// hooks
|
||||
import { useInstance } from "@/hooks/store";
|
||||
// components
|
||||
import { AuthRoot } from "@/plane-web/components/mobile";
|
||||
// assets
|
||||
import PlaneBackgroundPatternDark from "@/public/auth/background-pattern-dark.svg";
|
||||
import PlaneBackgroundPattern from "@/public/auth/background-pattern.svg";
|
||||
|
||||
const MobileAuth = observer(() => {
|
||||
const { resolvedTheme } = useTheme();
|
||||
// hooks
|
||||
const { config } = useInstance();
|
||||
|
||||
// derived values
|
||||
const pageBackgroundPattern = resolvedTheme === "dark" ? PlaneBackgroundPatternDark : PlaneBackgroundPattern;
|
||||
|
||||
return (
|
||||
<div className="isolate relative w-screen h-screen overflow-hidden">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<Image src={pageBackgroundPattern} className="w-full h-full object-cover" alt="Plane background pattern" />
|
||||
</div>
|
||||
<div className="relative z-10 w-screen h-screen overflow-hidden overflow-y-auto flex flex-col">
|
||||
<div className="py-5 flex flex-col justify-center flex-grow container mx-auto max-w-lg px-10 lg:max-w-md lg:px-5 transition-all">
|
||||
<div className="isolate relative z-10 flex flex-col items-center w-screen h-screen overflow-hidden overflow-y-auto pt-6 pb-10 px-8">
|
||||
<div className="flex flex-col justify-center items-center flex-grow w-full py-6 mt-10">
|
||||
<div className="relative flex flex-col gap-6 max-w-[22.5rem] w-full">
|
||||
<AuthRoot config={config as TInstanceConfig} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -103,10 +103,10 @@ export const AuthHeader: FC<TAuthHeader> = observer((props) => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-2xl font-semibold text-custom-text-100">
|
||||
<span className="text-2xl font-semibold text-custom-text-100 leading-7">
|
||||
{typeof header === "string" ? t(header) : header}
|
||||
</span>
|
||||
<span className="text-2xl font-semibold text-custom-text-400">{subHeader}</span>
|
||||
<span className="text-2xl font-semibold text-custom-text-400 leading-7">{subHeader}</span>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ export const AuthEmailForm: FC<TAuthEmailForm> = observer((props) => {
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder={t("auth.common.email.placeholder")}
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-custom-text-400 autofill:bg-red-500 border-0 focus:bg-none active:bg-transparent`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-custom-text-400 autofill:bg-red-500 border-0 focus:bg-none active:bg-transparent`}
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
ref={inputRef}
|
||||
|
||||
@@ -111,7 +111,7 @@ export const ForgotPasswordForm = observer(() => {
|
||||
ref={ref}
|
||||
hasError={Boolean(errors.email)}
|
||||
placeholder={t("auth.common.email.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
autoComplete="on"
|
||||
disabled={resendTimerCode > 0}
|
||||
/>
|
||||
|
||||
@@ -195,7 +195,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
value={passwordFormData.email}
|
||||
onChange={(e) => handleFormChange("email", e.target.value)}
|
||||
placeholder={t("auth.common.email.placeholder")}
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-custom-text-400 border-0`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-custom-text-400 border-0`}
|
||||
disabled
|
||||
/>
|
||||
{passwordFormData.email.length > 0 && (
|
||||
@@ -223,7 +223,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
value={passwordFormData.password}
|
||||
onChange={(e) => handleFormChange("password", e.target.value)}
|
||||
placeholder={t("auth.common.password.placeholder")}
|
||||
className="disable-autofill-style h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
onFocus={() => setIsPasswordInputFocused(true)}
|
||||
onBlur={() => setIsPasswordInputFocused(false)}
|
||||
autoComplete="on"
|
||||
@@ -260,7 +260,7 @@ export const AuthPasswordForm: React.FC<Props> = observer((props: Props) => {
|
||||
value={passwordFormData.confirm_password}
|
||||
onChange={(e) => handleFormChange("confirm_password", e.target.value)}
|
||||
placeholder={t("auth.common.password.confirm_password.placeholder")}
|
||||
className="disable-autofill-style h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
onFocus={() => setIsRetryPasswordInputFocused(true)}
|
||||
onBlur={() => setIsRetryPasswordInputFocused(false)}
|
||||
/>
|
||||
|
||||
@@ -117,7 +117,7 @@ export const ResetPasswordForm = observer(() => {
|
||||
value={resetFormData.email}
|
||||
//hasError={Boolean(errors.email)}
|
||||
placeholder={t("auth.common.email.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 text-custom-text-400 cursor-not-allowed"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 text-custom-text-400 cursor-not-allowed"
|
||||
autoComplete="on"
|
||||
disabled
|
||||
/>
|
||||
@@ -135,7 +135,7 @@ export const ResetPasswordForm = observer(() => {
|
||||
onChange={(e) => handleFormChange("password", e.target.value)}
|
||||
//hasError={Boolean(errors.password)}
|
||||
placeholder={t("auth.common.password.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
minLength={8}
|
||||
onFocus={() => setIsPasswordInputFocused(true)}
|
||||
onBlur={() => setIsPasswordInputFocused(false)}
|
||||
@@ -167,7 +167,7 @@ export const ResetPasswordForm = observer(() => {
|
||||
value={resetFormData.confirm_password}
|
||||
onChange={(e) => handleFormChange("confirm_password", e.target.value)}
|
||||
placeholder={t("auth.common.password.confirm_password.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
onFocus={() => setIsRetryPasswordInputFocused(true)}
|
||||
onBlur={() => setIsRetryPasswordInputFocused(false)}
|
||||
/>
|
||||
|
||||
@@ -131,7 +131,7 @@ export const SetPasswordForm = observer(() => {
|
||||
value={user?.email}
|
||||
//hasError={Boolean(errors.email)}
|
||||
placeholder={t("auth.common.email.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 text-custom-text-400 cursor-not-allowed"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 text-custom-text-400 cursor-not-allowed"
|
||||
autoComplete="on"
|
||||
disabled
|
||||
/>
|
||||
@@ -149,7 +149,7 @@ export const SetPasswordForm = observer(() => {
|
||||
onChange={(e) => handleFormChange("password", e.target.value)}
|
||||
//hasError={Boolean(errors.password)}
|
||||
placeholder={t("auth.common.password.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
minLength={8}
|
||||
onFocus={() => setIsPasswordInputFocused(true)}
|
||||
onBlur={() => setIsPasswordInputFocused(false)}
|
||||
@@ -181,7 +181,7 @@ export const SetPasswordForm = observer(() => {
|
||||
value={passwordFormData.confirm_password}
|
||||
onChange={(e) => handleFormChange("confirm_password", e.target.value)}
|
||||
placeholder={t("auth.common.password.confirm_password.placeholder")}
|
||||
className="h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
onFocus={() => setIsRetryPasswordInputFocused(true)}
|
||||
onBlur={() => setIsRetryPasswordInputFocused(false)}
|
||||
/>
|
||||
|
||||
@@ -129,7 +129,7 @@ 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-custom-text-400 border-0"
|
||||
className="disable-autofill-style h-10 w-full placeholder:text-custom-text-400 border-0"
|
||||
autoComplete="on"
|
||||
disabled
|
||||
/>
|
||||
@@ -156,7 +156,7 @@ export const AuthUniqueCodeForm: React.FC<TAuthUniqueCodeForm> = (props) => {
|
||||
value={uniqueCodeFormData.code}
|
||||
onChange={(e) => handleFormChange("code", e.target.value)}
|
||||
placeholder={t("auth.common.unique_code.placeholder")}
|
||||
className="disable-autofill-style h-[46px] w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-custom-border-300 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
autoFocus
|
||||
/>
|
||||
<div className="flex w-full items-center justify-between px-1 text-xs pt-1">
|
||||
|
||||
@@ -26,7 +26,7 @@ const BRAND_LOGOS: {
|
||||
|
||||
export const AuthFooter = () => (
|
||||
<div className="flex flex-col items-center gap-6">
|
||||
<span className="text-md text-custom-text-300 whitespace-nowrap">Join 10,000+ teams building with Plane</span>
|
||||
<span className="text-sm text-custom-text-300 whitespace-nowrap">Join 10,000+ teams building with Plane</span>
|
||||
<div className="flex items-center justify-center gap-x-10 gap-y-4 w-full flex-wrap">
|
||||
{BRAND_LOGOS.map((brand) => (
|
||||
<div className="flex items-center justify-center h-7 flex-1" key={brand.id}>
|
||||
|
||||
@@ -135,14 +135,14 @@ export const MobileAuthEmailValidationForm: FC<TMobileAuthEmailValidationForm> =
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="name@example.com"
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-custom-text-400 autofill:bg-red-500 border-0 focus:bg-none active:bg-transparent`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-custom-text-400 autofill:bg-red-500 border-0 focus:bg-none active:bg-transparent`}
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
ref={inputRef}
|
||||
/>
|
||||
{email.length > 0 && (
|
||||
<XCircle
|
||||
className="h-[46px] w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs"
|
||||
className="h-10 w-11 px-3 stroke-custom-text-400 hover:cursor-pointer text-xs"
|
||||
onClick={() => {
|
||||
setEmail("");
|
||||
inputRef.current?.focus();
|
||||
|
||||
@@ -156,7 +156,7 @@ export const MobileAuthPasswordForm: FC<TMobileAuthPasswordForm> = (props) => {
|
||||
value={formData.email}
|
||||
onChange={(e) => handleFormChange("email", e.target.value)}
|
||||
placeholder="name@company.com"
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-custom-text-400 border-0`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-custom-text-400 border-0`}
|
||||
disabled
|
||||
/>
|
||||
{formData.email.length > 0 && (
|
||||
@@ -180,7 +180,7 @@ export const MobileAuthPasswordForm: FC<TMobileAuthPasswordForm> = (props) => {
|
||||
value={formData.password}
|
||||
onChange={(e) => handleFormChange("password", e.target.value)}
|
||||
placeholder="Enter password"
|
||||
className="disable-autofill-style h-[46px] w-full border border-custom-border-100 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-custom-border-100 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
onFocus={() => handlePasswordInputFocused("password")}
|
||||
@@ -218,7 +218,7 @@ export const MobileAuthPasswordForm: FC<TMobileAuthPasswordForm> = (props) => {
|
||||
value={formData.passwordConfirmation}
|
||||
onChange={(e) => handleFormChange("passwordConfirmation", e.target.value)}
|
||||
placeholder="Enter password"
|
||||
className="disable-autofill-style h-[46px] w-full border border-custom-border-100 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-custom-border-100 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
disabled={!isPasswordConfirmationEnabled}
|
||||
onFocus={() => handlePasswordInputFocused("passwordConfirmation")}
|
||||
onBlur={() => handlePasswordInputFocused("passwordConfirmation")}
|
||||
|
||||
@@ -114,7 +114,7 @@ export const MobileAuthUniqueCodeForm: FC<TMobileAuthUniqueCodeForm> = (props) =
|
||||
value={formData.email}
|
||||
onChange={(e) => handleFormChange("email", e.target.value)}
|
||||
placeholder="name@company.com"
|
||||
className={`disable-autofill-style h-[46px] w-full placeholder:text-custom-text-400 border-0`}
|
||||
className={`disable-autofill-style h-10 w-full placeholder:text-custom-text-400 border-0`}
|
||||
disabled
|
||||
/>
|
||||
{formData.email.length > 0 && (
|
||||
@@ -137,7 +137,7 @@ export const MobileAuthUniqueCodeForm: FC<TMobileAuthUniqueCodeForm> = (props) =
|
||||
value={formData.code}
|
||||
onChange={(e) => handleFormChange("code", e.target.value)}
|
||||
placeholder="gets-sets-flys"
|
||||
className="disable-autofill-style h-[46px] w-full border border-custom-border-100 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
className="disable-autofill-style h-10 w-full border border-custom-border-100 !bg-custom-background-100 pr-12 placeholder:text-custom-text-400"
|
||||
autoComplete="on"
|
||||
autoFocus
|
||||
/>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import Image from "next/image";
|
||||
import { EMobileAuthModes, EMobileAuthSteps, TMobileAuthModes, TMobileAuthSteps } from "@plane/constants";
|
||||
import { TMobileWorkspaceInvitation } from "@plane/types";
|
||||
// assets
|
||||
import planeLogo from "@/public/plane-logos/blue-without-text.png";
|
||||
import { PlaneLogo } from "@plane/ui";
|
||||
|
||||
const AUTH_SIGNUP_HEADER_CONTENT_OPTIONS = {
|
||||
[EMobileAuthSteps.EMAIL]: {
|
||||
@@ -69,11 +67,9 @@ export const MobileAuthHeader: FC<TMobileAuthHeader> = (props) => {
|
||||
|
||||
return (
|
||||
<div className="relative space-y-6">
|
||||
<div className="relative h-[50px] w-[50px]">
|
||||
<Image src={planeLogo} alt="Plane logo" className="object-contain" />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<h3 className="text-3xl font-semibold text-custom-text-100">{title}</h3>
|
||||
<PlaneLogo height={51} width={84} className="text-custom-text-100" />
|
||||
<div className="flex flex-col gap-1">
|
||||
<h3 className="text-2xl font-semibold text-custom-text-100">{title}</h3>
|
||||
{description && <p className="font-medium text-custom-text-400">{description}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import React from "react";
|
||||
import Link from "next/link";
|
||||
import { EAuthModes } from "@plane/constants";
|
||||
|
||||
export const MobileTermsAndConditions: FC = () => (
|
||||
<div className="flex items-center justify-center py-4">
|
||||
<div className="text-center text-sm text-custom-text-200 whitespace-pre-line">
|
||||
By signing in, you agree to our
|
||||
<br />
|
||||
<Link href="https://plane.so/legals/terms-and-conditions" target="_blank" rel="noopener noreferrer">
|
||||
<span className="text-sm font-medium underline hover:cursor-pointer">Terms of Service</span>
|
||||
</Link>
|
||||
and
|
||||
<Link href="https://plane.so/legals/privacy-policy" target="_blank" rel="noopener noreferrer">
|
||||
<span className="text-sm font-medium underline hover:cursor-pointer">Privacy Policy</span>
|
||||
</Link>
|
||||
.
|
||||
</div>
|
||||
interface TermsAndConditionsProps {
|
||||
authType?: EAuthModes;
|
||||
}
|
||||
|
||||
// Constants for better maintainability
|
||||
const LEGAL_LINKS = {
|
||||
termsOfService: "https://plane.so/legals/terms-and-conditions",
|
||||
privacyPolicy: "https://plane.so/legals/privacy-policy",
|
||||
} as const;
|
||||
|
||||
const MESSAGES = {
|
||||
[EAuthModes.SIGN_UP]: "By creating an account",
|
||||
[EAuthModes.SIGN_IN]: "By signing in",
|
||||
} as const;
|
||||
|
||||
// Reusable link component to reduce duplication
|
||||
const LegalLink: React.FC<{ href: string; children: React.ReactNode }> = ({ href, children }) => (
|
||||
<Link href={href} className="text-custom-text-200" target="_blank" rel="noopener noreferrer">
|
||||
<span className="text-sm font-medium underline hover:cursor-pointer">{children}</span>
|
||||
</Link>
|
||||
);
|
||||
|
||||
export const MobileTermsAndConditions: React.FC<TermsAndConditionsProps> = ({ authType = EAuthModes.SIGN_IN }) => (
|
||||
<div className="flex items-center justify-center">
|
||||
<p className="text-center text-sm text-custom-text-300 whitespace-pre-line">
|
||||
{`${MESSAGES[authType]}, you understand and agree to \n our `}
|
||||
<LegalLink href={LEGAL_LINKS.termsOfService}>Terms of Service</LegalLink> and{" "}
|
||||
<LegalLink href={LEGAL_LINKS.privacyPolicy}>Privacy Policy</LegalLink>.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user