init
This commit is contained in:
BIN
app/favicon.ico
BIN
app/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 15 KiB |
@@ -20,6 +20,7 @@
|
||||
--color-sand: var(--color-sand);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--font-display: var(--font-space-grotesk);
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -27,3 +28,87 @@ body {
|
||||
color: var(--color-fg);
|
||||
font-family: var(--font-sans), Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* Ambient accent glow behind everything — modern dark-UI depth. */
|
||||
body::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
background:
|
||||
radial-gradient(60rem 40rem at 15% -10%, color-mix(in oklab, var(--color-accent) 14%, transparent), transparent 70%),
|
||||
radial-gradient(50rem 40rem at 100% 0%, color-mix(in oklab, var(--color-secondary) 45%, transparent), transparent 65%);
|
||||
}
|
||||
|
||||
/* Display font for all headings. */
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
font-family: var(--font-display), var(--font-sans), sans-serif;
|
||||
letter-spacing: -0.015em;
|
||||
}
|
||||
|
||||
/* Tabular figures for stats so numbers line up. */
|
||||
.tabular-nums {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* Confine Leaflet's internal panes (z-index 400–1000) to their own stacking
|
||||
context so the map never overlaps the sticky navbar. */
|
||||
.leaflet-container {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Unified button system. In @layer components so Tailwind utility overrides
|
||||
(e.g. px-8, text-xs, w-full) still win over these base styles. */
|
||||
@layer components {
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.375rem;
|
||||
border-radius: 0.75rem;
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.25rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
transition: transform 0.12s ease, background-color 0.15s ease,
|
||||
border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease,
|
||||
filter 0.15s ease;
|
||||
}
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--color-accent);
|
||||
color: #fff;
|
||||
box-shadow: 0 6px 18px -6px color-mix(in oklab, var(--color-accent) 70%, transparent);
|
||||
}
|
||||
.btn-primary:hover:not(:disabled) {
|
||||
filter: brightness(1.08);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.btn-primary:active:not(:disabled) {
|
||||
filter: brightness(0.96);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: color-mix(in oklab, var(--color-surface) 55%, transparent);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
color: color-mix(in oklab, var(--color-fg) 88%, transparent);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
.btn-secondary:hover:not(:disabled) {
|
||||
border-color: color-mix(in oklab, var(--color-accent) 55%, transparent);
|
||||
color: var(--color-accent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 450 B |
@@ -1,36 +1,31 @@
|
||||
import { signIn } from "@/auth";
|
||||
import { Wordmark } from "@/components/wordmark";
|
||||
|
||||
export default function LoginPage() {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col items-center justify-center gap-10">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="/logo.svg"
|
||||
alt="KNUR"
|
||||
width={160}
|
||||
height={160}
|
||||
className="rounded-3xl shadow-2xl ring-2 ring-surface"
|
||||
/>
|
||||
<h1 className="text-3xl font-bold tracking-tight text-fg">KNUR</h1>
|
||||
<p className="text-sm text-fg/50">
|
||||
Książka Notowań Udźwigów i Rezultatów
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex min-h-screen flex-col items-center justify-center px-4">
|
||||
<div className="flex w-full max-w-sm flex-col items-center gap-7 rounded-2xl border border-white/10 bg-surface/55 p-8 shadow-lg shadow-black/10 backdrop-blur-md">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img src="/logo-bars.svg" alt="" width={51} height={48} className="h-12 w-auto" />
|
||||
<Wordmark className="text-3xl" />
|
||||
<p className="text-center text-sm text-fg/50">
|
||||
Książka Notowań Udźwigów i Rezultatów
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form
|
||||
action={async () => {
|
||||
"use server";
|
||||
await signIn("keycloak", { redirectTo: "/" });
|
||||
}}
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-lg bg-accent px-8 py-3 text-sm font-semibold text-white transition-opacity hover:opacity-90"
|
||||
<form
|
||||
className="w-full"
|
||||
action={async () => {
|
||||
"use server";
|
||||
await signIn("keycloak", { redirectTo: "/" });
|
||||
}}
|
||||
>
|
||||
Zaloguj
|
||||
</button>
|
||||
</form>
|
||||
<button type="submit" className="btn btn-primary w-full px-8 py-3 text-base">
|
||||
Zaloguj
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ function buildGrid(maxDistKm: number): number[] {
|
||||
function RouteMap({ activity }: { activity: RunningActivity }) {
|
||||
const routePoints = activity.routePoints;
|
||||
return (
|
||||
<div className="col-span-2 row-span-3 min-h-[240px] overflow-hidden rounded-lg border border-muted/40">
|
||||
<div className="col-span-2 row-span-3 min-h-[240px] overflow-hidden rounded-2xl border border-white/10">
|
||||
{routePoints && routePoints.length > 0 ? (
|
||||
<RouteMapSection points={routePoints} />
|
||||
) : (
|
||||
|
||||
@@ -34,7 +34,7 @@ export default async function RunningPage() {
|
||||
<li key={activity._id.toString()}>
|
||||
<Link
|
||||
href={`/running/${activity._id.toString()}`}
|
||||
className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4 transition-colors hover:border-accent/60"
|
||||
className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4 transition-colors hover:border-accent/60"
|
||||
>
|
||||
<div>
|
||||
<div className="font-semibold text-fg">{activity.name}</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ export function GarminCredentialsForm({ savedEmail }: { savedEmail: string | nul
|
||||
defaultValue={savedEmail ?? ""}
|
||||
placeholder="twoj@email.com"
|
||||
required
|
||||
className="rounded-md border border-muted/40 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
|
||||
className="rounded-md border border-white/10 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1.5">
|
||||
@@ -35,7 +35,7 @@ export function GarminCredentialsForm({ savedEmail }: { savedEmail: string | nul
|
||||
type="password"
|
||||
placeholder="••••••••"
|
||||
required
|
||||
className="rounded-md border border-muted/40 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
|
||||
className="rounded-md border border-white/10 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -49,7 +49,7 @@ export function GarminCredentialsForm({ savedEmail }: { savedEmail: string | nul
|
||||
<button
|
||||
type="submit"
|
||||
disabled={pending}
|
||||
className="self-start rounded-md bg-accent px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90 disabled:opacity-50"
|
||||
className="btn btn-primary self-start"
|
||||
>
|
||||
{pending ? "Zapisywanie…" : "Zapisz"}
|
||||
</button>
|
||||
|
||||
@@ -15,7 +15,7 @@ function StatusRow({ label, ok, okLabel = "Skonfigurowano", failLabel = "Brak ko
|
||||
failLabel?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4">
|
||||
<div className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4">
|
||||
<span className="text-fg">{label}</span>
|
||||
{ok ? (
|
||||
<span className="flex items-center gap-1.5 text-sm text-fg/70">
|
||||
@@ -67,14 +67,14 @@ export default async function SettingsPage() {
|
||||
|
||||
<section className="flex flex-col gap-3">
|
||||
<h2 className="text-lg font-semibold text-fg">Konto Garmin Connect</h2>
|
||||
<div className="rounded-lg border border-muted/40 bg-surface p-4">
|
||||
<div className="rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4">
|
||||
<GarminCredentialsForm savedEmail={garminCreds?.email ?? null} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col gap-3">
|
||||
<h2 className="text-lg font-semibold text-fg">Synchronizacja z Garmin</h2>
|
||||
<div className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4">
|
||||
<div className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4">
|
||||
<span className="text-sm text-fg/70">
|
||||
{lastSyncAt
|
||||
? `Ostatnia synchronizacja: ${formatDate(lastSyncAt)}`
|
||||
|
||||
@@ -55,7 +55,7 @@ export default async function StrengthWorkoutPage({
|
||||
{exercisesWithHistory.map(({ exercise }, index) => {
|
||||
const e1rm = exerciseE1rm(exercise);
|
||||
return (
|
||||
<div key={index} className="flex flex-col gap-2 rounded-lg border border-muted/40 bg-surface px-3 py-2.5">
|
||||
<div key={index} className="flex flex-col gap-2 rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md px-3 py-2.5">
|
||||
<p className="text-xs font-semibold text-fg">{exercise.name}</p>
|
||||
{exercise.notes ? <p className="text-xs text-fg/50 italic">{exercise.notes}</p> : null}
|
||||
<div className="flex flex-wrap gap-1">
|
||||
|
||||
@@ -18,12 +18,12 @@ export function ImportForm() {
|
||||
rows={16}
|
||||
required
|
||||
placeholder={"Trening A\nWednesday, 10 June 2026 at 06:40\n\nDeadlift (Barbell)\nSet 1: 80 kg × 8\n..."}
|
||||
className="w-full rounded-md border border-muted/40 bg-surface p-3 font-mono text-sm text-fg placeholder:text-fg/30 focus:border-accent focus:outline-none"
|
||||
className="w-full rounded-md border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-3 font-mono text-sm text-fg placeholder:text-fg/30 focus:border-accent focus:outline-none"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={pending}
|
||||
className="self-start rounded-md bg-accent px-4 py-2 text-sm font-semibold text-fg transition-opacity hover:opacity-90 disabled:opacity-50"
|
||||
className="btn btn-primary self-start"
|
||||
>
|
||||
{pending ? "Importowanie..." : "Importuj"}
|
||||
</button>
|
||||
|
||||
@@ -31,7 +31,7 @@ export default async function StrengthPage() {
|
||||
</div>
|
||||
<Link
|
||||
href="/strength/import"
|
||||
className="flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-semibold text-fg transition-opacity hover:opacity-90"
|
||||
className="btn btn-primary"
|
||||
>
|
||||
<Plus size={16} />
|
||||
Importuj
|
||||
@@ -52,7 +52,7 @@ export default async function StrengthPage() {
|
||||
<li key={workout._id.toString()}>
|
||||
<Link
|
||||
href={`/strength/${workout._id.toString()}`}
|
||||
className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4 transition-colors hover:border-accent/60"
|
||||
className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4 transition-colors hover:border-accent/60"
|
||||
>
|
||||
<div>
|
||||
<div className="font-semibold text-fg">{workout.name}</div>
|
||||
|
||||
Reference in New Issue
Block a user