Skip to content

Commit

Permalink
confirm-email page design
Browse files Browse the repository at this point in the history
  • Loading branch information
Anas-github-acc committed Jul 22, 2024
1 parent 17b52f4 commit 58621aa
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 10 deletions.
1 change: 1 addition & 0 deletions public/auth/confirm_email_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
152 changes: 147 additions & 5 deletions src/app/auth/confirm_email/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,153 @@
import React from 'react';
'use client';
import React, { useState, useEffect, use } from 'react';
import Link from 'next/link';
import { Button } from '@/components/ui/button';
import { useSearchParams } from 'next/navigation';
import { supabase } from '@/utils/supabase/client';

import Image from 'next/image';

export default function Confirm() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [countdown, setCountdown] = useState(10);

const searchParams = useSearchParams();
const email = searchParams.get('email') || 'xxxx-xxxx-xxxx-xxxx';

if(!validateEmail(email)) {
return (
<div className="flex justify-center flex-row items-center mt-10">
<XIcon className="w-24 h-24" />
<h2 className="text-center text-3xl font-bold tracking-tight text-primary">
Invalid email address:
</h2>
<h2 className="text-center text-3xl font-bold tracking-tight text-primary pl-2">
<a href="mailto:{{email}}" className="text-primary underline">{email}</a>
</h2>
</div>
);
}

useEffect(() => {
const timer = setTimeout(() => {
setError('The email confirmation link has expired. Please sign up again to receive a new confirmation email.');
}, 1000 * 60 * 60 );
return () => clearTimeout(timer);
}, []);

useEffect(() => {
if (loading) {
const timer = setTimeout(() => {
setCountdown((prev) => prev - 1);
if (countdown === 0) {
setLoading(false);
setCountdown(10);
}
}, 1000);
}
}, [loading, countdown]);

const resent = async () => {
setLoading(true)
const { error } = await supabase.auth.resend({
type: 'signup',
email: email,
options: {
emailRedirectTo: '/auth/confirm_email?email=' + email,
}
})
if (error) {
setError(error.message)
}
}

return (
<div className="flex justify-center mt-10">
<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-primary">
Check your inbox for a confirmation email
</h2>
<div className="flex min-h-[100dvh] lg:flex-row flex-col bg-background">
<div className="lg:h-[100vh] h-[50vh] w-[100vw] flex flex-col items-center justify-center px-4 py-12 sm:px-6 lg:px-8 lg:scale-125">
<div className="mx-auto max-w-md text-center">
<CircleCheckIcon className="mx-auto h-12 w-12 text-primary" />
<h1 className="mt-4 text-3xl font-bold tracking-tight text-foreground sm:text-4xl">Email Sent!</h1>
<div className="mx-auto max-w-md text-center">
<p className="mt-4 text-muted-foreground">
We've sent a confirmation email to <span className="font-medium">{email}</span>. Click the link in
the email to verify your account.
</p>
<div className="mt-6 flex flex-col items-center lg:justify-end justify-center gap-4 sm:flex-row">
<Button
onClick={resent}
disabled={loading}
className="inline-flex items-center rounded-md bg-primary px-5 py-6 text-sm font-medium text-primary-foreground shadow-sm transition-colors hover:bg-primary focus:outline-none disabled:pointer-events-none disabled:opacity-50"
>
Resend Email
</Button>
<Link
href="/"
className="inline-flex items-center rounded-md border border-input bg-background px-5 py-3 text-sm font-medium text-muted-foreground shadow-sm transition-colors hover:bg-muted hover:text-muted-foreground focus:outline-none"
prefetch={false}
>
Return to Home
</Link>
</div>
<div className="mt-4 text-muted-foreground">
{loading && <p className="text-muted-foreground">Resending email in {countdown} seconds...</p>}
</div>
<div className="mt-4 text-muted-foreground">
{error && <p className="text-red-500">{error}</p>}
</div>
</div>
</div>
</div>
<div className="lg:h-[100vh] h-[50vh] w-[100vw] flex flex-col items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
<Image src="/auth/confirm_email_logo.svg" alt="Confirm Email" className="lg:w-[400px] lg:h-[400px] w-[300px] h-[300px]" width={300} height={300} />
</div>
</div>
);
}


const validateEmail = (email: string) => {
const re = /\S+@\S+\.\S+/;
return re.test(email);
}

function CircleCheckIcon(props: React.JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="10" />
<path d="m9 12 2 2 4-4" />
</svg>
)
}


function XIcon(props: React.JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M18 6 6 18" />
<path d="m6 6 12 12" />
</svg>
)
}
2 changes: 1 addition & 1 deletion src/app/auth/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default function Auth(){
setError(error);
return false;
} else {
router.push('/auth/confirm_email');
router.push('/auth/confirm_email?email=' + email);
}
}
const Authsignin = async () => {
Expand Down
6 changes: 3 additions & 3 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@
}

.dark {
--background: #0d020a;
--background: #201F31;
--foreground: #fcfdff;
--card: #0d020a;
--card-foreground: #fcfdff;
--popover: #0d020a;
--popover-foreground: #fcfdff;
--primary: #fcfdff;
--primary: #ffbade;
--primary-foreground: #1c2230;
--secondary: #2a2f3d;
--secondary-foreground: #fcfdff;
--muted: #2a2f3d;
--muted-foreground: #a4a9b5;
--accent: #2a2f3d;
--accent-foreground: #fcfdff;
--destructive: #4d0019;
--destructive: #e60000;
--destructive-foreground: #fcfdff;
--border: #2a2f3d;
--input: #2a2f3d;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/supabase/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export async function updateSession(request: NextRequest) {
const { data: {user}} = await supabase.auth.getUser()
if (user && !user?.confirmed_at && request.nextUrl.pathname === '/form_create') {
response = NextResponse.redirect(new URL('/auth/confirm_email', request.nextUrl.href))
} else if (user && user?.confirmed_at && request.nextUrl.pathname === '/auth/confirm_email') {
} else if (user?.confirmed_at && request.nextUrl.pathname === '/auth/confirm_email') {
response = NextResponse.redirect(new URL('/form_create', request.nextUrl.href))
} else if (user && request.nextUrl.pathname === '/auth') {
response = NextResponse.redirect(new URL('/form_create', request.nextUrl.href))
Expand Down

0 comments on commit 58621aa

Please sign in to comment.