mirror of
https://github.com/hex248/ob248.com.git
synced 2026-02-07 18:23:04 +00:00
added age
This commit is contained in:
15
src/App.tsx
15
src/App.tsx
@@ -1,11 +1,17 @@
|
|||||||
import { Downasaur, Home as HomeIcon } from "@nsmr/pixelart-react";
|
import {
|
||||||
|
Downasaur,
|
||||||
|
Github,
|
||||||
|
Home as HomeIcon,
|
||||||
|
Mail,
|
||||||
|
Notes,
|
||||||
|
} from "@nsmr/pixelart-react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Link, Route, Routes, useParams } from "react-router-dom";
|
import { Link, Route, Routes, useParams } from "react-router-dom";
|
||||||
import { AskAI } from "@/components/ask-ai";
|
import { AskAI } from "@/components/ask-ai";
|
||||||
import { ProjectListItem } from "@/components/ProjectListItem";
|
import { ProjectListItem } from "@/components/ProjectListItem";
|
||||||
|
import { TimeSince } from "@/components/time-since";
|
||||||
import { type ProjectEntry, projectList, projects } from "@/projects";
|
import { type ProjectEntry, projectList, projects } from "@/projects";
|
||||||
import { ThemeToggle } from "./components/theme-toggle";
|
import { ThemeToggle } from "./components/theme-toggle";
|
||||||
import { Github, Mail, Notes } from "@nsmr/pixelart-react";
|
|
||||||
|
|
||||||
const asciiFiles = [
|
const asciiFiles = [
|
||||||
"cat-sleep.txt",
|
"cat-sleep.txt",
|
||||||
@@ -57,7 +63,7 @@ function Home() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-dvh flex flex-col items-center gap-2 text-2xl px-6 py-10">
|
<div className="min-h-dvh flex flex-col items-center gap-2 text-2xl px-6 py-10">
|
||||||
<div className="flex flex-col items-center gap-8 mb-4">
|
<div className="flex flex-col items-center gap-4 mb-4">
|
||||||
{asciiArt ? (
|
{asciiArt ? (
|
||||||
<pre className="text-[#000000] dark:text-[#ffffff] leading-1.75 tracking-[-1.75px]">
|
<pre className="text-[#000000] dark:text-[#ffffff] leading-1.75 tracking-[-1.75px]">
|
||||||
<code className="commitmono text-[11px]">{asciiArt}</code>
|
<code className="commitmono text-[11px]">{asciiArt}</code>
|
||||||
@@ -92,6 +98,9 @@ function Home() {
|
|||||||
<Notes className="size-6" /> CV
|
<Notes className="size-6" /> CV
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-base text-fg">
|
||||||
|
Age: <TimeSince date={new Date(2004, 10, 4, 11, 47, 0)} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full max-w-5xl grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="w-full max-w-5xl grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
{sortedProjects.map((project) => (
|
{sortedProjects.map((project) => (
|
||||||
|
|||||||
44
src/components/time-since.tsx
Normal file
44
src/components/time-since.tsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
type TimeSinceProps = {
|
||||||
|
date: Date;
|
||||||
|
className?: string;
|
||||||
|
yearsDp?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const yearMs = 1000 * 60 * 60 * 24 * 365.25;
|
||||||
|
|
||||||
|
function roundToDp(value: number, dp: number) {
|
||||||
|
const factor = 10 ** dp;
|
||||||
|
return Math.floor(value * factor) / factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TimeSince({ date, className, yearsDp = 2 }: TimeSinceProps) {
|
||||||
|
const dateMs = useMemo(() => date.getTime(), [date]);
|
||||||
|
const [milliseconds, setMilliseconds] = useState(() =>
|
||||||
|
Math.max(0, Date.now() - dateMs),
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let rafId: number | null = null;
|
||||||
|
|
||||||
|
const tick = () => {
|
||||||
|
setMilliseconds(Math.max(0, Date.now() - dateMs));
|
||||||
|
rafId = requestAnimationFrame(tick);
|
||||||
|
};
|
||||||
|
|
||||||
|
rafId = requestAnimationFrame(tick);
|
||||||
|
return () => {
|
||||||
|
if (rafId !== null) cancelAnimationFrame(rafId);
|
||||||
|
};
|
||||||
|
}, [dateMs]);
|
||||||
|
|
||||||
|
const years = roundToDp(milliseconds / yearMs, yearsDp);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className={cn("tabular-nums text-fg", className)}>
|
||||||
|
{years}y or {milliseconds}ms
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user