97 lines
4.1 KiB
TypeScript
97 lines
4.1 KiB
TypeScript
'use client';
|
|
|
|
import { redirect } from "next/navigation";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { ZDay } from "@lifetracker/shared/types/days";
|
|
import { EditableHourCode } from "../hours/EditableHourCode";
|
|
import { getHourFromTime } from "@lifetracker/shared/utils/hours";
|
|
import Link from "next/link";
|
|
import { cn } from "@/lib/utils";
|
|
import { ArrowLeftSquare, ArrowRightSquare } from "lucide-react";
|
|
import spacetime from "spacetime";
|
|
import EditableHour from "@/components/dashboard/hours/EditableHour";
|
|
import { useUpdateHour } from "@lifetracker/shared-react/hooks/days";
|
|
import { useState } from "react";
|
|
|
|
export default function TimelineView({
|
|
days: initialDays,
|
|
}: {
|
|
days: ZDay[];
|
|
}) {
|
|
|
|
// Hacky, but it works
|
|
// Remove "container" class from parent div
|
|
const parent = document.querySelector(".container");
|
|
if (parent) {
|
|
parent.classList.remove("container");
|
|
}
|
|
|
|
const [days, setDays] = useState(initialDays);
|
|
const { mutate: updateHour, isPending } = useUpdateHour({
|
|
onSuccess: (res, req, meta) => {
|
|
const hourDay = days.find(day => day.date === req.date);
|
|
// Replace the relevant hour within hourDay
|
|
hourDay.hours[req.i] = res;
|
|
// Place the new hourDay within the days array
|
|
setDays([...days]);
|
|
},
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<div className="grid font-mono border-b-2 text-sm" style={{ gridTemplateColumns: "repeat(26, 1fr)", borderColor: "white" }}>
|
|
<div className="flex text-center justify-center">DATE</div>
|
|
<div className="flex text-center justify-center border-r-2 border-inherit">DAY</div>
|
|
{Array.from({ length: 24 }, (_, i) => (
|
|
<div key={i} className={cn("flex text-center items-center justify-center",
|
|
i == spacetime().hour() ? "bg-white text-black" : ""
|
|
)}>
|
|
{getHourFromTime(i, "all")}
|
|
</div>
|
|
))}
|
|
</div>
|
|
{
|
|
days.map((day, index) => (
|
|
<div
|
|
key={index}
|
|
className="grid font-mono"
|
|
style={{ gridTemplateColumns: "repeat(26, 1fr)", borderColor: "white" }}
|
|
>
|
|
<div className={cn("text-center",
|
|
spacetime(day.date).diff(spacetime.now()).hours < 24 && spacetime(day.date).diff(spacetime.now()).hours > 0 ? "bg-white text-black" : ""
|
|
)}>
|
|
{spacetime(day.date).format("{iso-month}/{date-pad}")}
|
|
</div>
|
|
<div className={cn("text-center",
|
|
spacetime(day.date).diff(spacetime.now()).hours < 24 && spacetime(day.date).diff(spacetime.now()).hours > 0 ? "bg-white text-black" : ""
|
|
)}>
|
|
{spacetime(day.date).format("{day-short}")}
|
|
</div>
|
|
{day.hours.map((hour, i) => (
|
|
<EditableHourCode
|
|
className="w-full h-full hover:cursor-default text-xs"
|
|
key={i}
|
|
originalText={hour.categoryCode}
|
|
hour={hour}
|
|
i={i}
|
|
onSubmit={updateHour}
|
|
/>
|
|
// <div key={i}
|
|
// datetime={day.date + "T" + hour.time + ":00:00"}
|
|
// className="flex items-center justify-center font-mono"
|
|
// style={{
|
|
// backgroundColor: hour.background ?? "white",
|
|
// color: hour.foreground ?? "black",
|
|
// }}
|
|
// >
|
|
// {hour.categoryCode ?? "_"}
|
|
// </div>
|
|
))}
|
|
</div>
|
|
|
|
))
|
|
}
|
|
</>
|
|
);
|
|
}
|