This commit is contained in:
grngxd 2024-12-26 11:00:16 +00:00
parent 552c412c17
commit bf1881ccb5
13 changed files with 551 additions and 148 deletions

View file

@ -1,107 +1,144 @@
import { useEffect, useState } from 'preact/hooks';
type EntryBody = {
err: boolean;
referral: string;
key: string;
err: boolean;
referral: string;
key: string;
}
export const Home = () => {
const [referral, setReferral] = useState('');
const [entryBody, setEntryBody] = useState<EntryBody | null>({
err: true,
referral: '',
key: ''
});
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(() => {
console.log('Referral:', referral);
}, [referral]);
const interval = setInterval(() => {
setTimeLeft(getTimeLeft(eventDateCET));
}, 1000);
const entry = async () => {
let res = await fetch("http://localhost:8080/entry", {
method: 'GET',
headers: { referral }
})
if (!res.ok) {
console.error('Error:', res.status);
return
}
return () => clearInterval(interval);
}, []);
let body: EntryBody = await res.json();
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)}
if (body.err) {
console.error('Error:', body.referral);
window.location.href = '/error';
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"
/>
return
}
<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>
console.log('Entry:', body);
setEntryBody(body);
{
!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>
setReferral('');
}
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>time left here</p>
<div class="flex flex-col justify-center items-center gap-4">
<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 00:00 CET on 1 Jan, the system will choose a random entry. Their referral key shall be publically
displayed on this page. The person associated to 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 the 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>
<div>
<b>How does one enter?</b>
<p>One needs a referral key to enter.</p>
</div>
</div>
)
}
</div>
)
)
};

View file

@ -1,10 +1,14 @@
import preact from '@preact/preset-vite';
import { defineConfig } from 'vite';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [preact()],
server: {
cors: true
}
});
base: '/public',
plugins: [preact()],
server: {
cors: true
},
build: {
outDir: '../public',
emptyOutDir: true
}
});