fixes
This commit is contained in:
parent
d07a5bd9a8
commit
8c620abbe6
5 changed files with 147 additions and 97 deletions
|
|
@ -20,7 +20,6 @@ public class ParticipantRegistrationRequest
|
||||||
|
|
||||||
public string? PhoneNumber { get; set; }
|
public string? PhoneNumber { get; set; }
|
||||||
|
|
||||||
[EmailAddress]
|
|
||||||
public string? Email { get; set; }
|
public string? Email { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ interface EventContent {
|
||||||
rulesAndGdpr: string;
|
rulesAndGdpr: string;
|
||||||
additionalInfo: string;
|
additionalInfo: string;
|
||||||
registrationEnabled: boolean;
|
registrationEnabled: boolean;
|
||||||
|
volunteerRegistrationEnabled?: boolean;
|
||||||
visitorOnly: boolean;
|
visitorOnly: boolean;
|
||||||
volunteerAreas: string;
|
volunteerAreas: string;
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +129,19 @@ export default function AdminDashboard() {
|
||||||
Endast Besöks-registrering (Ingen Dator)
|
Endast Besöks-registrering (Ingen Dator)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="volunteerRegistrationEnabled"
|
||||||
|
name="volunteerRegistrationEnabled"
|
||||||
|
className="h-5 w-5 text-blue-600 focus:ring-blue-500 border-gray-300 rounded cursor-pointer"
|
||||||
|
checked={content.volunteerRegistrationEnabled ?? true}
|
||||||
|
onChange={(e) => setContent(prev => prev ? { ...prev, volunteerRegistrationEnabled: e.target.checked } : null)}
|
||||||
|
/>
|
||||||
|
<label htmlFor="volunteerRegistrationEnabled" className="ml-3 text-sm font-semibold text-gray-900 cursor-pointer">
|
||||||
|
Aktivera Funktionärs-anmälan
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ interface EventContent {
|
||||||
rulesAndGdpr: string;
|
rulesAndGdpr: string;
|
||||||
additionalInfo: string;
|
additionalInfo: string;
|
||||||
registrationEnabled: boolean;
|
registrationEnabled: boolean;
|
||||||
|
volunteerRegistrationEnabled?: boolean;
|
||||||
visitorOnly: boolean;
|
visitorOnly: boolean;
|
||||||
volunteerAreas: string;
|
volunteerAreas: string;
|
||||||
}
|
}
|
||||||
|
|
@ -73,98 +74,111 @@ export default function LandingPage() {
|
||||||
|
|
||||||
{/* Info Section */}
|
{/* Info Section */}
|
||||||
<main className="max-w-4xl mx-auto py-12 px-6 space-y-20">
|
<main className="max-w-4xl mx-auto py-12 px-6 space-y-20">
|
||||||
{(content.eventDate ||
|
{!content.registrationEnabled ? (
|
||||||
content.eventTime ||
|
<section className="flex flex-col items-center justify-center py-20 space-y-6">
|
||||||
content.locationName ||
|
<h2 className="text-4xl font-extrabold text-gray-900">Anmälan är stängd</h2>
|
||||||
content.locationAddress ||
|
<p className="text-xl text-gray-600 text-center max-w-lg">
|
||||||
content.additionalInfo) && (
|
Vi tar tyvärr inte emot fler anmälningar just nu. Håll utkik för framtida evenemang!
|
||||||
<section className="space-y-6">
|
|
||||||
<h2 className="text-3xl font-bold border-b-2 border-blue-500 pb-2 inline-block">
|
|
||||||
Information
|
|
||||||
</h2>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mt-6">
|
|
||||||
{(content.eventDate || content.eventTime) && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<h3 className="font-semibold text-lg text-blue-600">
|
|
||||||
Tid/Datum
|
|
||||||
</h3>
|
|
||||||
{content.eventDate && <p>{content.eventDate}</p>}
|
|
||||||
{content.eventTime && <p>{content.eventTime}</p>}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{(content.locationName || content.locationAddress) && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<h3 className="font-semibold text-lg text-blue-600">Plats</h3>
|
|
||||||
{content.locationName && <p>{content.locationName}</p>}
|
|
||||||
{content.locationAddress && <p>{content.locationAddress}</p>}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{content.additionalInfo && (
|
|
||||||
<div className="mt-8 text-lg text-gray-700 whitespace-pre-wrap leading-relaxed">
|
|
||||||
{content.additionalInfo}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{content.whatToBring && (
|
|
||||||
<section className="space-y-6">
|
|
||||||
<h2 className="text-3xl font-bold border-b-2 border-blue-500 pb-2 inline-block">
|
|
||||||
Ta Med(bokad LAN-plats)
|
|
||||||
</h2>
|
|
||||||
<ul className="list-disc list-inside space-y-3 text-lg text-gray-700">
|
|
||||||
{content.whatToBring
|
|
||||||
.split("\n")
|
|
||||||
.filter((line) => line.trim())
|
|
||||||
.map((line, i) => (
|
|
||||||
<li key={i}>{line}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{content.rulesAndGdpr && (
|
|
||||||
<section className="space-y-6">
|
|
||||||
<h2 className="text-3xl font-bold border-b-2 border-blue-500 pb-2 inline-block">
|
|
||||||
Regler för LAN & GDPR
|
|
||||||
</h2>
|
|
||||||
<p className="text-lg text-gray-700 leading-relaxed whitespace-pre-wrap">
|
|
||||||
{content.rulesAndGdpr}
|
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
)}
|
) : (
|
||||||
|
<>
|
||||||
|
{(content.eventDate ||
|
||||||
|
content.eventTime ||
|
||||||
|
content.locationName ||
|
||||||
|
content.locationAddress ||
|
||||||
|
content.additionalInfo) && (
|
||||||
|
<section className="space-y-6">
|
||||||
|
<h2 className="text-3xl font-bold border-b-2 border-blue-500 pb-2 inline-block">
|
||||||
|
Information
|
||||||
|
</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mt-6">
|
||||||
|
{(content.eventDate || content.eventTime) && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<h3 className="font-semibold text-lg text-blue-600">
|
||||||
|
Tid/Datum
|
||||||
|
</h3>
|
||||||
|
{content.eventDate && <p>{content.eventDate}</p>}
|
||||||
|
{content.eventTime && <p>{content.eventTime}</p>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(content.locationName || content.locationAddress) && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<h3 className="font-semibold text-lg text-blue-600">Plats</h3>
|
||||||
|
{content.locationName && <p>{content.locationName}</p>}
|
||||||
|
{content.locationAddress && <p>{content.locationAddress}</p>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{content.additionalInfo && (
|
||||||
|
<div className="mt-8 text-lg text-gray-700 whitespace-pre-wrap leading-relaxed">
|
||||||
|
{content.additionalInfo}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Call to Action */}
|
{content.whatToBring && (
|
||||||
{content.registrationEnabled && (
|
<section className="space-y-6">
|
||||||
<section className="flex flex-col items-center justify-center space-y-8 pt-12 border-t border-gray-100">
|
<h2 className="text-3xl font-bold border-b-2 border-blue-500 pb-2 inline-block">
|
||||||
<div className="text-center space-y-2">
|
Ta Med(bokad LAN-plats)
|
||||||
<h2 className="text-4xl font-bold">Vill du delta?</h2>
|
</h2>
|
||||||
<p className="text-gray-600 text-lg">
|
<ul className="list-disc list-inside space-y-3 text-lg text-gray-700">
|
||||||
Begränsade platser, Säkra din plats idag!
|
{content.whatToBring
|
||||||
</p>
|
.split("\n")
|
||||||
</div>
|
.filter((line) => line.trim())
|
||||||
<Link
|
.map((line, i) => (
|
||||||
href="/register"
|
<li key={i}>{line}</li>
|
||||||
className="bg-blue-600 hover:bg-blue-700 text-white text-xl font-bold py-4 px-12 rounded-full shadow-lg transform transition hover:scale-105 active:scale-95"
|
))}
|
||||||
>
|
</ul>
|
||||||
Anmäl dig nu
|
</section>
|
||||||
</Link>
|
)}
|
||||||
</section>
|
|
||||||
|
{content.rulesAndGdpr && (
|
||||||
|
<section className="space-y-6">
|
||||||
|
<h2 className="text-3xl font-bold border-b-2 border-blue-500 pb-2 inline-block">
|
||||||
|
Regler för LAN & GDPR
|
||||||
|
</h2>
|
||||||
|
<p className="text-lg text-gray-700 leading-relaxed whitespace-pre-wrap">
|
||||||
|
{content.rulesAndGdpr}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Call to Action */}
|
||||||
|
{content.registrationEnabled && (
|
||||||
|
<section className="flex flex-col items-center justify-center space-y-8 pt-12 border-t border-gray-100">
|
||||||
|
<div className="text-center space-y-2">
|
||||||
|
<h2 className="text-4xl font-bold">Vill du delta?</h2>
|
||||||
|
<p className="text-gray-600 text-lg">
|
||||||
|
Begränsade platser, Säkra din plats idag!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Link
|
||||||
|
href="/register"
|
||||||
|
className="bg-blue-600 hover:bg-blue-700 text-white text-xl font-bold py-4 px-12 rounded-full shadow-lg transform transition hover:scale-105 active:scale-95"
|
||||||
|
>
|
||||||
|
Anmäl dig nu
|
||||||
|
</Link>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<footer className="bg-gray-50 py-12 text-center text-gray-500 border-t border-gray-100 relative">
|
<footer className="bg-gray-50 py-12 text-center text-gray-500 border-t border-gray-100 relative">
|
||||||
<div className="mb-8">
|
{(content.volunteerRegistrationEnabled ?? true) && (
|
||||||
<p className="text-gray-600 mb-4">Vill du hjälpa till?</p>
|
<div className="mb-8">
|
||||||
<Link
|
<p className="text-gray-600 mb-4">Vill du hjälpa till?</p>
|
||||||
href="/volunteer"
|
<Link
|
||||||
className="inline-block bg-gray-800 hover:bg-black text-white font-bold py-2 px-6 rounded-md transition"
|
href="/volunteer"
|
||||||
>
|
className="inline-block bg-gray-800 hover:bg-black text-white font-bold py-2 px-6 rounded-md transition"
|
||||||
Bli Funktionär
|
>
|
||||||
</Link>
|
Bli Funktionär
|
||||||
</div>
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<p>© 2026 Vbytes Gaming. Alla rättigheter förbehållna.</p>
|
<p>© 2026 Vbytes Gaming. Alla rättigheter förbehållna.</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -169,10 +169,6 @@ export default function RegisterPage() {
|
||||||
"Vårdnadshavarens e-postadress är ogiltig.";
|
"Vårdnadshavarens e-postadress är ogiltig.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formData.email.trim() && !isValidEmail(formData.email.trim())) {
|
|
||||||
nextFieldErrors.email = "Din e-postadress är ogiltig.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!formData.hasApprovedGdpr) {
|
if (!formData.hasApprovedGdpr) {
|
||||||
nextFieldErrors.hasApprovedGdpr = "Du måste godkänna GDPR för att anmäla dig.";
|
nextFieldErrors.hasApprovedGdpr = "Du måste godkänna GDPR för att anmäla dig.";
|
||||||
}
|
}
|
||||||
|
|
@ -240,7 +236,9 @@ export default function RegisterPage() {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
setMessage({
|
setMessage({
|
||||||
type: "success",
|
type: "success",
|
||||||
text: "Registreringen är klar! Du är nu anmäld till LAN:et.",
|
text: isMember
|
||||||
|
? "Registreringen är klar! Du är nu anmäld till LAN:et."
|
||||||
|
: "Din anmälan är mottagen, men det återstår ett viktigt steg för att du ska få delta.",
|
||||||
});
|
});
|
||||||
setShowBecomeMemberCta(!isMember);
|
setShowBecomeMemberCta(!isMember);
|
||||||
|
|
||||||
|
|
@ -300,19 +298,22 @@ export default function RegisterPage() {
|
||||||
{message.type === "success" && (
|
{message.type === "success" && (
|
||||||
<div className="mb-8 space-y-6">
|
<div className="mb-8 space-y-6">
|
||||||
<div className="p-6 rounded-lg text-center bg-green-50 text-green-800 border border-green-200">
|
<div className="p-6 rounded-lg text-center bg-green-50 text-green-800 border border-green-200">
|
||||||
<div className="text-4xl mb-4">🎉</div>
|
<div className="text-4xl mb-4">{showBecomeMemberCta ? "⏳" : "🎉"}</div>
|
||||||
<h2 className="text-xl font-bold mb-2">Klart!</h2>
|
<h2 className="text-xl font-bold mb-2">
|
||||||
|
{showBecomeMemberCta ? "Nästan Klart!" : "Klart!"}
|
||||||
|
</h2>
|
||||||
<p>{message.text}</p>
|
<p>{message.text}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showBecomeMemberCta && (
|
{showBecomeMemberCta && (
|
||||||
<div className="bg-gray-50 p-6 rounded-lg border border-gray-200">
|
<div className="bg-gray-50 p-6 rounded-lg border border-orange-200">
|
||||||
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
||||||
Du är inte medlem än
|
Du är inte medlem än
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-gray-600 mb-4">
|
<p className="text-gray-600 mb-4">
|
||||||
Vi hittade dig inte i vårt medlemsregister. Genom att bli
|
Vi hittade dig inte i vårt medlemsregister. För att kunna
|
||||||
medlem i vBytes hjälper du oss att anordna fler och bättre
|
delta på LAN:et måste du vara medlem i vBytes. Medlemskapet är
|
||||||
|
gratis och hjälper oss dessutom att anordna fler och bättre
|
||||||
LAN!
|
LAN!
|
||||||
</p>
|
</p>
|
||||||
<a
|
<a
|
||||||
|
|
@ -470,7 +471,7 @@ export default function RegisterPage() {
|
||||||
E-post
|
E-post
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="text"
|
||||||
name="email"
|
name="email"
|
||||||
id="email"
|
id="email"
|
||||||
className={`mt-1 block w-full rounded-md shadow-sm sm:text-sm p-2 border text-gray-900 ${fieldErrors.email ? "border-red-500 focus:border-red-500 focus:ring-red-500" : "border-gray-300 focus:border-blue-500 focus:ring-blue-500"}`}
|
className={`mt-1 block w-full rounded-md shadow-sm sm:text-sm p-2 border text-gray-900 ${fieldErrors.email ? "border-red-500 focus:border-red-500 focus:ring-red-500" : "border-gray-300 focus:border-blue-500 focus:ring-blue-500"}`}
|
||||||
|
|
@ -659,7 +660,7 @@ export default function RegisterPage() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{message.text && (
|
{message.text && message.type !== "success" && (
|
||||||
<div
|
<div
|
||||||
className={`p-4 rounded-md ${
|
className={`p-4 rounded-md ${
|
||||||
message.type === "success"
|
message.type === "success"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
interface EventContent {
|
interface EventContent {
|
||||||
volunteerAreas: string;
|
volunteerAreas: string;
|
||||||
|
volunteerRegistrationEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isValidEmail = (value: string) =>
|
const isValidEmail = (value: string) =>
|
||||||
|
|
@ -42,6 +43,27 @@ export default function VolunteerPage() {
|
||||||
.then((data) => setContent(data))
|
.then((data) => setContent(data))
|
||||||
.catch((err) => console.error("Failed to fetch content", err));
|
.catch((err) => console.error("Failed to fetch content", err));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (content && content.volunteerRegistrationEnabled === false) {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex items-center justify-center bg-gray-50 px-4">
|
||||||
|
<div className="max-w-md w-full bg-white p-8 rounded-xl shadow-md text-center">
|
||||||
|
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
||||||
|
Anmälan är stängd
|
||||||
|
</h1>
|
||||||
|
<p className="text-gray-600 mb-6">
|
||||||
|
Vi tar tyvärr inte emot fler funktionärsanmälningar just nu.
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={() => router.push("/")}
|
||||||
|
className="text-blue-600 hover:underline"
|
||||||
|
>
|
||||||
|
Gå tillbaka till startsidan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value, type, checked } = e.target;
|
const { name, value, type, checked } = e.target;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue