mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
- Replace `tmdbProviderId` (single int) with a many-to-many `platformTmdbProviders` join table so one platform entry can map to multiple TMDB provider IDs (e.g. a single "Max" platform covers several regional TMDB IDs) - Add `isSubscription` flag to platforms to distinguish subscription services from transactional ones, replacing the old `displayOrder` field in API responses - Add `getPlatformTmdbIds` / `getPlatformTmdbIdMap` helpers in `@sofa/core/platforms` and thread them through discover, explore, and platform list procedures - Replace `providerId: number` with `platformId: string` (UUID) in discover input schema so the client never needs to resolve TMDB IDs - Add `scripts/sync-tmdb-providers.ts` script to pull live provider data from TMDB and update `platforms.json` - Split native title detail availability into separate "Stream" and "Buy or Rent" sections matching the web pattern - Add two new DB migrations for the join table and platform schema changes
47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import { useState } from "react";
|
|
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import { orpc } from "@/lib/orpc/client";
|
|
|
|
import { IntegrationCard, type IntegrationConnection } from "./integration-card";
|
|
import { INTEGRATION_CONFIGS } from "./integration-configs";
|
|
|
|
export function IntegrationsSection() {
|
|
const { data, isPending } = useQuery(orpc.integrations.list.queryOptions());
|
|
const [localConnections, setLocalConnections] = useState<IntegrationConnection[] | null>(null);
|
|
|
|
// Use local state if user has modified connections, else use query data
|
|
const connections = localConnections ?? data?.integrations ?? [];
|
|
|
|
function handleSetConnections(
|
|
updater: IntegrationConnection[] | ((prev: IntegrationConnection[]) => IntegrationConnection[]),
|
|
) {
|
|
setLocalConnections((prev) => {
|
|
const current = prev ?? data?.integrations ?? [];
|
|
return typeof updater === "function" ? updater(current) : updater;
|
|
});
|
|
}
|
|
|
|
return isPending ? (
|
|
<div className="space-y-2.5">
|
|
{INTEGRATION_CONFIGS.map((c) => (
|
|
<Skeleton key={c.provider} className="h-20 w-full rounded-xl" />
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="space-y-2.5">
|
|
{INTEGRATION_CONFIGS.map((config) => (
|
|
<IntegrationCard
|
|
key={config.provider}
|
|
config={config}
|
|
connection={
|
|
connections.find((c: IntegrationConnection) => c.provider === config.provider) ?? null
|
|
}
|
|
setConnections={handleSetConnections}
|
|
/>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|