Skip to content

Commit

Permalink
less 🍝 and now storing lat and long instead osm link
Browse files Browse the repository at this point in the history
  • Loading branch information
dheidemann committed Oct 6, 2024
1 parent 279bf71 commit 97e0e53
Show file tree
Hide file tree
Showing 12 changed files with 591 additions and 307 deletions.
245 changes: 4 additions & 241 deletions frontend/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import {
EventCloseupDocument,
EventCloseupQuery,
EventCloseupQueryVariables,
PlannerEventsDocument,
PlannerEventsQuery,
PlannerEventsQueryVariables,
Expand All @@ -21,13 +17,7 @@ import {
} from "@/lib/gql/generated/graphql";
import { client } from "@/lib/graphClient";
import React, { useEffect, useState } from "react";
import {
Check,
ChevronsUpDown,
Mail,
Building2,
ArrowDownToDot,
} from "lucide-react";
import { Check, ChevronsUpDown } from "lucide-react";

import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
Expand All @@ -45,21 +35,9 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";
import { Skeleton } from "@/components/ui/skeleton";
import {
Dialog,
DialogHeader,
DialogContent,
DialogDescription,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table";
import {
HoverCard,
HoverCardTrigger,
HoverCardContent,
} from "@/components/ui/hover-card";
import { Dialog, DialogTrigger } from "@/components/ui/dialog";
import EventDialog from "./ui/event-dialog";
import Filter from "@/components/filter";

type GroupedEvents = {
[week: number]: {
Expand Down Expand Up @@ -366,218 +344,3 @@ export default function Home() {
</main>
);
}

function Filter({
title,
options,
filter,
setFilter,
}: {
title: string;
options: string[];
filter: string[];
setFilter: React.Dispatch<React.SetStateAction<string[]>>;
}) {
const handleFilterChange = (f: string) => {
setFilter((prevSelected) =>
prevSelected.includes(f)
? prevSelected.filter((t) => t !== f)
: [...prevSelected, f]
);
};

return (
<div>
<p className="font-bold text-xs">{title}</p>
<div className="flex flex-row space-x-4">
{options.map((o) => (
<label key={o} className="flex items-center space-x-2">
<Checkbox
checked={filter.includes(o)}
onCheckedChange={() => handleFilterChange(o)}
/>
<p>{o}</p>
</label>
))}
</div>
</div>
);
}

function EventDialog({ id }: { id: number }) {
const [loading, setLoading] = useState(true);
const [event, setEvent] = useState<EventCloseupQuery["events"][0] | null>(
null
);

useEffect(() => {
if (!id) return;
const fetchData = async () => {
setLoading(true);

const vars: EventCloseupQueryVariables = {
id: id,
};

await new Promise((resolve) => setTimeout(resolve, 250));

const eventData = await client.request<EventCloseupQuery>(
EventCloseupDocument,
vars
);

if (eventData.events.length) {
setEvent(eventData.events[0]);
setLoading(false);
}
};

fetchData();
}, [id]);

return (
<DialogContent className="sm:max-w-[550px]">
{loading ? (
<div className="flex flex-col space-y-3">
<Skeleton className="h-5 w-[80px]" />
<Skeleton className="h-3 w-[200px]" />
<Skeleton className="h-[125px] w-full rounded-xl" />
</div>
) : (
<div className="space-y-4">
<DialogHeader>
<DialogTitle>{event?.title}</DialogTitle>
<DialogDescription>
{event?.description}
<div className="space-x-2 mt-2">
<Badge variant="event" color={event?.topic.color}>
{event?.topic.name}
</Badge>
<Badge variant="event" color={event?.type.color}>
{event?.type.name}
</Badge>
</div>
</DialogDescription>
</DialogHeader>
<div className="rounded-md border">
<Table>
<TableBody>
{event?.tutorsAssigned?.map((e) => {
const registrations = e.registrations ?? 0;
const capacity = e.room?.capacity ?? 1;
const utilization = (registrations / capacity) * 100;

return (
<TableRow key={e.room?.number}>
<div
className={
"absolute inset-0 z-0 rounded-md bg-" +
(utilization < 100 ? "green" : "red") +
"-200"
}
style={{
width: `${utilization}%`,
}}
/>
<TableCell className="relative z-10">
{e.tutors?.map((t) => (
<HoverCard key={t.mail}>
<HoverCardTrigger asChild>
<p className="hover:underline">
{t.fn + " " + t.sn[0] + "."}
</p>
</HoverCardTrigger>
<HoverCardContent>
<p className="mb-1 text-xs text-muted-foreground">
{t.fn + " " + t.sn}
</p>
<div className="flex flex-row items-center">
<Mail className="mr-2 h-4 w-4 opacity-70" />
<a
href={"mailto:" + t.mail}
className="hover:underline text-blue-500"
>
{t.mail}
</a>
</div>
</HoverCardContent>
</HoverCard>
))}
</TableCell>
<TableCell className="relative z-2">
<HoverCard>
<HoverCardTrigger asChild>
<div className="hover:undeline">
<p className="text-xs text-muted-foreground">
{e.room?.building.name}
</p>
<p>
{e.room?.name ? e.room.name : e.room?.number}
</p>
</div>
</HoverCardTrigger>
<HoverCardContent className="min-w-[400px] p-0 flex flex-row">
<div className="p-4 space-y-4">
<div className="flex flex-row space-x-2">
<Building2 className="h-5 w-5" />
<div>
<p className="font-bold">
{e.room?.building.name}
</p>
<p className="text-xs text-muted-foreground">
{e.room?.building.street +
" " +
e.room?.building.number}
</p>
<div className="flex flex-row space-x-1 text-xs text-muted-foreground">
<p>{e.room?.building.zip},</p>
<p>{e.room?.building.city}</p>
</div>
</div>
</div>
<div className="flex flex-row space-x-2">
<ArrowDownToDot className="h-5 w-5" />
<div>
<p className="font-bold">
{e.room?.name
? e.room.name
: e.room?.number}
</p>
<p className="text-xs text-muted-foreground">
Ebene {e.room?.floor}
</p>
</div>
</div>
</div>
<iframe
className="rounded-tr-lg rounded-br-lg"
height="100%"
width="100%"
src="https://www.openstreetmap.org/export/embed.html?bbox=8.674038648605348%2C49.41641767965658%2C8.675851821899416%2C49.41860402680603&amp;layer=mapnik"
></iframe>
</HoverCardContent>
</HoverCard>
</TableCell>
<TableCell className="relative z-10">
<div>
<span>{registrations}</span>
<span>/</span>
<span>{e.room?.capacity}</span>
</div>
</TableCell>
<TableCell className="relative z-10">
<Button disabled={utilization == 100} variant="outline">
Eintragen
</Button>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</div>
</div>
)}
</DialogContent>
);
}
Loading

0 comments on commit 97e0e53

Please sign in to comment.