Add Next.js frontend PWA

- Pages: login, register, tasks list, task detail
- Components: TaskCard, TaskForm, GroupSelector, StatusBadge, Header
- Tailwind CSS, dark/light mode, PWA manifest
- Running on :3001 via systemd

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude CLI Agent
2026-03-29 10:02:32 +00:00
parent 9d075455e3
commit b5a6dd6d6f
29 changed files with 7541 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
"use client";
import { useAuth } from "@/lib/auth";
import { useTheme } from "./ThemeProvider";
import Link from "next/link";
import { useRouter } from "next/navigation";
export default function Header() {
const { user, logout, token } = useAuth();
const { theme, toggleTheme } = useTheme();
const router = useRouter();
function handleLogout() {
logout();
router.push("/login");
}
return (
<header className="sticky top-0 z-50 bg-white/80 dark:bg-gray-950/80 backdrop-blur-md border-b border-gray-200 dark:border-gray-800">
<div className="max-w-4xl mx-auto px-4 h-14 flex items-center justify-between">
<Link href="/tasks" className="text-lg font-bold tracking-tight">
Task Team
</Link>
<div className="flex items-center gap-3">
<button
onClick={toggleTheme}
className="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
aria-label="Prepnout tema"
>
{theme === "dark" ? (
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
) : (
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
</svg>
)}
</button>
{token && user ? (
<div className="flex items-center gap-2">
<span className="text-sm text-muted hidden sm:inline">{user.name || user.email}</span>
<button
onClick={handleLogout}
className="text-sm px-3 py-1.5 rounded-lg border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
>
Odhlasit
</button>
</div>
) : (
<Link
href="/login"
className="text-sm px-3 py-1.5 rounded-lg bg-blue-600 text-white hover:bg-blue-700 transition-colors"
>
Prihlasit
</Link>
)}
</div>
</div>
</header>
);
}