62 lines
2.3 KiB
TypeScript
62 lines
2.3 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import ReactMarkdown from 'react-markdown';
|
|
import remarkGfm from 'remark-gfm';
|
|
import rehypeRaw from 'rehype-raw';
|
|
import { useClient } from 'hooks/useClient';
|
|
import { Card } from '@/components/Card';
|
|
export const Plans = () => {
|
|
const client = useClient();
|
|
const [selectedPlan, setSelectedPlan] = useState<string | null>(null);
|
|
|
|
const { data: plans = [] } = useQuery<string[]>({
|
|
queryKey: ['plans'],
|
|
queryFn: () => client.get<string[]>('/plans'),
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (plans.length > 0 && !selectedPlan) {
|
|
setSelectedPlan(plans[0]!);
|
|
}
|
|
}, [plans, selectedPlan]);
|
|
|
|
const { data: content = '' } = useQuery<string>({
|
|
queryKey: ['plans', selectedPlan],
|
|
queryFn: () => client.getText(`/plans/${selectedPlan}`),
|
|
enabled: !!selectedPlan,
|
|
});
|
|
|
|
return (
|
|
<div className="flex flex-col h-full p-4">
|
|
<Card className="flex-1 overflow-hidden">
|
|
{/* Header with plan selector */}
|
|
<div className="shrink-0 flex items-center gap-3 px-4 py-2 border-b border-duck-dark/10 bg-background/60">
|
|
<span className="text-sm font-medium text-duck-dark/70">Plans</span>
|
|
{plans.length > 1 && (
|
|
<select
|
|
value={selectedPlan ?? ''}
|
|
onChange={(ev) => setSelectedPlan(ev.target.value)}
|
|
className="text-xs border border-duck-dark/20 rounded px-2 py-1 bg-background/80 text-duck-dark"
|
|
>
|
|
{plans.map((p) => (
|
|
<option key={p} value={p}>
|
|
{p}
|
|
</option>
|
|
))}
|
|
</select>
|
|
)}
|
|
</div>
|
|
|
|
{/* Markdown content */}
|
|
<div className="overflow-y-auto h-full p-6">
|
|
<div className="prose prose-sm dark:prose-invert max-w-none prose-headings:text-duck-dark prose-a:text-duck-teal prose-pre:bg-gray-900 prose-pre:text-green-400 prose-code:text-duck-teal prose-code:before:content-none prose-code:after:content-none prose-td:text-sm prose-th:text-sm">
|
|
<ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
|
|
{content}
|
|
</ReactMarkdown>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|