Add invite page with invitation code validation
Some checks failed
Build and Push Docker Images / changes (push) Successful in 4s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Failing after 43s

This commit introduces a new invite page where users can input and validate their invitation codes. The page redirects valid users to the related event, and displays appropriate errors for invalid or failed submissions. It includes a responsive UI with loading states and error handling.
This commit is contained in:
2025-03-05 11:04:47 +01:00
parent c1cfc05a9e
commit 29e0ba2a70

View File

@@ -0,0 +1,118 @@
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import Navbar from "@/components/layout/navbar";
import { client } from "@/client/client.gen";
export default function InvitePage() {
const [invitationCode, setInvitationCode] = useState("");
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!invitationCode.trim()) {
setError("Please enter your invitation code");
return;
}
setIsLoading(true);
setError(null);
try {
// Assuming your API has an endpoint to validate invitation codes
const response = await client.get({
url: `/api/v1/guests/validate-code/${invitationCode}`,
throwOnError: true,
});
// If successful, redirect to the event page
const data: any = response.data;
router.push(`/events/${data.event_slug}?guest_id=${data.guest_id}`);
} catch (err: any) {
console.error("Error validating invitation code:", err);
if (err.response?.status === 404) {
setError("Invalid invitation code. Please check and try again.");
} else {
setError("An error occurred. Please try again later.");
}
} finally {
setIsLoading(false);
}
};
return (
<>
<Navbar />
<div className="min-h-screen bg-gradient-to-b from-blue-50 to-white dark:from-slate-900 dark:to-slate-800 py-12">
<div className="container mx-auto px-4">
<div className="max-w-md mx-auto">
<div className="text-center mb-8">
<h1 className="text-3xl font-bold text-slate-900 dark:text-white">
Enter Invitation Code
</h1>
<p className="mt-2 text-slate-600 dark:text-slate-300">
Please enter the invitation code you received
</p>
</div>
<div className="bg-white dark:bg-slate-800 rounded-lg shadow-md p-8">
{error && (
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 rounded-lg">
{error}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label
htmlFor="invitationCode"
className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"
>
Invitation Code
</label>
<input
id="invitationCode"
type="text"
value={invitationCode}
onChange={(e) => setInvitationCode(e.target.value)}
placeholder="Enter your code here"
className="w-full p-3 text-center text-lg tracking-wider uppercase border border-slate-300 dark:border-slate-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-slate-700 dark:text-white"
autoComplete="off"
autoFocus
maxLength={16}
/>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full py-3 px-4 bg-blue-600 text-white font-medium rounded-md shadow hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
>
{isLoading ? "Checking..." : "Continue to Event"}
</button>
</form>
<div className="mt-6 text-center">
<p className="text-sm text-slate-600 dark:text-slate-400">
Need to manage your events?{" "}
<Link
href="/login"
className="text-blue-600 dark:text-blue-400 font-medium hover:underline"
>
Sign in
</Link>
</p>
</div>
</div>
</div>
</div>
</div>
</>
);
}