"use client";
import { useEffect, useState } from "react";
import { useTranslations } from "next-intl";
import ReactMarkdown, { type Components } from "react-markdown";
import { Modal, Button } from "@/shared/components";
const markdownComponents: Components = {
h1({ children }) {
return
{children}
;
},
h2({ children }) {
return (
terminal
{children}
);
},
h3({ children }) {
return {children}
;
},
h4({ children }) {
return (
{children}
);
},
p({ children }) {
return {children}
;
},
ul({ children }) {
return ;
},
ol({ children }) {
return {children}
;
},
li({ children }) {
return (
{children}
);
},
strong({ children }) {
return {children};
},
code({ children, className }) {
const isBlock = className?.includes("language-");
if (isBlock) {
return (
{children}
);
}
return (
{children}
);
},
pre({ children }) {
return (
{children}
);
},
blockquote({ children }) {
return (
{children}
);
},
table({ children }) {
return (
);
},
thead({ children }) {
return {children};
},
tr({ children }) {
return {children}
;
},
th({ children }) {
return {children} | ;
},
td({ children }) {
return {children} | ;
},
hr() {
return
;
},
a({ href, children }) {
if (!href) return {children};
return (
{children}
);
},
};
interface CodexCliGuideModalProps {
isOpen: boolean;
onClose: () => void;
}
export default function CodexCliGuideModal({ isOpen, onClose }: CodexCliGuideModalProps) {
const t = useTranslations("providers");
const tc = useTranslations("common");
const [content, setContent] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const text = (key: string, fallback: string) =>
typeof t.has === "function" && t.has(key as never) ? t(key as never) : fallback;
useEffect(() => {
if (!isOpen || content) return;
let cancelled = false;
const load = async () => {
setLoading(true);
setError(false);
try {
const res = await fetch("/api/docs/codex-cli");
if (!res.ok) throw new Error(`${res.status}`);
const data = (await res.json()) as { content: string };
if (!cancelled) setContent(data.content);
} catch {
if (!cancelled) setError(true);
} finally {
if (!cancelled) setLoading(false);
}
};
void load();
return () => {
cancelled = true;
};
}, [isOpen, content]);
return (
{loading && (
sync
{text("codexCliGuideLoading", "Loading guide...")}
)}
{error && (
error_outline
{text("codexCliGuideLoadFailed", "Could not load the guide.")}
)}
{!loading && !error && content && (
{content}
)}
);
}