a tool for shared writing and social publishing
1"use client";
2import { DatePicker, TimePicker } from "components/DatePicker";
3import { useMemo, useState } from "react";
4import { timeAgo } from "src/utils/timeAgo";
5import { Popover } from "components/Popover";
6import { Separator } from "react-aria-components";
7import { useReplicache } from "src/replicache";
8import { create } from "zustand";
9
10export const useLocalPublishedAt = create<{ [uri: string]: Date }>(() => ({}));
11export const Backdater = (props: { publishedAt: string; docURI: string }) => {
12 let { rep } = useReplicache();
13 let localPublishedAtDate = useLocalPublishedAt((s) =>
14 s[props.docURI] ? s[props.docURI] : null,
15 );
16 let localPublishedAt = useMemo(
17 () => localPublishedAtDate || new Date(props.publishedAt),
18 [localPublishedAtDate, props.publishedAt],
19 );
20
21 let [timeValue, setTimeValue] = useState(
22 `${localPublishedAt.getHours().toString().padStart(2, "0")}:${localPublishedAt.getMinutes().toString().padStart(2, "0")}`,
23 );
24
25 let currentTime = `${new Date().getHours().toString().padStart(2, "0")}:${new Date().getMinutes().toString().padStart(2, "0")}`;
26
27 const handleTimeChange = async (time: string) => {
28 setTimeValue(time);
29 const [hours, minutes] = time.split(":").map((str) => parseInt(str, 10));
30 const newDate = new Date(localPublishedAt);
31 newDate.setHours(hours);
32 newDate.setMinutes(minutes);
33
34 let currentDate = new Date();
35 if (newDate > currentDate) {
36 useLocalPublishedAt.setState({ [props.docURI]: currentDate });
37 setTimeValue(currentTime);
38 } else {
39 useLocalPublishedAt.setState({ [props.docURI]: newDate });
40 }
41 };
42
43 const handleDateChange = async (date: Date | undefined) => {
44 if (!date) return;
45 const [hours, minutes] = timeValue
46 .split(":")
47 .map((str) => parseInt(str, 10));
48 const newDate = new Date(date);
49 newDate.setHours(hours);
50 newDate.setMinutes(minutes);
51
52 let currentDate = new Date();
53 if (newDate > currentDate) {
54 useLocalPublishedAt.setState({ [props.docURI]: currentDate });
55
56 setTimeValue(currentTime);
57 } else {
58 useLocalPublishedAt.setState({ [props.docURI]: newDate });
59 }
60 };
61
62 return (
63 <Popover
64 className="w-64 z-10 px-2!"
65 trigger={
66 <div className="underline">
67 {timeAgo(localPublishedAt.toISOString())}
68 </div>
69 }
70 >
71 <div className="flex flex-col gap-3">
72 <DatePicker
73 selected={localPublishedAt}
74 onSelect={handleDateChange}
75 disabled={(date) => date > new Date()}
76 />
77 <Separator className="border-border" />
78 <div className="flex gap-4 pb-1 items-center">
79 <TimePicker value={timeValue} onChange={handleTimeChange} />
80 </div>
81 </div>
82 </Popover>
83 );
84};