mafap/client/src/components/timerCard.tsx

117 lines
3.1 KiB
TypeScript
Raw Normal View History

import { useEffect, useState } from "react";
2023-04-04 15:44:06 -06:00
import { ago } from "../utils/ago";
import { TimerResponse, Friend, TimersFilter } from "../utils/types";
const replaceReferencedFriendsInName = (
name: string,
referencedFriends: Friend[],
onSelect: (select?: TimersFilter) => void
) => {
const friendIdToFriend = referencedFriends.reduce(
(friendMap: Record<string, Friend>, friend) => {
friendMap[friend.id.toString()] = friend;
return friendMap;
},
{}
);
2023-04-04 15:44:06 -06:00
return name.split(/(@\<\d+\>)/g).map((s: string) => {
2023-04-04 13:27:33 -06:00
const matches = /@\<(\d+)\>/g.exec(s);
if (matches) {
const [_match, id] = matches;
const name = friendIdToFriend[id].name;
2023-04-04 15:44:06 -06:00
return <a onClick={() => onSelect({ friendId: Number(id) })}>{name}</a>;
2023-04-04 13:27:33 -06:00
}
return s;
});
};
2023-04-05 00:30:03 -06:00
const refreshTimer = (id: number) =>
fetch(`/api/timers/${id}/refresh`, {
method: "POST",
});
2023-04-04 15:44:06 -06:00
export type TimerCardProps = {
timer: TimerResponse;
onSelect: (select?: TimersFilter) => void;
};
export default function TimerCard({ timer, onSelect }: TimerCardProps) {
2023-04-05 00:30:03 -06:00
const [since, setSince] = useState<string>("");
useEffect(() => {
2023-04-05 00:30:03 -06:00
const start = new Date(timer.start);
2023-04-04 15:44:06 -06:00
let updateTimersInterval: ReturnType<typeof setInterval>;
2023-04-05 00:30:03 -06:00
const msTillNextSecond = 1000 - (start.getTime() % 1000);
setSince(ago(start));
setTimeout(() => {
2023-04-05 00:30:03 -06:00
updateTimersInterval = setInterval(() => setSince(ago(start)), 1_000);
}, msTillNextSecond);
return () => clearInterval(updateTimersInterval);
2023-04-05 00:30:03 -06:00
}, [timer.start]);
return (
2023-04-05 00:30:03 -06:00
<div className="card grid-card">
<div>
<header>
<h4 className="is-center">
<code>{since || "..."}</code>
</h4>
</header>
<p>
{replaceReferencedFriendsInName(
timer.name,
timer.referenced_friends,
onSelect
).map((element: JSX.Element | string, i: number) => (
<span style={{ overflowWrap: "anywhere", hyphens: "auto" }} key={i}>
{element}
</span>
))}
</p>
</div>
<div className="timer-metadata text-grey italic">
<div>
<a
onClick={() =>
onSelect({ friendId: timer.timer_refreshes[0].refreshed_by.id })
}
>
{" "}
{timer.created_by.name}
</a>{" "}
is tracking this
</div>
<div>
{timer.timer_refreshes && timer.timer_refreshes.length ? (
<span>
<a
onClick={() =>
onSelect({
friendId: timer.timer_refreshes[0].refreshed_by.id,
})
}
>
{timer.timer_refreshes[0].refreshed_by.name}
</a>{" "}
refreshed it last
</span>
) : (
"has not yet been refreshed..."
)}
</div>
<button
onClick={() => refreshTimer(timer.id)}
className="button outline"
>
Refresh
</button>
</div>
</div>
);
2023-04-03 23:14:07 -06:00
}