feat: Add hour titles, make list titles sticky
This commit is contained in:
parent
6110d965a6
commit
6288e716d0
8 changed files with 64 additions and 45 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import { groupEventsByLine } from "@/common/utils";
|
import { groupEventsByLine, groupEventsByStartTime } from "@/common/utils";
|
||||||
import { EventCard } from "@/components/EventCard";
|
import { EventCard } from "@/components/EventCard";
|
||||||
import { EventList } from "@/components/EventList";
|
import { EventList } from "@/components/EventList";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
@ -11,6 +11,7 @@ import {
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { getAllLines, getEventsForDate } from "@/db";
|
import { getAllLines, getEventsForDate } from "@/db";
|
||||||
|
import { line } from "drizzle-orm/pg-core";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
|
|
||||||
export default async function ScheduleByDate({
|
export default async function ScheduleByDate({
|
||||||
|
|
@ -35,11 +36,12 @@ export default async function ScheduleByDate({
|
||||||
if (events.length === 0) {
|
if (events.length === 0) {
|
||||||
return notFound();
|
return notFound();
|
||||||
}
|
}
|
||||||
const groupedEvents = groupEventsByLine(events);
|
const eventsByLine = groupEventsByLine(events);
|
||||||
|
const eventsByTime = groupEventsByStartTime(events);
|
||||||
const allLines = await getAllLines();
|
const allLines = await getAllLines();
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-items-center p-8 pb-20 gap-4 sm:p-20 w-full">
|
<div className="flex flex-col items-center justify-items-center pb-20 w-full">
|
||||||
<div className="flex flex-col sm:flex-row justify-between items-center w-full gap-2 mb-4">
|
<div className="flex flex-col sm:flex-row justify-between items-center w-full gap-2 p-8">
|
||||||
<h1 className="text-3xl font-bold">
|
<h1 className="text-3xl font-bold">
|
||||||
{parsedDate.toLocaleDateString(["cs-CZ"], {
|
{parsedDate.toLocaleDateString(["cs-CZ"], {
|
||||||
weekday: "long",
|
weekday: "long",
|
||||||
|
|
@ -71,14 +73,25 @@ export default async function ScheduleByDate({
|
||||||
</div>
|
</div>
|
||||||
<main className="flex flex-col gap-8 items-center">
|
<main className="flex flex-col gap-8 items-center">
|
||||||
{group === "line" &&
|
{group === "line" &&
|
||||||
groupedEvents.map((line) => (
|
eventsByLine.map((line) => (
|
||||||
<EventList
|
<EventList
|
||||||
key={line.lineId}
|
key={line.lineId}
|
||||||
events={line.events}
|
events={line.events}
|
||||||
title={allLines.find((l) => l.id === line.lineId)?.name}
|
title={allLines.find((l) => l.id === line.lineId)?.name}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{group !== "line" && <EventList events={events} showLine />}
|
{group !== "line" &&
|
||||||
|
eventsByTime.map((time) => (
|
||||||
|
<EventList
|
||||||
|
key={time.startTime.toISOString()}
|
||||||
|
events={time.events}
|
||||||
|
title={`Od ${time.startTime.toLocaleTimeString("cs-CZ", {
|
||||||
|
hour12: false,
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "2-digit",
|
||||||
|
})}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ export default async function FavoritesPage({
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-items-center p-8 pb-20 gap-4 sm:p-20 w-full">
|
<div className="flex flex-col items-center justify-items-center pb-20 w-full">
|
||||||
<div className="flex flex-col sm:flex-row justify-between items-center w-full gap-2 mb-4">
|
<div className="flex flex-col sm:flex-row justify-between items-center w-full gap-2 p-8">
|
||||||
<h1 className="text-3xl font-bold">Oblíbené</h1>
|
<h1 className="text-3xl font-bold">Oblíbené</h1>
|
||||||
<ShowElapsedSwitch defaultValue={false} />
|
<ShowElapsedSwitch defaultValue={false} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ export default async function RootLayout({
|
||||||
<SidebarProvider>
|
<SidebarProvider>
|
||||||
<AppSidebar />
|
<AppSidebar />
|
||||||
<SidebarInset>
|
<SidebarInset>
|
||||||
<header className="bg-background sticky top-0 flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
<header className="bg-background sticky top-0 flex h-16 shrink-0 z-10 items-center gap-2 border-b px-4">
|
||||||
<SidebarTrigger className="-ml-1" />
|
<SidebarTrigger className="-ml-1" />
|
||||||
<Separator orientation="vertical" className="mr-2 h-4" />
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
<div className="flex-grow">
|
<div className="flex-grow">
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default async function ScheduleByLine({
|
||||||
const lineData = groupEventsByDate(events);
|
const lineData = groupEventsByDate(events);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-items-center p-8 pb-20 gap-4 sm:p-20 w-full">
|
<div className="flex flex-col items-center justify-items-center pb-20 w-full">
|
||||||
<div className="flex flex-col items-center text-center">
|
<div className="flex flex-col items-center text-center">
|
||||||
<h1 className="text-3xl font-bold mb-4">{lineInfo.name}</h1>
|
<h1 className="text-3xl font-bold mb-4">{lineInfo.name}</h1>
|
||||||
<h6 className="text-gray-500 mb-4">{lineInfo.description}</h6>
|
<h6 className="text-gray-500 mb-4">{lineInfo.description}</h6>
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,23 @@ export default async function FavoritesPage() {
|
||||||
const groupedEvents = groupEventsByStartTime(nowEvents);
|
const groupedEvents = groupEventsByStartTime(nowEvents);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-items-center p-8 pb-20 gap-4 sm:p-20 w-full">
|
<div className="flex flex-col items-center justify-items-center pb-20 w-full">
|
||||||
<div className="flex flex-col sm:flex-row justify-between items-center w-full gap-2 mb-4">
|
<div className="flex flex-col sm:flex-row justify-between items-center w-full gap-2 p-8">
|
||||||
<h1 className="text-3xl font-bold">Kam jít?</h1>
|
<h1 className="text-3xl font-bold">Kam jít?</h1>
|
||||||
</div>
|
</div>
|
||||||
<main className="flex flex-col gap-8 w-full">
|
<main className="flex flex-col gap-8 w-full">
|
||||||
{groupedEvents.map(({events, startTime}) => (
|
{groupedEvents.map(({ events, startTime }) => (
|
||||||
<div key={startTime.toISOString()} className="w-full">
|
<div key={startTime.toISOString()} className="w-full">
|
||||||
<h2 className="text-2xl font-semibold mb-4">
|
<EventList
|
||||||
Od {new Date(startTime).toLocaleTimeString("cs-CZ", {
|
title={`Od ${new Date(startTime).toLocaleTimeString("cs-CZ", {
|
||||||
hour: "2-digit",
|
hour: "2-digit",
|
||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
hour12: false,
|
hour12: false,
|
||||||
})}
|
})}`}
|
||||||
</h2>
|
events={events}
|
||||||
<EventList events={events} showDate showLine />
|
showDate
|
||||||
|
showLine
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export default async function Home({ searchParams }: HomePageProps) {
|
||||||
console.log("Message from searchParams:", message);
|
console.log("Message from searchParams:", message);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-items-center p-8 pb-20 gap-4 sm:p-20 w-full">
|
<div className="flex flex-col items-center justify-items-center pb-20 w-full">
|
||||||
<main className="flex flex-col gap-[32px] w-full items-center sm:items-start">
|
<main className="flex flex-col gap-[32px] w-full items-center sm:items-start">
|
||||||
{message && (
|
{message && (
|
||||||
<Alert variant="default">
|
<Alert variant="default">
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ export default async function SearchPage({ searchParams }: SearchPageProps) {
|
||||||
const query = (await searchParams).q || "";
|
const query = (await searchParams).q || "";
|
||||||
const results = query ? await searchEvents(query) : [];
|
const results = query ? await searchEvents(query) : [];
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-items-center p-8 pb-20 gap-4 sm:p-20 w-full">
|
<div className="flex flex-col items-center justify-items-center pb-20 w-full">
|
||||||
<main className="flex flex-col gap-8 items-center w-full">
|
<main className="flex flex-col gap-8 items-center w-full">
|
||||||
<h1 className="text-3xl font-bold mb-4 w-full">
|
<h1 className="text-3xl font-bold mb-4 w-full">
|
||||||
Výsledky hledání pro "{query}"
|
Výsledky hledání pro "{query}"
|
||||||
|
|
|
||||||
|
|
@ -2,30 +2,34 @@ import type { Event } from "@/common/parser";
|
||||||
import { EventCard } from "./EventCard";
|
import { EventCard } from "./EventCard";
|
||||||
|
|
||||||
export function EventList({
|
export function EventList({
|
||||||
events,
|
events,
|
||||||
title,
|
title,
|
||||||
showDate,
|
showDate,
|
||||||
showLine,
|
showLine,
|
||||||
}: {
|
}: {
|
||||||
events: Event[];
|
events: Event[];
|
||||||
title?: string;
|
title?: string;
|
||||||
showDate?: boolean;
|
showDate?: boolean;
|
||||||
showLine?: boolean;
|
showLine?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2 w-full">
|
<div className="space-y-2 w-full">
|
||||||
{title && <h2 className="text-2xl font-bold">{title}</h2>}
|
{title && (
|
||||||
{events.length === 0 && (
|
<h2 className="text-2xl font-bold sticky top-16 bg-white dark:bg-black px-8 py-4">
|
||||||
<p className="text-gray-500">Žádné události.</p>
|
{title}
|
||||||
)}
|
</h2>
|
||||||
{events.map((event) => (
|
)}
|
||||||
<EventCard
|
{events.length === 0 && <p className="text-gray-500 px-8">Žádné události.</p>}
|
||||||
key={event.id}
|
<div className="flex flex-col gap-2 px-8">
|
||||||
event={event}
|
{events.map((event) => (
|
||||||
showDate={showDate}
|
<EventCard
|
||||||
showLine={showLine}
|
key={event.id}
|
||||||
/>
|
event={event}
|
||||||
))}
|
showDate={showDate}
|
||||||
</div>
|
showLine={showLine}
|
||||||
);
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue