feat: add Now page

This commit is contained in:
Matej Stieranka 2025-07-01 13:09:26 +02:00
parent 4604463a8e
commit 03fd4d89bf
6 changed files with 78 additions and 4 deletions

View file

@ -1,8 +1,5 @@
import { EventList } from "@/components/EventList"; import { EventList } from "@/components/EventList";
import { ShowElapsedSwitch } from "@/components/ShowElapsedSwitch"; import { ShowElapsedSwitch } from "@/components/ShowElapsedSwitch";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { getEventsByIds } from "@/db"; import { getEventsByIds } from "@/db";
import { cookies } from "next/headers"; import { cookies } from "next/headers";

30
src/app/now/page.tsx Normal file
View file

@ -0,0 +1,30 @@
import { groupEventsByStartTime } from "@/common/utils";
import { EventList } from "@/components/EventList";
import { getNowEvents } from "@/db";
export default async function FavoritesPage() {
const nowEvents = await getNowEvents();
const groupedEvents = groupEventsByStartTime(nowEvents);
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 sm:flex-row justify-between items-center w-full gap-2 mb-4">
<h1 className="text-3xl font-bold">Kam jít?</h1>
</div>
<main className="flex flex-col gap-8 w-full">
{groupedEvents.map(({events, startTime}) => (
<div key={startTime.toISOString()} className="w-full">
<h2 className="text-2xl font-semibold mb-4">
Od {new Date(startTime).toLocaleTimeString("cs-CZ", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
})}
</h2>
<EventList events={events} showDate showLine />
</div>
))}
</main>
</div>
);
}

View file

@ -29,6 +29,13 @@ export default async function Home({ searchParams }: HomePageProps) {
</a> </a>
</li> </li>
</ul> </ul>
<ul className="list-disc pl-5">
<li className="mb-2">
<a href="/now" className="text-blue-600 hover:underline">
Kam jít?
</a>
</li>
</ul>
</section> </section>
<section className="w-full"> <section className="w-full">
<h1 className="text-3xl font-bold mb-4">Dny</h1> <h1 className="text-3xl font-bold mb-4">Dny</h1>

View file

@ -53,6 +53,21 @@ export function groupEventsByLine(events: Event[]) {
})); }));
} }
export function groupEventsByStartTime(events: Event[]) {
const grouped: Record<string, Event[]> = {};
for (const event of events) {
const startTime = new Date(event.startTime).toISOString();
if (!grouped[startTime]) {
grouped[startTime] = [];
}
grouped[startTime].push(event);
}
return Object.entries(grouped).map(([startTime, events]) => ({
startTime: new Date(startTime),
events,
}));
}
export async function isEventFavorite(eventId: number): Promise<boolean> { export async function isEventFavorite(eventId: number): Promise<boolean> {
const cookieStore = await cookies(); const cookieStore = await cookies();
const favorites = cookieStore.get("favorites")?.value || "[]"; const favorites = cookieStore.get("favorites")?.value || "[]";

View file

@ -1,5 +1,5 @@
import * as React from "react"; import * as React from "react";
import { ChevronRight } from "lucide-react"; import { ChevronRight, LoaderIcon } from "lucide-react";
import { SearchForm } from "@/components/search-form"; import { SearchForm } from "@/components/search-form";
import { import {
@ -71,6 +71,11 @@ export async function AppSidebar({
<a href="/">Rozcestník</a> <a href="/">Rozcestník</a>
</SidebarMenuButton> </SidebarMenuButton>
</SidebarMenuItem> </SidebarMenuItem>
<SidebarMenuItem key={"now"}>
<SidebarMenuButton asChild isActive={false}>
<a href="/now">Kam jít?</a>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem key={"favorites"}> <SidebarMenuItem key={"favorites"}>
<SidebarMenuButton asChild isActive={false}> <SidebarMenuButton asChild isActive={false}>
<a href="/favorites">Oblíbené</a> <a href="/favorites">Oblíbené</a>

View file

@ -156,3 +156,23 @@ export async function searchEvents(query: string) {
) )
.orderBy(eventsTable.startTime, eventsTable.endTime); .orderBy(eventsTable.startTime, eventsTable.endTime);
} }
export async function getNowEvents() {
if (process.env.IS_DOCKER_BUILD === "true") {
return []; // Skip fetching now events during Docker build
}
const now = new Date();
return db
.select()
.from(eventsTable)
.where(
and(
gte(eventsTable.startTime, now),
lte(
eventsTable.startTime,
new Date(now.getTime() + 2 * 60 * 60 * 1000),
),
),
)
.orderBy(eventsTable.startTime, eventsTable.endTime);
}