Mobile-first Web-App fuer persoenliches Health-, Ernaehrungs-, Aktivitaets- und Einkaufs-Tracking im Home-Lab-Betrieb. Stack: pnpm Monorepo - Next.js 16 + React 19 + Tailwind (apps/admin) - Hono + tRPC + Better Auth mit 2FA und Passkeys (packages/api) - PostgreSQL + Drizzle ORM (packages/db) - Docker fuer Postgres und pgAdmin. Module: - Auth mit Login, 2FA (TOTP + Backup-Codes), Passkeys und Admin-Recovery - Tagesansicht mit Essen, Trinken, Gewicht, Aktivitaeten und Coach-Hinweisen - Lebensmittelkatalog mit Naehrwerten, Portionen, OCR/Barcode/Open Food Facts - Rezepte mit Live-Naehrwertberechnung und Community-Vorschlaegen - Essensplanung und Wochenbudget mit Sportbonus - Einkaufslisten mit Maerkten und Laufweg-Sortierung - Hellfireclub mit Aktivitaetspunkten und gemeinsamer Aktivitaetsplanung - Wearables-Vorbereitung (Fitbit / Google Fit / Health Connect) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
CalendarDaysIcon,
|
|
BellAlertIcon,
|
|
BoltIcon,
|
|
ChartBarIcon,
|
|
Cog6ToothIcon,
|
|
FireIcon,
|
|
SparklesIcon,
|
|
Squares2X2Icon,
|
|
} from "@heroicons/react/24/outline";
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
|
|
const items = [
|
|
{ href: "/", label: "Tag", icon: CalendarDaysIcon },
|
|
{ href: "/planung", label: "Plan", icon: SparklesIcon },
|
|
{ href: "/statistiken", label: "Stats", icon: ChartBarIcon },
|
|
{ href: "/hellfireclub", label: "Club", icon: FireIcon },
|
|
];
|
|
|
|
export function MobileNav() {
|
|
const pathname = usePathname();
|
|
|
|
return (
|
|
<>
|
|
<div className="sticky top-0 z-30 flex items-center justify-between border-b border-gray-200 bg-white/95 px-4 py-3 backdrop-blur dark:border-neutral-800 dark:bg-neutral-900/95 lg:hidden">
|
|
<div className="flex items-center gap-2">
|
|
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-[#0F766E] text-xs font-bold text-white">
|
|
HH
|
|
</div>
|
|
<div>
|
|
<p className="text-sm font-semibold leading-none text-gray-900 dark:text-neutral-100">Hellth Hub</p>
|
|
<p className="mt-0.5 text-xs text-gray-400">Daily Health</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<nav className="fixed inset-x-0 bottom-0 z-40 grid grid-cols-4 border-t border-gray-200 bg-white/95 px-2 pb-[env(safe-area-inset-bottom)] pt-1 backdrop-blur dark:border-neutral-800 dark:bg-neutral-900/95 lg:hidden">
|
|
{items.map((item) => {
|
|
const active = item.href === "/" ? pathname === "/" : pathname.startsWith(item.href);
|
|
return (
|
|
<Link
|
|
key={`${item.href}-${item.label}`}
|
|
href={item.href}
|
|
className={`flex min-h-14 flex-col items-center justify-center gap-0.5 rounded-md text-xs font-medium ${
|
|
active ? "text-[#0F766E]" : "text-gray-500 dark:text-neutral-400"
|
|
}`}
|
|
>
|
|
<item.icon className="h-5 w-5" />
|
|
<span>{item.label}</span>
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
</>
|
|
);
|
|
}
|