Merge branch 'master' of ssh://host.jeynes.uk:222/jill/UXHack26

This commit is contained in:
William Jeynes
2026-06-23 12:42:41 +01:00
10 changed files with 2870 additions and 960 deletions
+319
View File
@@ -0,0 +1,319 @@
"use client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { InputWrapper } from "@/components/ui/input_wrapper";
import Section from "@/components/ui/section";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue
} from "@/components/ui/select";
import { Spinner } from "@/components/ui/spinner";
import { getRandomThirdPartyCount, getRandomUsername } from "@/lib/utils";
import { useState } from "react";
import { useTranslation } from "react-i18next";
export default function Apply() {
const { t } = useTranslation("common");
const [password, setPassword] = useState("");
const [email, setEmail] = useState("");
const [email2, setEmail2] = useState("");
const [email3, setEmail3] = useState("");
const [hours, setHours] = useState("");
const [experience, setExperience] = useState("");
const [graduationYear, setGraduationYear] = useState("");
const [digitOfPi, setDigitOfPi] = useState("");
const [submitSpinner, setSubmitSpinner] = useState(false);
const isValidPassword = password.length >= 8;
return (
<div className="flex flex-col items-center min-h-screen gap-6 mt-8 mb-8">
<h1 className="text-3xl mb-3">{t("application.title")}</h1>
<form className="flex flex-col gap-10">
<Section>
<div>
<p className="text-lg">
{t("application.personal.sectionTitle")}
</p>
<p className="text-md text-gray-700">
{t("application.personal.description", {
count: getRandomThirdPartyCount()
})}
</p>
</div>
<InputWrapper name={t("application.personal.name.label")}>
<Input
type="text"
placeholder={t("application.personal.name.firstName")}
/>
<Input
type="text"
placeholder={t("application.personal.name.lastName")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.email.label")}>
<Input
type="email"
placeholder={t("application.personal.email.label")}
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</InputWrapper>
<InputWrapper
name={t("application.personal.email.confirm")}
error={email !== email2 ? t("application.personal.email.error") : ""}
>
<Input
type="email"
placeholder={t("application.personal.email.label")}
value={email2}
onChange={(e) => setEmail2(e.target.value)}
/>
</InputWrapper>
{email === email2 && email !== "" ? (
<InputWrapper
name={t("application.personal.email.tripleCheck")}
error={
email !== email2 || email !== email3
? t("application.personal.email.error")
: ""
}
>
<Input
type="email"
placeholder={t("application.personal.email.label")}
value={email3}
onChange={(e) => setEmail3(e.target.value)}
/>
</InputWrapper>
) : null}
<InputWrapper name={t("application.personal.phone")}>
<Input
type="tel"
placeholder={t("application.personal.phone")}
/>
</InputWrapper>
<InputWrapper
name={t("application.personal.password.label")}
error={
isValidPassword
? t("application.personal.password.error", {
username: getRandomUsername()
})
: ""
}
>
<Input
type="password"
placeholder={t("application.personal.password.label")}
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.bank.label")}>
<Input
type="text"
placeholder={t("application.personal.bank.cardNumber")}
/>
<Input
type="text"
placeholder={t("application.personal.bank.expiry")}
/>
<Input
type="text"
placeholder={t("application.personal.bank.cvv")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.discord")}>
<Input
type="text"
placeholder={t("application.personal.discord")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.address")}>
<Input
type="text"
placeholder={t("application.personal.address")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.dob")}>
<Input
type="date"
placeholder={t("application.personal.dob")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.pets")}>
<Input
type="textarea"
placeholder={t("application.personal.pets")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.color")}>
<Input
type="color"
placeholder={t("application.personal.color")}
/>
</InputWrapper>
<InputWrapper name={t("application.personal.vote.label")}>
<Select>
<SelectTrigger className="w-full max-w-48 override">
<SelectValue
placeholder={t("application.personal.vote.placeholder")}
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
{t("application.personal.vote.placeholder")}
</SelectLabel>
<SelectItem value="capitalists">
{t("application.personal.vote.options.capitalists")}
</SelectItem>
<SelectItem value="communists">
{t("application.personal.vote.options.communists")}
</SelectItem>
<SelectItem value="centrists">
{t("application.personal.vote.options.centrists")}
</SelectItem>
<SelectItem value="greens">
{t("application.personal.vote.options.greens")}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</InputWrapper>
<InputWrapper
name={t("application.personal.gamingHours.label")}
error={
Number(hours) < 1
? ""
: t("application.personal.gamingHours.error")
}
>
<Input
type="text"
placeholder={t("application.personal.gamingHours.label")}
value={hours}
onChange={(e) => setHours(e.target.value)}
/>
</InputWrapper>
</Section>
<Section>
<p className="text-lg">
{t("application.education.sectionTitle")}
</p>
<p className="text-md">
{t("application.education.description")}
</p>
<InputWrapper
name={t("application.education.university.label")}
description={t("application.education.university.description")}
>
<div>
<input id="cambridge" name="university" type="radio" value="Cambridge" />
<label htmlFor="cambridge">
{t("application.education.university.options.cambridge")}
</label>
</div>
<div>
<input id="oxford" name="university" type="radio" value="Oxford" />
<label htmlFor="oxford">
{t("application.education.university.options.oxford")}
</label>
</div>
<div>
<input id="tau" name="university" type="radio" value="TAU" />
<label htmlFor="tau">
{t("application.education.university.options.tau")}
</label>
</div>
</InputWrapper>
<InputWrapper
name={t("application.education.experience.label")}
error={
Number(experience) >= 30 || experience == ""
? ""
: t("application.education.experience.error")
}
>
<Input
type="number"
placeholder={t("application.education.experience.label")}
value={experience}
onChange={(e) => setExperience(e.target.value)}
/>
</InputWrapper>
<InputWrapper
name={t("application.education.graduationYear.label")}
error={
Number(graduationYear) < 2025 && graduationYear != ""
? t("application.education.graduationYear.error")
: ""
}
>
<Input
type="number"
placeholder={t("application.education.graduationYear.label")}
value={graduationYear}
onChange={(e) => setGraduationYear(e.target.value)}
/>
</InputWrapper>
</Section>
<Section>
<p className="text-lg">
{t("application.additional.sectionTitle")}
</p>
<InputWrapper
name={t("application.additional.piQuestion.label")}
description={
digitOfPi == "8"
? t("application.additional.piQuestion.correct")
: ""
}
>
<Input
type="number"
placeholder={t("application.additional.piQuestion.label")}
value={digitOfPi}
onChange={(e) => setDigitOfPi(e.target.value)}
/>
</InputWrapper>
</Section>
<Button type="submit" className="self-center text-4xl p-6">
<a href="#submitted" onClick={() => setSubmitSpinner(true)}>t("application.submit.button")</a>
{submitSpinner && <Spinner data-icon="inline-start" />}
</Button>
</form>
</div>
);
}