From 829d610e952eb07298e75879b686568e7d8a67b3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 25 Jun 2026 03:30:18 +0000 Subject: [PATCH 1/2] =?UTF-8?q?refactor(api):=20custom-links=20=E2=86=92?= =?UTF-8?q?=20src/api=20modules=20(Effort=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mechanical move of the custom-links feature from src/hooks/queries/custom-links to src/api/custom-links, adding queryOptions factories for the query hooks. No behavior change. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01K513rsQz6Lg1HbbfYiafrE --- src/api/custom-links/types.ts | 9 ++++++++ .../custom-links/useCustomLinks.ts | 22 +++++++++---------- .../custom-links/useCustomLinksMutation.ts | 2 +- src/pages/EditionView/EditionLayout.tsx | 2 +- src/pages/EditionView/tabs/InfoTab.tsx | 2 +- src/pages/FestivalSelection.tsx | 2 +- .../FestivalFields/FestivalLinksField.tsx | 4 ++-- .../festivals/info/FestivalInfoDetails.tsx | 2 +- 8 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 src/api/custom-links/types.ts rename src/{hooks/queries => api}/custom-links/useCustomLinks.ts (59%) rename src/{hooks/queries => api}/custom-links/useCustomLinksMutation.ts (97%) diff --git a/src/api/custom-links/types.ts b/src/api/custom-links/types.ts new file mode 100644 index 00000000..706fff58 --- /dev/null +++ b/src/api/custom-links/types.ts @@ -0,0 +1,9 @@ +import type { Tables } from "@/integrations/supabase/types"; + +export type CustomLink = Tables<"custom_links">; + +export const customLinksKeys = { + all: ["customLinks"] as const, + byFestival: (festivalId: string) => + [...customLinksKeys.all, festivalId] as const, +}; diff --git a/src/hooks/queries/custom-links/useCustomLinks.ts b/src/api/custom-links/useCustomLinks.ts similarity index 59% rename from src/hooks/queries/custom-links/useCustomLinks.ts rename to src/api/custom-links/useCustomLinks.ts index f79bbaf3..9757b5f4 100644 --- a/src/hooks/queries/custom-links/useCustomLinks.ts +++ b/src/api/custom-links/useCustomLinks.ts @@ -1,14 +1,6 @@ -import { useQuery } from "@tanstack/react-query"; +import { queryOptions, useQuery } from "@tanstack/react-query"; import { supabase } from "@/integrations/supabase/client"; -import { Tables } from "@/integrations/supabase/types"; - -export type CustomLink = Tables<"custom_links">; - -export const customLinksKeys = { - all: ["customLinks"] as const, - byFestival: (festivalId: string) => - [...customLinksKeys.all, festivalId] as const, -}; +import { CustomLink, customLinksKeys } from "./types"; async function fetchCustomLinks(festivalId: string): Promise { const { data, error } = await supabase @@ -26,10 +18,16 @@ async function fetchCustomLinks(festivalId: string): Promise { return data || []; } +export function customLinksQuery(festivalId: string) { + return queryOptions({ + queryKey: customLinksKeys.byFestival(festivalId), + queryFn: () => fetchCustomLinks(festivalId), + }); +} + export function useCustomLinksQuery(festivalId: string | undefined) { return useQuery({ - queryKey: customLinksKeys.byFestival(festivalId || ""), - queryFn: () => fetchCustomLinks(festivalId!), + ...customLinksQuery(festivalId!), enabled: !!festivalId, }); } diff --git a/src/hooks/queries/custom-links/useCustomLinksMutation.ts b/src/api/custom-links/useCustomLinksMutation.ts similarity index 97% rename from src/hooks/queries/custom-links/useCustomLinksMutation.ts rename to src/api/custom-links/useCustomLinksMutation.ts index c5ae6b8d..ee2c8045 100644 --- a/src/hooks/queries/custom-links/useCustomLinksMutation.ts +++ b/src/api/custom-links/useCustomLinksMutation.ts @@ -1,7 +1,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { useToast } from "@/hooks/use-toast"; import { supabase } from "@/integrations/supabase/client"; -import { customLinksKeys } from "./useCustomLinks"; +import { customLinksKeys } from "./types"; interface BulkUpdateCustomLinksData { festivalId: string; diff --git a/src/pages/EditionView/EditionLayout.tsx b/src/pages/EditionView/EditionLayout.tsx index 74173c49..140d927c 100644 --- a/src/pages/EditionView/EditionLayout.tsx +++ b/src/pages/EditionView/EditionLayout.tsx @@ -3,7 +3,7 @@ import { MainTabNavigation } from "./TabNavigation/TabNavigation"; import ErrorBoundary from "@/components/ErrorBoundary"; import { useFestivalEdition } from "@/contexts/FestivalEditionContext"; import { Outlet } from "@tanstack/react-router"; -import { useCustomLinksQuery } from "@/hooks/queries/custom-links/useCustomLinks"; +import { useCustomLinksQuery } from "@/api/custom-links/useCustomLinks"; export default function EditionView() { const { festival, edition } = useFestivalEdition(); diff --git a/src/pages/EditionView/tabs/InfoTab.tsx b/src/pages/EditionView/tabs/InfoTab.tsx index df0782f1..a9c0c1a8 100644 --- a/src/pages/EditionView/tabs/InfoTab.tsx +++ b/src/pages/EditionView/tabs/InfoTab.tsx @@ -7,7 +7,7 @@ import { CustomLinks } from "./InfoTab/CustomLinks"; import { NoInfo } from "./InfoTab/NoInfo"; import { LoadingInfo } from "./InfoTab/LoadingInfo"; import { SocialLinkItem } from "./InfoTab/SocialLinkItem"; -import { useCustomLinksQuery } from "@/hooks/queries/custom-links/useCustomLinks"; +import { useCustomLinksQuery } from "@/api/custom-links/useCustomLinks"; export function InfoTab() { const { edition, festival } = useFestivalEdition(); diff --git a/src/pages/FestivalSelection.tsx b/src/pages/FestivalSelection.tsx index 088a9485..38da703f 100644 --- a/src/pages/FestivalSelection.tsx +++ b/src/pages/FestivalSelection.tsx @@ -14,7 +14,7 @@ import { isMainGetuplineDomain, } from "@/lib/subdomain"; import { Link } from "@tanstack/react-router"; -import { useCustomLinksQuery } from "@/hooks/queries/custom-links/useCustomLinks"; +import { useCustomLinksQuery } from "@/api/custom-links/useCustomLinks"; import { PageTitle } from "@/components/PageTitle/PageTitle"; import { TopBar } from "@/components/layout/TopBar"; import { AppHeader } from "@/components/layout/AppHeader"; diff --git a/src/pages/admin/festivals/info/FestivalFields/FestivalLinksField.tsx b/src/pages/admin/festivals/info/FestivalFields/FestivalLinksField.tsx index f263ab96..3b330c94 100644 --- a/src/pages/admin/festivals/info/FestivalFields/FestivalLinksField.tsx +++ b/src/pages/admin/festivals/info/FestivalFields/FestivalLinksField.tsx @@ -4,8 +4,8 @@ import { Input } from "@/components/ui/input"; import { ExternalLink, Plus, Trash2 } from "lucide-react"; import { EditableField } from "./shared/EditableField"; import { EditContainer } from "./shared/EditContainer"; -import { CustomLink } from "@/hooks/queries/custom-links/useCustomLinks"; -import { useBulkUpdateCustomLinksMutation } from "@/hooks/queries/custom-links/useCustomLinksMutation"; +import { CustomLink } from "@/api/custom-links/types"; +import { useBulkUpdateCustomLinksMutation } from "@/api/custom-links/useCustomLinksMutation"; interface FestivalLinksFieldProps { festivalId: string; diff --git a/src/pages/admin/festivals/info/FestivalInfoDetails.tsx b/src/pages/admin/festivals/info/FestivalInfoDetails.tsx index 6bfa7d9e..34297c13 100644 --- a/src/pages/admin/festivals/info/FestivalInfoDetails.tsx +++ b/src/pages/admin/festivals/info/FestivalInfoDetails.tsx @@ -1,7 +1,7 @@ import { Button } from "@/components/ui/button"; import { Loader2, Edit } from "lucide-react"; import { useFestivalInfoQuery } from "@/hooks/queries/festival-info/useFestivalInfo"; -import { useCustomLinksQuery } from "@/hooks/queries/custom-links/useCustomLinks"; +import { useCustomLinksQuery } from "@/api/custom-links/useCustomLinks"; import { FestivalMapField } from "./FestivalFields/FestivalMapField"; import { FestivalInfoField } from "./FestivalFields/FestivalInfoField"; import { FestivalSocialField } from "./FestivalFields/FestivalSocialField"; From 857da9e3e6adc211913e6eada29c4b07e83ba9e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 25 Jun 2026 03:38:06 +0000 Subject: [PATCH 2/2] fix(api): preserve empty-string key normalization in useCustomLinksQuery The mechanical move changed customLinksKeys.byFestival(festivalId || "") to customLinksQuery(festivalId!), shifting the disabled-state cache key from ["customLinks", ""] to ["customLinks", undefined]. Restore the original normalization via ?? "" to keep the move behavior-neutral. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01K513rsQz6Lg1HbbfYiafrE --- src/api/custom-links/useCustomLinks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/custom-links/useCustomLinks.ts b/src/api/custom-links/useCustomLinks.ts index 9757b5f4..205a1f5e 100644 --- a/src/api/custom-links/useCustomLinks.ts +++ b/src/api/custom-links/useCustomLinks.ts @@ -27,7 +27,7 @@ export function customLinksQuery(festivalId: string) { export function useCustomLinksQuery(festivalId: string | undefined) { return useQuery({ - ...customLinksQuery(festivalId!), + ...customLinksQuery(festivalId ?? ""), enabled: !!festivalId, }); }