Skip to content

Commit

Permalink
Merge pull request #479 from sinamics/auth-layout-take2
Browse files Browse the repository at this point in the history
Improved public auth pages layout
  • Loading branch information
sinamics authored Aug 8, 2024
2 parents 61fccfa + d30c8b7 commit 130a40d
Show file tree
Hide file tree
Showing 25 changed files with 486 additions and 400 deletions.
2 changes: 1 addition & 1 deletion docs/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const LandingPage = (): JSX.Element => {
<h2>ZTNET Documentation</h2>

<h1 className="title-text">
<span className="text-primary ">Zerotier </span>Controller Web UI
<span className="text-primary">Zerotier </span>Controller Web UI
</h1>
<div className="nav-buttons">
<a
Expand Down
8 changes: 7 additions & 1 deletion src/__tests__/pages/auth/signin.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ jest.mock("../../../utils/api", () => ({
getWelcomeMessage: {
useQuery: jest.fn(),
},
registrationAllowed: {
useQuery: jest.fn().mockReturnValue({
data: { allowed: true },
isLoading: false,
}),
},
},
network: {
getUserNetworks: {
Expand Down Expand Up @@ -63,7 +69,7 @@ describe("LoginPage", () => {
render(
<QueryClientProvider client={queryClient}>
<NextIntlClientProvider locale="en" messages={enTranslation}>
<LoginPage hasOauth={hasOauth} oauthExlusiveLogin={false} />
<LoginPage title="test" hasOauth={hasOauth} oauthExclusiveLogin={false} />
</NextIntlClientProvider>
</QueryClientProvider>,
);
Expand Down
7 changes: 5 additions & 2 deletions src/components/auth/credentialsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toast } from "react-hot-toast";
import { ErrorCode } from "~/utils/errorCode";
import Link from "next/link";
import TOTPInput from "./totpInput";
import SubmitButtons from "./submitButtons";
import FormSubmitButtons from "./formSubmitButton";
import FormInput from "./formInput";

interface FormData {
Expand Down Expand Up @@ -122,7 +122,10 @@ const CredentialsForm: React.FC = () => {
)}
{showOTP && <TOTPInput totpCode={totpCode} setTotpCode={setTotpCode} />}
<div className="pt-5">
<SubmitButtons loading={loading.credentials} isTotp={showOTP} />
<FormSubmitButtons
loading={loading.credentials}
title={showOTP ? "Verify TOTP" : "Sign in"}
/>
</div>
</form>
);
Expand Down
62 changes: 25 additions & 37 deletions src/components/auth/forgotPasswordForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useState } from "react";
import { api } from "~/utils/api";
import cn from "classnames";
import { toast } from "react-hot-toast";
import { useTrpcApiErrorHandler } from "~/hooks/useTrpcApiHandler";
import FormInput from "./formInput";
import FormSubmitButtons from "./formSubmitButton";

interface FormData {
email: string;
Expand Down Expand Up @@ -44,43 +45,30 @@ const ForgotPasswordForm: React.FC = () => {
});
};
return (
<div className="z-10 flex justify-center self-center">
<div className="w-100 mx-auto rounded-2xl border p-12">
<div className="mb-4">
<h3 className="text-2xl font-semibold">Forgot Password </h3>
<p className="text-gray-500">
We will send you a reset link if the email exist
</p>
</div>
<form className="space-y-5" onSubmit={submitHandler}>
<div className="space-y-2">
<label className="text-sm font-medium tracking-wide">Email</label>
<input
className="input w-full rounded-lg border border-gray-300 px-4 py-2 text-base focus:border-primary/25 focus:outline-none"
value={formData.email}
onChange={handleChange}
type="email"
name="email"
placeholder="mail@example.com"
/>
</div>
<div className="pt-5">
<button
type="submit"
className={cn(
"btn btn-block btn-primary cursor-pointer rounded-full p-3 font-semibold tracking-wide shadow-lg",
)}
>
{loading ? <span className="loading loading-spinner"></span> : null}
Send Email
</button>
</div>
</form>
<div className="pt-5 text-center text-xs text-gray-400">
<span>Copyright © {new Date().getFullYear()} Kodea Solutions</span>
</div>
<form className="space-y-5" onSubmit={submitHandler}>
<FormInput
label="Email"
name="email"
type="text"
value={formData.email}
onChange={handleChange}
placeholder="mail@example.com"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
className="h-4 w-4 opacity-70"
>
<path d="M2.5 3A1.5 1.5 0 0 0 1 4.5v.793c.026.009.051.02.076.032L7.674 8.51c.206.1.446.1.652 0l6.598-3.185A.755.755 0 0 1 15 5.293V4.5A1.5 1.5 0 0 0 13.5 3h-11Z" />
<path d="M15 6.954 8.978 9.86a2.25 2.25 0 0 1-1.956 0L1 6.954V11.5A1.5 1.5 0 0 0 2.5 13h11a1.5 1.5 0 0 0 1.5-1.5V6.954Z" />
</svg>
}
/>
<div className="pt-5">
<FormSubmitButtons loading={loading} title="Send Email" />
</div>
</div>
</form>
);
};

Expand Down
3 changes: 3 additions & 0 deletions src/components/auth/formInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface FormInputProps {
value: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
placeholder: string;
disabled?: boolean;
icon?: ReactElement;
}

Expand All @@ -17,6 +18,7 @@ const FormInput: React.FC<FormInputProps> = ({
value,
onChange,
placeholder,
disabled = false,
icon,
}) => {
return (
Expand All @@ -28,6 +30,7 @@ const FormInput: React.FC<FormInputProps> = ({
{icon && React.cloneElement(icon, { className: "h-4 w-4 opacity-70" })}
<input
id={name}
disabled={disabled}
className="grow"
value={value}
onChange={onChange}
Expand Down
20 changes: 20 additions & 0 deletions src/components/auth/formSubmitButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import cn from "classnames";

interface SubmitButtonProps {
loading: boolean;
title: string;
}

const FormSubmitButtons: React.FC<SubmitButtonProps> = ({ loading, title }) => (
<button
type="submit"
className={cn(
"btn btn-block btn-primary border cursor-pointer font-semibold tracking-wide shadow-lg",
)}
>
{loading ? <span className="loading loading-spinner"></span> : null}
{title}
</button>
);

export default FormSubmitButtons;
65 changes: 27 additions & 38 deletions src/components/auth/mfaRecoveryForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useState } from "react";
import { api } from "~/utils/api";
import cn from "classnames";
import { toast } from "react-hot-toast";
import { useTrpcApiErrorHandler } from "~/hooks/useTrpcApiHandler";
import FormInput from "./formInput";
import FormSubmitButtons from "./formSubmitButton";

interface FormData {
email: string;
Expand Down Expand Up @@ -33,7 +34,7 @@ const MfaRecoveryForm: React.FC = () => {
onSuccess: () => {
setLoading(false);
setFormData({ email: "" });
toast.success("Password reset link sent to your email if the account exist!", {
toast.success("2FA reset procedure sent to your email if the account exist!", {
duration: 10000,
});
},
Expand All @@ -44,43 +45,31 @@ const MfaRecoveryForm: React.FC = () => {
});
};
return (
<div className="z-10 flex justify-center self-center">
<div className="w-100 mx-auto rounded-2xl border border-primary p-12">
<div className="mb-4">
<h3 className="text-2xl font-semibold">2FA Recovery</h3>
<p className="text-gray-500">
We will send you instructions on how to recover your account
</p>
</div>
<form className="space-y-5" onSubmit={submitHandler}>
<div className="space-y-2">
<label className="text-sm font-medium tracking-wide">Email</label>
<input
className="input w-full rounded-lg border border-gray-300 px-4 py-2 text-base focus:border-primary/25 focus:outline-none"
value={formData.email}
onChange={handleChange}
type="email"
name="email"
placeholder="mail@example.com"
/>
</div>
<div className="pt-5">
<button
type="submit"
className={cn(
"btn btn-block btn-primary cursor-pointer rounded-full p-3 font-semibold tracking-wide shadow-lg",
)}
>
{loading ? <span className="loading loading-spinner"></span> : null}
Send Email
</button>
</div>
</form>
<div className="pt-5 text-center text-xs text-gray-400">
<span>Copyright © {new Date().getFullYear()} Kodea Solutions</span>
</div>
<form className="space-y-5" onSubmit={submitHandler}>
<FormInput
label="Email"
name="email"
type="email"
value={formData.email}
onChange={handleChange}
placeholder="mail@example.com"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
className="h-4 w-4 opacity-70"
>
<path d="M2.5 3A1.5 1.5 0 0 0 1 4.5v.793c.026.009.051.02.076.032L7.674 8.51c.206.1.446.1.652 0l6.598-3.185A.755.755 0 0 1 15 5.293V4.5A1.5 1.5 0 0 0 13.5 3h-11Z" />
<path d="M15 6.954 8.978 9.86a2.25 2.25 0 0 1-1.956 0L1 6.954V11.5A1.5 1.5 0 0 0 2.5 13h11a1.5 1.5 0 0 0 1.5-1.5V6.954Z" />
</svg>
}
/>

<div className="pt-5">
<FormSubmitButtons loading={loading} title="Send Email" />
</div>
</div>
</form>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/auth/oauthLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const OauthLogin: React.FC = () => {
type="button"
onClick={oAuthHandler}
className={cn(
"btn btn-block btn-primary cursor-pointer rounded-full font-semibold tracking-wide shadow-lg",
"btn btn-block btn-primary cursor-pointer font-semibold tracking-wide shadow-lg",
)}
>
{loading ? <span className="loading loading-spinner"></span> : null}
Expand Down
Loading

0 comments on commit 130a40d

Please sign in to comment.