Implemented cryptomining, although its extremely bad optimized.
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { motion, Easing } from 'framer-motion';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Terminal, Server, Cpu, Zap, Pickaxe } from 'lucide-react';
|
||||
import TypingText from '@/components/TypingText';
|
||||
import { useSettings } from '@/contexts/SettingsContext';
|
||||
|
||||
const getStatusForAmsterdamTime = () => {
|
||||
// Get current time in Amsterdam
|
||||
const now = new Date();
|
||||
const amsterdamTime = new Date(now.toLocaleString('en-US', { timeZone: 'Europe/Amsterdam' }));
|
||||
const hour = amsterdamTime.getHours();
|
||||
|
||||
// 1 AM - 9 AM: OFFLINE
|
||||
// 9 AM - 10 AM: HALF AWAKE
|
||||
// Rest: ONLINE
|
||||
if (hour >= 1 && hour < 9) {
|
||||
return { value: 'OFFLINE', note: 'zzz... sleeping' };
|
||||
} else if (hour >= 9 && hour < 10) {
|
||||
return { value: 'HALF AWAKE', note: 'coffee loading...' };
|
||||
} else {
|
||||
return { value: 'ONLINE', note: undefined };
|
||||
}
|
||||
};
|
||||
|
||||
const Home = () => {
|
||||
const [typingComplete, setTypingComplete] = useState(false);
|
||||
const [status, setStatus] = useState(getStatusForAmsterdamTime);
|
||||
const { playSound, cryptoConsent, hashrate, totalHashes, acceptedHashes } = useSettings();
|
||||
|
||||
useEffect(() => {
|
||||
// Update status every minute
|
||||
const interval = setInterval(() => {
|
||||
setStatus(getStatusForAmsterdamTime());
|
||||
}, 60000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const statVariants = {
|
||||
hidden: { opacity: 0, x: -10 },
|
||||
visible: (i: number) => ({
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
transition: {
|
||||
delay: 2 + i * 0.15,
|
||||
duration: 0.3,
|
||||
ease: [0.4, 0, 0.2, 1] as Easing,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const stats: Array<{ icon: typeof Terminal; label: string; value: React.ReactNode; valueEnd?: string; note?: string }> = [
|
||||
{ icon: Terminal, label: 'STATUS', value: status.value, note: status.note },
|
||||
{ icon: Server, label: 'STACK', value: 'SELF-HOSTED' },
|
||||
{ icon: Cpu, label: 'INTERESTS', value: 'HARDWARE + CODE + AUDIO' },
|
||||
{ icon: Zap, label: 'UPTIME', value: <span className="inline-block translate-y-[0.35em]">~</span>, valueEnd: '67%', note: 'humans need sleep' },
|
||||
];
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="space-y-6"
|
||||
>
|
||||
{/* Terminal-style intro */}
|
||||
<div className="space-y-2">
|
||||
<p className="font-pixel text-sm text-muted-foreground">
|
||||
<TypingText text="root@severijnse:~$" speed={50} />
|
||||
</p>
|
||||
<h1 className="font-minecraft text-2xl md:text-3xl text-primary text-glow-strong">
|
||||
<TypingText
|
||||
text="cat welcome.txt"
|
||||
speed={60}
|
||||
delay={600}
|
||||
onComplete={() => setTypingComplete(true)}
|
||||
/>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Welcome message */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: typingComplete ? 1 : 0 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="border-l-2 border-primary/50 pl-4 space-y-3"
|
||||
>
|
||||
<p className="font-pixel text-lg text-foreground/90 leading-relaxed">
|
||||
<TypingText
|
||||
text="Hey, I'm Jory."
|
||||
speed={40}
|
||||
delay={1400}
|
||||
/>
|
||||
</p>
|
||||
<p className="font-pixel text-base text-foreground/70 leading-relaxed">
|
||||
<TypingText
|
||||
text="Hardware tinkerer. Self-hosting enthusiast. Building things that work."
|
||||
speed={25}
|
||||
delay={1800}
|
||||
/>
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Quick stats */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ delay: 2.5, duration: 0.5 }}
|
||||
className="grid grid-cols-2 gap-3 mt-6"
|
||||
>
|
||||
{stats.map((stat, i) => (
|
||||
<motion.div
|
||||
key={stat.label}
|
||||
custom={i}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
variants={statVariants}
|
||||
onHoverStart={() => playSound('hover')}
|
||||
className="p-3 border border-primary/20 hover:border-primary/50 bg-background/30 transition-all duration-200"
|
||||
>
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<stat.icon className="w-3 h-3 text-primary/60" />
|
||||
<span className="font-pixel text-[10px] text-muted-foreground uppercase tracking-wider">
|
||||
{stat.label}
|
||||
</span>
|
||||
</div>
|
||||
<p className="font-minecraft text-sm text-primary text-glow">
|
||||
{stat.value}{stat.valueEnd}
|
||||
</p>
|
||||
{stat.note && (
|
||||
<p className="font-pixel text-[8px] text-muted-foreground mt-0.5">
|
||||
{stat.note}
|
||||
</p>
|
||||
)}
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* Miner Stats */}
|
||||
{cryptoConsent && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.2 }}
|
||||
className="mt-6"
|
||||
>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<Pickaxe className="w-4 h-4 text-primary/60" />
|
||||
<h2 className="font-pixel text-sm text-muted-foreground uppercase tracking-wider">Miner Statistics</h2>
|
||||
</div>
|
||||
<div className="p-3 border border-primary/20 bg-background/30">
|
||||
<ul className="font-pixel text-sm text-foreground/90 space-y-1">
|
||||
<li><b>Current hash rate: </b><span id="rate">{hashrate.toFixed(1)} H/s</span></li>
|
||||
<li><b>Total hashes: </b><span id="total">{totalHashes}</span></li>
|
||||
<li><b>Accepted hashes: </b><span id="accepted">{acceptedHashes}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* Navigation hint */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 3.2, duration: 0.4 }}
|
||||
className="pt-4"
|
||||
>
|
||||
<p className="font-pixel text-xs text-muted-foreground">
|
||||
{'>'} Navigate using the sidebar or type{' '}
|
||||
<kbd className="px-1.5 py-0.5 bg-primary/10 border border-primary/30 text-primary font-minecraft text-xs">
|
||||
/
|
||||
</kbd>{' '}
|
||||
for commands
|
||||
</p>
|
||||
<div className="flex gap-3 mt-3">
|
||||
<Link
|
||||
to="/about"
|
||||
onClick={() => playSound('click')}
|
||||
className="font-pixel text-xs text-primary hover:text-glow underline underline-offset-2"
|
||||
>
|
||||
about me
|
||||
</Link>
|
||||
<Link
|
||||
to="/projects"
|
||||
onClick={() => playSound('click')}
|
||||
className="font-pixel text-xs text-primary hover:text-glow underline underline-offset-2"
|
||||
>
|
||||
projects
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
Reference in New Issue
Block a user