done
This commit is contained in:
parent
552c412c17
commit
bf1881ccb5
13 changed files with 551 additions and 148 deletions
|
@ -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>
|
||||
)
|
||||
)
|
||||
};
|
|
@ -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
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue