Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions clients/web/src/components/rooms/OverviewCard.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { ReactNode } from "react";
import { UrgentIcon } from "@/icons/urgent";
import { cn } from "@/lib/utils";

export type OverviewCardColumn = {
field: string;
value: ReactNode;
valueSecondary?: ReactNode;
description: string;
urgent?: boolean;
};

type OverviewCardProps = {
Expand All @@ -19,23 +22,53 @@ export function OverviewCard({
className = "",
}: OverviewCardProps) {
return (
<section className={cn("bg-white px-[1vw] py-[1.5vh]", className)}>
<h2 className="text-md font-medium text-text-default">{title}</h2>
<section className={cn("flex w-full min-w-0 flex-col bg-white", className)}>
<h2 className="my-2 shrink-0 text-sm font-medium leading-tight text-neutral-400">
{title}
</h2>

<div className="mt-[1vh] h-[0.125vh] w-full bg-stroke-subtle" />
<div className="h-0.5 w-full shrink-0 bg-stroke-subtle" />

<div className="mt-[1.8vh] grid grid-cols-3 gap-[1.7vw]">
<div className="mt-0 flex flex-wrap items-start justify-between gap-y-2">
{columns.map((col) => (
<div key={col.field} className="flex flex-col gap-[1vw]">
<div className="text-sm font-medium leading-tight text-text-default">
{col.field}
<div
key={col.field}
className="flex min-h-px min-w-px flex-1 flex-col gap-1 p-4"
>
<div className="text-sm leading-tight text-text-default">
{col.urgent ? (
<span className="inline-flex gap-0.5">
<UrgentIcon
className="h-4.5 w-4.5 shrink-0 text-text-default"
aria-hidden
/>
{col.field}
</span>
) : (
col.field
)}
</div>

<div className="text-4xl font-semibold tracking-tight text-text-default">
{col.value}
<div
className={cn(
"inline-flex max-w-full min-w-0 flex-nowrap items-center gap-x-1 leading-[1.4] tracking-[-0.32px]",
col.valueSecondary != null && "whitespace-nowrap",
)}
>
<span className="text-[32px] font-bold text-text-default">
{col.value}
</span>
{col.valueSecondary != null && (
<span className="text-[11px] font-medium tracking-normal text-text-subtle">
{" / "}
{col.valueSecondary}
</span>
)}
</div>

<div className="text-sm text-text-default">{col.description}</div>
<div className="text-sm leading-tight text-neutral-400">
{col.description}
</div>
</div>
))}
</div>
Expand Down
16 changes: 11 additions & 5 deletions clients/web/src/components/rooms/RoomsOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@ export function RoomsOverview({ rooms }: RoomsOverviewProps) {
const vacantRooms = totalRooms - occupiedRooms;

return (
<aside className="w-1/4 shrink-0 min-h-0 overflow-y-auto bg-white p-[2vw]">
<div className="flex flex-col gap-[2.2vh]">
<aside className="w-1/4 shrink-0 min-h-0 overflow-y-auto px-6">
<div className="flex flex-col">
<OverviewCard
title="Tasks"
columns={[
{ field: "Urgent", value: 0, description: "Tasks" },
{
field: "Urgent",
value: 0,
description: "Tasks",
urgent: true,
},
{
field: "Unassigned",
value: cleaningOnlyRooms,
Expand All @@ -43,8 +48,9 @@ export function RoomsOverview({ rooms }: RoomsOverviewProps) {
columns={[
{
field: "Floor Occupancy",
value: vacantRooms,
description: "Rooms left",
value: occupiedRooms,
valueSecondary: totalRooms,
description: "Rooms occupied",
},
{
field: "Expected Arrivals",
Expand Down
34 changes: 19 additions & 15 deletions clients/web/src/routes/_protected/rooms.index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { RoomsHeader } from "@/components/rooms/RoomsHeader";
import { RoomsList } from "@/components/rooms/RoomsList";
import { RoomDetailsDrawer } from "@/components/rooms/RoomDetailsDrawer";
import { GeneratedRequestDrawer } from "@/components/requests/GeneratedRequestDrawer";
import { RoomsOverview } from "@/components/rooms/RoomsOverview";

export const Route = createFileRoute("/_protected/rooms/")({
component: RoomsPage,
Expand Down Expand Up @@ -57,25 +58,28 @@ function RoomsPage() {
}
drawerOpen={generatedRequest !== null || selectedRoom !== null}
drawer={drawerContent}
bodyClassName="overflow-hidden"
contentClassName={"h-full pb-26.5"}
>
<SortByContainer ascending={ascending} setAscending={setAscending} />
<RoomsList
rooms={rooms?.items ?? []}
ascending={ascending}
onRoomSelect={(room) => {
setGeneratedRequest(null);
setSelectedRoom(room);
}}
selectedRoomNumber={selectedRoom?.room_number ?? null}
/>
{generatedRequest === null && selectedRoom === null && (
<GlobalTaskInput
onRequestGenerated={(r) => {
setSelectedRoom(null);
setGeneratedRequest(r);
<div className="flex min-h-0 flex-row">
<RoomsList
rooms={rooms?.items ?? []}
ascending={ascending}
onRoomSelect={(room) => {
setGeneratedRequest(null);
setSelectedRoom(room);
}}
selectedRoomNumber={selectedRoom?.room_number ?? null}
/>
)}
<RoomsOverview rooms={rooms?.items ?? []} />
</div>
<GlobalTaskInput
onRequestGenerated={(r) => {
setSelectedRoom(null);
setGeneratedRequest(r);
}}
/>
</PageShell>
);
}
1 change: 1 addition & 0 deletions clients/web/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
--color-text-subtle: #747474;
--color-text-secondary: #5d5d5d;
--color-bg-selected: #edf5f1;
--color-neutral-400: #808080;
--color-muted: #f0f0f0;
--color-request-pending-secondary: #fcdcd1;
--color-request-pending: #f25118;
Expand Down
Loading