144 lines
No EOL
5.3 KiB
TypeScript
144 lines
No EOL
5.3 KiB
TypeScript
import { useEffect, useState } from 'preact/hooks';
|
|
|
|
type EntryBody = {
|
|
err: boolean;
|
|
referral: string;
|
|
key: string;
|
|
}
|
|
|
|
export const Home = () => {
|
|
const [referral, setReferral] = useState('');
|
|
const [entryBody, setEntryBody] = useState<EntryBody | null>({
|
|
err: true,
|
|
referral: '',
|
|
key: ''
|
|
});
|
|
|
|
const [timeLeft, setTimeLeft] = useState<string>('...');
|
|
|
|
useEffect(() => {
|
|
console.log('Referral:', referral);
|
|
}, [referral]);
|
|
|
|
const entry = async () => {
|
|
let res = await fetch("http://localhost:8080/entry", {
|
|
method: 'GET',
|
|
headers: { referral }
|
|
})
|
|
|
|
if (!res.ok) {
|
|
console.error('Error:', res.status);
|
|
return
|
|
}
|
|
|
|
let body: EntryBody = await res.json();
|
|
|
|
if (body.err) {
|
|
console.error('Error:', body.referral);
|
|
window.location.href = '/error';
|
|
|
|
return
|
|
}
|
|
|
|
console.log('Entry:', body);
|
|
|
|
setEntryBody(body);
|
|
|
|
setReferral('');
|
|
}
|
|
|
|
const eventDateCET = new Date('2025-01-01T00:00:00Z');
|
|
const userTime = new Intl.DateTimeFormat(undefined, {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
timeZoneName: 'short'
|
|
}).format(eventDateCET);
|
|
|
|
const getTimeLeft = (date: Date) => {
|
|
const now = new Date();
|
|
const diff = date.getTime() - now.getTime();
|
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
const hours = Math.floor(diff / (1000 * 60 * 60) % 24);
|
|
const minutes = Math.floor(diff / (1000 * 60) % 60);
|
|
const seconds = Math.floor(diff / 1000 % 60);
|
|
|
|
let s = "";
|
|
if (days > 0) s += days + "d ";
|
|
if (hours > 0) s += hours + "h ";
|
|
if (minutes > 0) s += minutes + "m ";
|
|
if (seconds > 0) s += seconds + "s";
|
|
|
|
if (s === "") s = "the time is upon us.";
|
|
else s += " remaining.";
|
|
return s;
|
|
}
|
|
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
setTimeLeft(getTimeLeft(eventDateCET));
|
|
}, 1000);
|
|
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
return (
|
|
<div class="flex flex-col gap-6 w-full h-full justify-center items-center">
|
|
<h1 class="text-6xl font-bold animate-pulse">???</h1>
|
|
<p>{timeLeft}</p>
|
|
|
|
<span>
|
|
<p class="opacity-100 hover:opacity-75 transition-opacity">
|
|
Referral:
|
|
</p>
|
|
|
|
|
|
<div class="flex gap-2">
|
|
<input
|
|
type="text"
|
|
value={referral}
|
|
onInput={(e) => setReferral(e.currentTarget.value)}
|
|
|
|
class="bg-black text-green-500 border-green-500 border-2 px-2 hover:bg-green-500 hover:text-black active:bg-green-500 active:text-black transition-colors"
|
|
/>
|
|
|
|
<button
|
|
onClick={async () => await entry()}
|
|
class="bg-green-500 text-black hover:bg-black hover:text-green-500 transition-colors px-4"
|
|
>
|
|
Submit
|
|
</button>
|
|
</div>
|
|
</span>
|
|
|
|
{
|
|
!entryBody.err ? (
|
|
<div class="flex flex-col gap-1.5 mt-3 justify-center items-center">
|
|
<p class="text-green-700">tip: click to copy.</p>
|
|
<h2 onClick={() => navigator.clipboard.writeText(entryBody?.key)}>Key: <code class="cursor-pointer bg-green-800 hover:bg-green-900 active:bg-green-700 transition-colors py-1 px-2 rounded-lg text-white">{entryBody?.key}</code></h2>
|
|
<h2 onClick={() => navigator.clipboard.writeText(entryBody?.referral)}>Referral: <code class="cursor-pointer bg-green-800 hover:bg-green-900 active:bg-green-700 transition-colors py-1 px-2 rounded-lg text-white">{entryBody?.referral}</code></h2>
|
|
<p class="text-green-700">good luck. keep note of these, if you lose them, you can't reroll.</p>
|
|
</div>
|
|
) : (
|
|
<div class="w-2/3 text-center flex flex-col gap-2">
|
|
<div>
|
|
<b>What is this?</b>
|
|
<p>At exactly {userTime} (00:00 CET on 1 Jan), the system will choose a random entry. Their referral key shall be publicly
|
|
displayed on this page. The person associated with this referral key shall contact us with their private key.
|
|
They shall win a little prize. To have one's entry weigh more than the rest, one shall have to spread their
|
|
referral key amongst people. Every referral shall increase their chance of getting selected.
|
|
</p>
|
|
</div>
|
|
|
|
<div>
|
|
<b>How does one enter?</b>
|
|
<p>One needs a referral key to enter.</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
)
|
|
}; |