refactor(ui,web): finding 1 — inline use-cookie into donation-toast, drop js-cookie from ui

The 107-line useCookie hook had exactly one consumer (donation-toast) that
only read + set-with-expiry. Inline the two Cookies.* calls directly and
delete the hook + its 128-line test. Drop js-cookie and @types/js-cookie
from packages/ui/package.json (apps/web retains its own js-cookie dep).

Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa
This commit is contained in:
Amruth Pillai
2026-07-04 21:57:10 +02:00
parent 79a69c5507
commit eab7534ea4
6 changed files with 21 additions and 265 deletions
@@ -14,9 +14,9 @@ type ToastOptions = {
unstyled: boolean;
};
const useCookieMock = vi.hoisted(() => ({
setDismissed: vi.fn(),
const cookieMock = vi.hoisted(() => ({
value: null as string | null,
set: vi.fn(),
}));
const toastMock = vi.hoisted(() => ({
@@ -26,8 +26,11 @@ const toastMock = vi.hoisted(() => ({
},
}));
vi.mock("@reactive-resume/ui/hooks/use-cookie", () => ({
useCookie: vi.fn(() => [useCookieMock.value, useCookieMock.setDismissed, vi.fn()] as const),
vi.mock("js-cookie", () => ({
default: {
get: vi.fn(() => cookieMock.value ?? undefined),
set: cookieMock.set,
},
}));
vi.mock("sonner", () => ({
@@ -51,8 +54,8 @@ describe("DonationToast", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-05-11T12:00:00.000Z"));
i18n.loadAndActivate({ locale: "en-US", messages: {} });
useCookieMock.value = null;
useCookieMock.setDismissed.mockClear();
cookieMock.value = null;
cookieMock.set.mockClear();
toastMock.toast.custom.mockClear();
toastMock.toast.dismiss.mockClear();
vi.spyOn(window, "open").mockReturnValue(null);
@@ -89,7 +92,7 @@ describe("DonationToast", () => {
});
it("does not show the toast after it has been dismissed", () => {
useCookieMock.value = "true";
cookieMock.value = "true";
render(<DonationToast />);
@@ -110,7 +113,7 @@ describe("DonationToast", () => {
fireEvent.click(screen.getByRole("button", { name: "Dismiss" }));
expect(useCookieMock.setDismissed).toHaveBeenCalledWith("true", {
expect(cookieMock.set).toHaveBeenCalledWith("donation-toast-dismissed", "true", {
expires: new Date("2026-06-10T12:05:00.000Z"),
});
expect(toastMock.toast.dismiss).toHaveBeenCalledWith("donation-toast");
@@ -126,7 +129,7 @@ describe("DonationToast", () => {
fireEvent.click(screen.getByRole("button", { name: "Donate" }));
expect(useCookieMock.setDismissed).toHaveBeenCalledWith("true", {
expect(cookieMock.set).toHaveBeenCalledWith("donation-toast-dismissed", "true", {
expires: new Date("2026-06-10T12:05:00.000Z"),
});
expect(window.open).toHaveBeenCalledWith(
@@ -1,10 +1,10 @@
import { Trans } from "@lingui/react/macro";
import { HandHeartIcon } from "@phosphor-icons/react";
import { useCallback } from "react";
import Cookies from "js-cookie";
import { useCallback, useState } from "react";
import { toast } from "sonner";
import { useTimeout } from "usehooks-ts";
import { Button } from "@reactive-resume/ui/components/button";
import { useCookie } from "@reactive-resume/ui/hooks/use-cookie";
const TOAST_ID = "donation-toast";
const SHOW_TOAST_DELAY_MS = 5 * 60 * 1000; // 5 minutes
@@ -14,7 +14,13 @@ const DISMISSED_COOKIE_EXPIRES_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
const getDismissedCookieExpiresAt = () => new Date(Date.now() + DISMISSED_COOKIE_EXPIRES_MS);
export function DonationToast() {
const [dismissed, setDismissed] = useCookie(DISMISSED_COOKIE_NAME);
// ponytail: inlined from @reactive-resume/ui/hooks/use-cookie — only consumer, one read + one set-with-expiry
const [dismissed, setDismissedState] = useState<string | null>(() => Cookies.get(DISMISSED_COOKIE_NAME) ?? null);
const setDismissed = useCallback((value: string, options?: { expires?: Date }) => {
Cookies.set(DISMISSED_COOKIE_NAME, value, options);
setDismissedState(value);
}, []);
const showToast = useCallback(() => {
if (dismissed === "true") return;