Load rule templates from API

This commit is contained in:
adilallo
2026-04-12 21:56:34 -06:00
parent cae4df261e
commit a39b4aa04b
17 changed files with 698 additions and 429 deletions
@@ -1,8 +1,15 @@
"use client";
import { memo } from "react";
import { memo, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { logger } from "../../../../lib/logger";
import {
fetchTemplates,
isTemplatesFetchAborted,
} from "../../../../lib/create/fetchTemplates";
import { GOVERNANCE_TEMPLATE_HOME_SLUGS } from "../../../../lib/templates/governanceTemplateCatalog";
import { gridEntriesForSlugOrderWithCatalogFallback } from "../../../../lib/templates/templateGridPresentation";
import type { TemplateGridCardEntry } from "../../../../lib/templates/templateGridPresentation";
import { RuleStackView } from "./RuleStack.view";
import type { RuleStackProps } from "./RuleStack.types";
@@ -19,8 +26,53 @@ declare global {
}
}
const RuleStackContainer = memo<RuleStackProps>(({ className = "" }) => {
const RuleStackContainer = memo<RuleStackProps>(
({ className = "", initialGridEntries }) => {
const router = useRouter();
const [gridEntries, setGridEntries] = useState<TemplateGridCardEntry[] | null>(
() => initialGridEntries ?? null,
);
useEffect(() => {
if (initialGridEntries !== undefined) {
return;
}
const ac = new AbortController();
let cancelled = false;
void (async () => {
try {
const result = await fetchTemplates({ signal: ac.signal });
if (cancelled) return;
if ("error" in result) {
setGridEntries(
gridEntriesForSlugOrderWithCatalogFallback(
[],
GOVERNANCE_TEMPLATE_HOME_SLUGS,
),
);
return;
}
setGridEntries(
gridEntriesForSlugOrderWithCatalogFallback(
result,
GOVERNANCE_TEMPLATE_HOME_SLUGS,
),
);
} catch (e) {
if (cancelled || isTemplatesFetchAborted(e)) return;
setGridEntries(
gridEntriesForSlugOrderWithCatalogFallback(
[],
GOVERNANCE_TEMPLATE_HOME_SLUGS,
),
);
}
})();
return () => {
cancelled = true;
ac.abort();
};
}, [initialGridEntries]);
const handleTemplateClick = (slug: string) => {
// Basic analytics tracking
@@ -44,9 +96,11 @@ const RuleStackContainer = memo<RuleStackProps>(({ className = "" }) => {
<RuleStackView
className={className}
onTemplateClick={handleTemplateClick}
gridEntries={gridEntries}
/>
);
});
},
);
RuleStackContainer.displayName = "RuleStack";