Files
claudecodeui/src/components/prd-editor/hooks/usePrdRegistry.ts
Haileyesus f68600bb76 refactor(prd-editor): modularize PRD editor with typed feature modules
Break the legacy PRDEditor.jsx monolith into a feature-based TypeScript architecture under src/components/prd-editor while keeping behavior parity and readability.

Key changes:

- Replace PRDEditor.jsx with a typed orchestrator component and a compatibility export bridge at src/components/PRDEditor.tsx.

- Split responsibilities into dedicated hooks: document loading/init, existing PRD registry fetching, save workflow with overwrite detection, and keyboard shortcuts.

- Split UI into focused view components: header, editor/preview body, footer stats, loading state, generate-tasks modal, and overwrite-confirm modal.

- Move filename concerns into utility helpers (sanitize, extension handling, default naming) and centralize template/constants.

- Keep component-local state close to the UI that owns it (workspace controls/modal toggles), while shared workflow state remains in the feature container.

- Reuse the existing MarkdownPreview component for safer markdown rendering instead of ad-hoc HTML conversion.

- Update TaskMasterPanel integration to consume typed PRDEditor directly (remove any-cast) and pass isExisting metadata for correct overwrite behavior.

- Keep all new/changed files below 300 lines and add targeted comments where behavior needs clarification.

Validation:

- npm run typecheck

- npm run build
2026-03-05 13:11:38 +03:00

51 lines
1.3 KiB
TypeScript

import { useCallback, useEffect, useState } from 'react';
import { api } from '../../../utils/api';
import type { ExistingPrdFile, PrdListResponse } from '../types';
type UsePrdRegistryArgs = {
projectName?: string;
};
type UsePrdRegistryResult = {
existingPrds: ExistingPrdFile[];
refreshExistingPrds: () => Promise<void>;
};
function getPrdFiles(data: PrdListResponse): ExistingPrdFile[] {
return data.prdFiles || data.prds || [];
}
export function usePrdRegistry({ projectName }: UsePrdRegistryArgs): UsePrdRegistryResult {
const [existingPrds, setExistingPrds] = useState<ExistingPrdFile[]>([]);
const refreshExistingPrds = useCallback(async () => {
if (!projectName) {
setExistingPrds([]);
return;
}
try {
const response = await api.get(`/taskmaster/prd/${encodeURIComponent(projectName)}`);
if (!response.ok) {
setExistingPrds([]);
return;
}
const data = (await response.json()) as PrdListResponse;
setExistingPrds(getPrdFiles(data));
} catch (error) {
console.error('Failed to fetch existing PRDs:', error);
setExistingPrds([]);
}
}, [projectName]);
useEffect(() => {
void refreshExistingPrds();
}, [refreshExistingPrds]);
return {
existingPrds,
refreshExistingPrds,
};
}