Files
ai-contract-platform/frontend/scripts/simplify-page.py
T
yuqei b76a2baad2 feat: comprehensive platform improvements (P0-P2 + landing split)
- Split landing page into public landing page and authenticated workspace
- Extract contract generation logic into use-contract-generation hook
- Extract contract generation service into sub-services
- Add AI quality scoring for contract generation
- Expand risk rules library with employment-specific rules
- Add custom exception classes (NotFoundError, ValidationError, etc.)
- Add prompt asset seeding script from LexForge documentation
- Add format utility library
- Fix SSR hydration mismatch on Ant Design inputs

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 17:39:27 +08:00

150 lines
6.4 KiB
Python

#!/usr/bin/env python3
"""Simplify contracts page to use the useContractGeneration hook."""
import re
with open('src/app/contracts/page.tsx', 'r', encoding='utf-8') as f:
content = f.read()
# 1. Replace the component function header
old_header = """export default function ContractsPage() {
const [messageApi, contextHolder] = message.useMessage();
const [form] = Form.useForm<ContractFormValues>();
const router = useRouter();
const currentUser = useAuthStore((state) => state.currentUser);
const searchParams = useSearchParams();
const restorePayload = useMemo(() => parseRestorePayload(searchParams.get("restore")), [searchParams]);
const reviewContext = useMemo(() => parseReviewContextPayload(searchParams.get("review")), [searchParams]);
const [templateLoading, setTemplateLoading] = useState(true);
const [historyLoading, setHistoryLoading] = useState(true);
const [generating, setGenerating] = useState(false);
const [previewing, setPreviewing] = useState(false);
const [downloadingCurrent, setDownloadingCurrent] = useState(false);
const [historyDownloadingId, setHistoryDownloadingId] = useState<string | null>(null);
const [currentStep, setCurrentStep] = useState(0);
const [templates, setTemplates] = useState<ContractTemplate[]>([]);
const [selectedTemplate, setSelectedTemplate] = useState<ContractTemplate | null>(null);
const [templateCategoryFilter, setTemplateCategoryFilter] = useState<string | undefined>(undefined);
const [industryCategoryFilter, setIndustryCategoryFilter] = useState<string | undefined>(undefined);
const [previewResult, setPreviewResult] = useState<ContractPreview | null>(null);
const [generatedContract, setGeneratedContract] = useState<GeneratedContract | null>(null);
const [historyContracts, setHistoryContracts] = useState<GeneratedContractListItem[]>([]);
const [historyKeyword, setHistoryKeyword] = useState("");
const [historyContractType, setHistoryContractType] = useState<string | undefined>(undefined);
const [historyLifecycleStatus, setHistoryLifecycleStatus] = useState<string | undefined>(undefined);
const [historyPage, setHistoryPage] = useState(1);
const [historyPageSize, setHistoryPageSize] = useState(10);
const [historyTotal, setHistoryTotal] = useState(0);
const [restoredOptions, setRestoredOptions] = useState<Record<string, unknown>>({});
const [appliedRestoreValue, setAppliedRestoreValue] = useState<string | null>(null);
const [lifecycleUpdating, setLifecycleUpdating] = useState(false);
const [historyCollapsed, setHistoryCollapsed] = useState(true);
const canDownloadContracts = currentUser?.role === "admin";"""
new_header = """export default function ContractsPage() {
const [form] = Form.useForm<ContractFormValues>();
const {
messageApi, contextHolder, router, currentUser, reviewContext, restorePayload,
templateLoading, historyLoading, generating, previewing, downloadingCurrent, historyDownloadingId,
currentStep, templates, selectedTemplate, templateCategoryFilter, industryCategoryFilter,
previewResult, generatedContract, historyContracts, historyKeyword, historyContractType,
historyLifecycleStatus, historyPage, historyPageSize, historyTotal, restoredOptions,
lifecycleUpdating, historyCollapsed, canDownloadContracts, contractTypeOptions,
setTemplateCategoryFilter, setIndustryCategoryFilter, setCurrentStep, setHistoryKeyword,
setHistoryContractType, setHistoryLifecycleStatus, setHistoryPage, setHistoryPageSize,
setHistoryCollapsed,
handleTemplateSelect, handlePreview, handleGenerate, handleDownload,
handleHistoryDownload, handleHistorySearch, handleHistoryFilterChange,
handleHistoryLifecycleFilterChange, handleHistoryReset, handleHistoryTableChange,
handleReset, handleLifecycleTransition, loadHistory, clearRestoreQuery,
} = useContractGeneration(form);"""
content = content.replace(old_header, new_header, 1)
# 2. Remove helper function blocks that are now in the hook
helper_funcs = [
'clearRestoreQuery',
'applyTemplateSelection',
'loadTemplates',
'loadHistory',
'contractTypeOptions',
'handleTemplateSelect',
'handlePreview',
'handleGenerate',
'handleDownload',
'handleHistoryDownload',
'handleHistorySearch',
'handleHistoryFilterChange',
'handleHistoryLifecycleFilterChange',
'handleHistoryReset',
'handleHistoryTableChange',
'handleReset',
'handleLifecycleTransition',
'handleOpenAutoReviewDetail',
'handleOpenAutoReviewChat',
'handleDownloadAutoReviewReport',
'handleOpenLifecycleModal',
'handleUpdateLifecycle',
]
# Find all lines that are function declarations and remove their bodies
lines = content.split('\n')
result = []
in_func = False
func_indent = 0
func_name = ''
for line in lines:
stripped = line.strip()
# Check if this line starts a handler function
detected_func = None
for fn in helper_funcs:
# Match patterns like: const fnName = ..., const fnName = useCallback(..., function fnName(
pattern1 = f'const {fn} = '
pattern2 = f'const {fn}:'
pattern3 = f'function {fn}('
# Also handle const { fn } = ... destructuring
if stripped.startswith(pattern1) or stripped.startswith(pattern2) or stripped.startswith(pattern3):
detected_func = fn
break
if detected_func and not in_func:
in_func = True
func_indent = len(line) - len(stripped)
func_name = detected_func
continue
if in_func:
current_indent = len(line) - len(stripped) if stripped else func_indent + 4
if stripped and current_indent <= func_indent and not stripped.startswith('//'):
in_func = False
result.append(line)
continue
continue
result.append(line)
# 3. Remove type/func definitions that moved to the hook
content = '\n'.join(result)
# Remove type definitions and helpers that migrated to the hook
removals = [
('type RefillPayload', '};'),
('type ReviewContextPayload', '};'),
('const GENERATE_RECOVERY_TIMEOUT_MS', ';'),
]
for start_pattern, end_marker in removals:
idx = content.find(start_pattern)
if idx >= 0:
end_idx = content.find(end_marker, idx) + len(end_marker)
# Find the next blank line or code
rest = content[end_idx:]
next_line = rest.find('\n')
content = content[:idx] + rest[next_line:]
with open('src/app/contracts/page.tsx', 'w', encoding='utf-8') as f:
f.write(content)
print('Done')
"