import { data, redirect, useSearchParams } from "react-router"; import { useTranslation } from "react-i18next"; import { eq } from "drizzle-orm"; import type { Route } from "./+types/settings.connections"; import { getSessionUser } from "~/lib/auth/session.server"; import { getDb } from "~/lib/db"; import { connectedServices } from "@trails-cool/db/schema/journal"; import { getAllManifests } from "~/lib/connected-services"; const KNOWN_ERRORS = ["too_many_tokens", "sync_failed", "generic"] as const; type KnownError = (typeof KNOWN_ERRORS)[number]; function isKnownError(value: string | null): value is KnownError { return value !== null && (KNOWN_ERRORS as readonly string[]).includes(value); } export function meta() { return [{ title: "Connected services — Settings — trails.cool" }]; } export async function loader({ request }: Route.LoaderArgs) { const user = await getSessionUser(request); if (!user) throw redirect("/auth/login"); const db = getDb(); const connections = await db .select({ provider: connectedServices.provider, providerUserId: connectedServices.providerUserId, }) .from(connectedServices) .where(eq(connectedServices.userId, user.id)); const providers = getAllManifests().map((m) => { const conn = connections.find((c) => c.provider === m.id); return { id: m.id, name: m.displayName, connected: !!conn, providerUserId: conn?.providerUserId, connectUrl: m.connectUrl ?? null, }; }); return data({ providers }); } export default function ConnectionsSettings({ loaderData }: Route.ComponentProps) { const { providers } = loaderData; const { t } = useTranslation(["journal"]); const [searchParams] = useSearchParams(); const errorParam = searchParams.get("error"); const errorKey: KnownError | null = isKnownError(errorParam) ? errorParam : errorParam ? "generic" : null; return (

{t("settings.services.title")}

{errorKey && (
{t(`settings.services.errors.${errorKey}`)}
)}
{providers.map((p) => (

{p.name}

{p.connected && p.providerUserId && (

{t("settings.services.connectedAs", { id: p.providerUserId })}

)}
{p.connected ? (
{t("sync.import")}
) : ( {t("settings.services.connect")} )}
))}
); }