init
This commit is contained in:
@@ -14,6 +14,8 @@ import {
|
||||
isSameMonth,
|
||||
isSameDay,
|
||||
isToday,
|
||||
isAfter,
|
||||
startOfDay,
|
||||
} from "date-fns";
|
||||
import { pl } from "date-fns/locale";
|
||||
import { Activity, ChevronLeft, ChevronRight, Dumbbell, Sparkles } from "lucide-react";
|
||||
@@ -64,9 +66,16 @@ export function DashboardAnalysisCard({ analyses, runs, workouts }: Props) {
|
||||
const [currentMonth, setCurrentMonth] = useState(() => new Date());
|
||||
const [selectedDate, setSelectedDate] = useState<Date>(() => new Date());
|
||||
|
||||
function hasAnalysis(date: Date) {
|
||||
return byDay.has(dayKey(date));
|
||||
}
|
||||
const runDays = useMemo(
|
||||
() => new Set(runs.map((r) => dayKey(new Date(r.startTime)))),
|
||||
[runs]
|
||||
);
|
||||
const workoutDays = useMemo(
|
||||
() => new Set(workouts.map((w) => dayKey(new Date(w.date)))),
|
||||
[workouts]
|
||||
);
|
||||
|
||||
const todayStart = startOfDay(new Date());
|
||||
|
||||
const monthStart = startOfMonth(currentMonth);
|
||||
const monthEnd = endOfMonth(monthStart);
|
||||
@@ -142,12 +151,17 @@ export function DashboardAnalysisCard({ analyses, runs, workouts }: Props) {
|
||||
|
||||
<div className="grid grid-cols-7 gap-1">
|
||||
{days.map((d, i) => {
|
||||
const key = dayKey(d);
|
||||
const inMonth = isSameMonth(d, monthStart);
|
||||
const has = hasAnalysis(d);
|
||||
const today = isToday(d);
|
||||
const selectable = has || today;
|
||||
const future = isAfter(startOfDay(d), todayStart);
|
||||
const selectable = !future;
|
||||
const selected = isSameDay(d, selectedDate);
|
||||
|
||||
const hasRun = runDays.has(key);
|
||||
const hasWorkout = workoutDays.has(key);
|
||||
const hasAnalysis = byDay.has(key);
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
@@ -159,21 +173,37 @@ export function DashboardAnalysisCard({ analyses, runs, workouts }: Props) {
|
||||
!inMonth && "opacity-30",
|
||||
selectable && !selected && "cursor-pointer text-fg hover:bg-accent/20",
|
||||
selected && "bg-accent font-semibold text-fg",
|
||||
!selectable && "cursor-default text-fg/40",
|
||||
!selectable && "cursor-not-allowed text-fg/30",
|
||||
today && !selected && "ring-1 ring-accent/50",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ")}
|
||||
>
|
||||
{d.getDate()}
|
||||
{has && !selected && (
|
||||
<span className="absolute bottom-0.5 left-1/2 h-1 w-1 -translate-x-1/2 rounded-full bg-accent" />
|
||||
{!selected && (hasRun || hasWorkout || hasAnalysis) && (
|
||||
<span className="absolute bottom-0.5 left-1/2 flex -translate-x-1/2 gap-0.5">
|
||||
{hasRun && <span className="h-1 w-1 rounded-full bg-[#5b9bd5]" />}
|
||||
{hasWorkout && <span className="h-1 w-1 rounded-full bg-[#70ad47]" />}
|
||||
{hasAnalysis && <span className="h-1 w-1 rounded-full bg-accent" />}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-fg/55">
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[#5b9bd5]" /> Bieg
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-[#70ad47]" /> Siłownia
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-accent" /> Analiza
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 flex flex-col gap-1.5">
|
||||
<p className="text-xs font-medium text-fg/50">
|
||||
Treningi · {format(selectedDate, "d MMM yyyy", { locale: pl })}
|
||||
@@ -250,7 +280,7 @@ export function DashboardAnalysisCard({ analyses, runs, workouts }: Props) {
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-sm text-fg/60">
|
||||
Wybierz dzień oznaczony kropką, aby zobaczyć analizę z tego dnia.
|
||||
Brak analizy AI dla {format(selectedDate, "d MMMM yyyy", { locale: pl })}.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -24,17 +24,15 @@ export async function Nav() {
|
||||
<Link href="/" className="flex items-center gap-3 text-lg font-bold text-fg">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src="/logo.svg"
|
||||
src="/logo-icon.svg"
|
||||
alt=""
|
||||
width={72}
|
||||
height={72}
|
||||
className="-mt-1 -mb-6 h-[72px] w-[72px] rounded-2xl shadow-lg ring-2 ring-surface"
|
||||
/>
|
||||
<span className="hidden text-xs font-normal tracking-wide text-fg/50 sm:block">
|
||||
<span className="font-semibold text-accent">K</span>siążka{" "}
|
||||
<span className="font-semibold text-accent">N</span>otowań{" "}
|
||||
<span className="font-semibold text-accent">U</span>dźwigów i{" "}
|
||||
<span className="font-semibold text-accent">R</span>ezultatów
|
||||
<span className="hidden text-2xl tracking-tight text-white [font-family:var(--font-space-grotesk)] sm:block">
|
||||
<span className="font-bold [-webkit-text-stroke:0.7px_white]">KNUR</span>
|
||||
<span className="font-medium text-accent">.APP</span>
|
||||
</span>
|
||||
</Link>
|
||||
<nav className="flex items-center gap-1 sm:gap-2">
|
||||
|
||||
Reference in New Issue
Block a user