Point the import-guide links at the docs site that actually has them

Both import cards linked /docs/integrations/data-import — a path the
app never serves, so every click 404'd. Link the external docs site
through the shared INTEGRATION_DOCS_BASE constant, opening in a new tab
like every other integrations runbook link.
This commit is contained in:
Marc-André Bombeck committed 2026-08-14 01:54:10 +02:00
1 parent c23e677b6e
commit 15fb5dbbdb
3 files changed
+46 -8

No files matched your search

@@ -0,0 +1,30 @@
/**
* The import cards' "docs" links must point at the external docs site.
*
* The app serves no `/docs` tree, so the old internal
* `/docs/integrations/data-import` href 404'd for every user who
* clicked it. The guide lives at `docs.healthlog.dev`; the link goes
* through `INTEGRATION_DOCS_BASE` so the host lives in exactly one
* place (the same constant every Settings → Integrations card uses).
*
* Watched red: restoring `href="/docs/integrations/data-import"` in
* either card fails the matching assertion below.
*/
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
const CARDS = ["csv-import-card.tsx", "json-import-card.tsx"] as const;
describe("import-card docs links", () => {
for (const card of CARDS) {
it(`${card} links the external docs site, never an internal /docs path`, () => {
const source = readFileSync(join(__dirname, "..", card), "utf8");
expect(source).not.toContain('href="/docs');
expect(source).toContain("INTEGRATION_DOCS_BASE");
expect(source).toContain("data-import");
// External link hygiene for a new-tab docs jump.
expect(source).toContain('rel="noopener noreferrer"');
});
}
});
@@ -1,7 +1,6 @@
"use client";
import { useId, useRef, useState } from "react";
import Link from "next/link";
import {
AlertCircle,
Download,
@@ -15,6 +14,7 @@ import { SettingsCardActions } from "@/components/settings/_card-actions";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { useTranslations } from "@/lib/i18n/context";
import { INTEGRATION_DOCS_BASE } from "@/components/settings/integrations/setup-guide-link";
import { apiFetchRaw } from "@/lib/api/api-fetch";
import { ImportCardShell } from "./import-card-shell";
import { MAX_PASTE_CHARS } from "./constants";
@@ -151,12 +151,16 @@ export function CsvImportCard() {
<p className="text-muted-foreground text-xs">
{t("settings.sections.export.import.csv.schemaHint")}{" "}
<Link
href="/docs/integrations/data-import"
{/* The import guide lives on the external docs site — the app
itself serves no /docs tree, so an internal link 404s. */}
<a
href={`${INTEGRATION_DOCS_BASE}/data-import`}
target="_blank"
rel="noopener noreferrer"
className="text-primary underline underline-offset-2"
>
{t("settings.sections.export.import.csv.docsLink")}
</Link>
</a>
</p>
<div aria-live="polite" className="space-y-2">
@@ -1,7 +1,6 @@
"use client";
import { useId, useRef, useState } from "react";
import Link from "next/link";
import { AlertCircle, Download, FileJson, Loader2, Upload } from "lucide-react";
import { Button } from "@/components/ui/button";
@@ -9,6 +8,7 @@ import { SettingsCardActions } from "@/components/settings/_card-actions";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { useTranslations } from "@/lib/i18n/context";
import { INTEGRATION_DOCS_BASE } from "@/components/settings/integrations/setup-guide-link";
import { apiFetchRaw } from "@/lib/api/api-fetch";
import { ImportCardShell } from "./import-card-shell";
import { MAX_PASTE_CHARS } from "./constants";
@@ -167,12 +167,16 @@ export function JsonImportCard() {
<p className="text-muted-foreground text-xs">
{t("settings.sections.export.import.json.schemaHint")}{" "}
<Link
href="/docs/integrations/data-import"
{/* The import guide lives on the external docs site — the app
itself serves no /docs tree, so an internal link 404s. */}
<a
href={`${INTEGRATION_DOCS_BASE}/data-import`}
target="_blank"
rel="noopener noreferrer"
className="text-primary underline underline-offset-2"
>
{t("settings.sections.export.import.json.docsLink")}
</Link>
</a>
</p>
<div aria-live="polite" className="space-y-2">