136 lines
3.9 KiB
TypeScript
136 lines
3.9 KiB
TypeScript
import React from 'react';
|
|
import {useSpring, animated} from '@react-spring/web';
|
|
|
|
import LoginForm from './LoginForm';
|
|
import ScoreCounter from './ScoreCounter';
|
|
import Icon from './Icon';
|
|
|
|
import { useJSONLocalStorage, useLocalStorage } from './hooks/useLocalStorage';
|
|
import {toot, starman, flush, getCheer} from './sound';
|
|
|
|
import './App.css';
|
|
|
|
|
|
const COLUMNS = [1,2,3,4,5,6,7,8,9,10];
|
|
|
|
interface Stats {
|
|
attempts: number;
|
|
scheduledPoops: number;
|
|
selfPoops: number;
|
|
cleanUndies: number;
|
|
streaks: number[];
|
|
currentStreakSince: number;
|
|
};
|
|
|
|
const initialStats:Stats = {
|
|
attempts: 1,
|
|
scheduledPoops: 1,
|
|
selfPoops: 1,
|
|
cleanUndies: 1,
|
|
streaks: [0,0,0,0],
|
|
currentStreakSince: Date.now()
|
|
};
|
|
|
|
function App() {
|
|
|
|
const [stats, setStats] = useJSONLocalStorage<Stats>("stats", initialStats);
|
|
const [name] = useLocalStorage<string>("name", {});
|
|
const [password] = useLocalStorage<string>("password", {});
|
|
const { attempts, scheduledPoops, selfPoops, cleanUndies, streaks, currentStreakSince } = stats;
|
|
|
|
return !name || !password ? <LoginForm /> :(
|
|
<div className="App">
|
|
<div className="header">
|
|
<div className="name-plate">Hello Pax!</div>
|
|
<div className="score-board">
|
|
Points: <ScoreCounter stats={stats}/>
|
|
</div>
|
|
</div>
|
|
<div className="row attempt" onClick={() => {
|
|
setStats({...stats, attempts: attempts + 1 });
|
|
flush.play();
|
|
setTimeout(() => getCheer().play(), 1800)
|
|
}}>
|
|
{COLUMNS.map(i =>
|
|
i <= attempts ?
|
|
<Icon key={i} emoji="🚽" className="attempt" />
|
|
: <div key={i} className="attempt cell"/>
|
|
)}
|
|
<div
|
|
className="delete cell checked"
|
|
onClick={e => {
|
|
e.stopPropagation();
|
|
setStats({...stats, attempts: Math.max(0, attempts - 1)});
|
|
console.log("BLARG");
|
|
}}
|
|
>
|
|
🚫
|
|
</div>
|
|
</div>
|
|
<div className="row scheduled-poops" onClick={() => {
|
|
setStats({...stats, scheduledPoops: scheduledPoops + 1 });
|
|
toot.play();
|
|
setTimeout(() => getCheer().play(), 1800)
|
|
}}>
|
|
{COLUMNS.map(i =>
|
|
i <= scheduledPoops ?
|
|
<Icon key={i} emoji="💩" className="scheduled" />
|
|
: <div key={i} className="scheduled cell"/>
|
|
)}
|
|
<div
|
|
className="delete cell checked"
|
|
onClick={e => {
|
|
e.stopPropagation();
|
|
setStats({...stats, scheduledPoops: Math.max(0, scheduledPoops - 1)});
|
|
}}
|
|
>
|
|
🚫
|
|
</div>
|
|
</div>
|
|
<div className="row self-poops" onClick={() => {
|
|
setStats({...stats, selfPoops: selfPoops + 1 });
|
|
toot.play();
|
|
setTimeout(() => getCheer().play(), 1800)
|
|
}}>
|
|
{COLUMNS.map(i =>
|
|
i <= selfPoops ?
|
|
<Icon emoji="💩" className="self" />
|
|
: <div key={i} className="self cell"/>
|
|
)}
|
|
<div
|
|
className="delete cell checked"
|
|
onClick={e => {
|
|
e.stopPropagation();
|
|
setStats({...stats, selfPoops: Math.max(0, selfPoops - 1)});
|
|
}}
|
|
>
|
|
🚫
|
|
</div>
|
|
</div>
|
|
<div className="row clean-undies" onClick={() => {
|
|
setStats({...stats, cleanUndies: cleanUndies + 1 })
|
|
starman.play();
|
|
setTimeout(() => getCheer().play(), 1800)
|
|
}}>
|
|
{COLUMNS.map(i =>
|
|
i <= cleanUndies ?
|
|
<Icon emoji="🩲" className="clean-undies" />
|
|
: <div key={i} className="clean-undies cell"/>
|
|
)}
|
|
<div
|
|
className="delete cell checked"
|
|
onClick={e => {
|
|
e.stopPropagation();
|
|
setStats({...stats, cleanUndies: Math.max(0, cleanUndies - 1)});
|
|
}}
|
|
>
|
|
🚫
|
|
</div>
|
|
</div>
|
|
<div className="streak-counter"></div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default App;
|