From 39657859afc79d432af8c3713f7d9b2c33379542 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sun, 18 Jan 2026 00:31:21 +0000 Subject: [PATCH] Refactor ErrorPanel into subcomponents --- src/components/ErrorPanel.tsx | 413 +++--------------- .../error-panel/ErrorPanelEmptyState.tsx | 36 ++ .../error-panel/ErrorPanelErrorItem.tsx | 104 +++++ .../error-panel/ErrorPanelFileCard.tsx | 88 ++++ .../error-panel/ErrorPanelFileList.tsx | 67 +++ .../error-panel/ErrorPanelHeader.tsx | 80 ++++ .../error-panel/error-panel-repair.ts | 142 ++++++ .../error-panel/error-panel-scan.ts | 48 ++ .../error-panel/useErrorPanelState.ts | 64 +++ src/data/error-panel.json | 47 ++ 10 files changed, 734 insertions(+), 355 deletions(-) create mode 100644 src/components/error-panel/ErrorPanelEmptyState.tsx create mode 100644 src/components/error-panel/ErrorPanelErrorItem.tsx create mode 100644 src/components/error-panel/ErrorPanelFileCard.tsx create mode 100644 src/components/error-panel/ErrorPanelFileList.tsx create mode 100644 src/components/error-panel/ErrorPanelHeader.tsx create mode 100644 src/components/error-panel/error-panel-repair.ts create mode 100644 src/components/error-panel/error-panel-scan.ts create mode 100644 src/components/error-panel/useErrorPanelState.ts create mode 100644 src/data/error-panel.json diff --git a/src/components/ErrorPanel.tsx b/src/components/ErrorPanel.tsx index 6e59f26..109e2f6 100644 --- a/src/components/ErrorPanel.tsx +++ b/src/components/ErrorPanel.tsx @@ -1,38 +1,10 @@ -import { useState, useEffect } from 'react' -import { CodeError } from '@/types/errors' -import { ProjectFile } from '@/types/project' -import { ErrorRepairService } from '@/lib/error-repair-service' -import { Card } from '@/components/ui/card' import { ScrollArea } from '@/components/ui/scroll-area' -import { - Warning, - X, - Wrench, - CheckCircle, - Info, - Lightning, - FileCode, - ArrowRight -} from '@phosphor-icons/react' -import { toast } from 'sonner' -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from '@/components/ui/collapsible' -import { - Badge, - ActionButton, - Stack, - Flex, - Heading, - Text, - EmptyState, - IconText, - Code, - StatusIcon, - PanelHeader -} from '@/components/atoms' +import errorPanelCopy from '@/data/error-panel.json' +import { ProjectFile } from '@/types/project' +import { ErrorPanelHeader } from '@/components/error-panel/ErrorPanelHeader' +import { ErrorPanelEmptyState } from '@/components/error-panel/ErrorPanelEmptyState' +import { ErrorPanelFileList } from '@/components/error-panel/ErrorPanelFileList' +import { useErrorPanelState } from '@/components/error-panel/useErrorPanelState' interface ErrorPanelProps { files: ProjectFile[] @@ -41,337 +13,68 @@ interface ErrorPanelProps { } export function ErrorPanel({ files, onFileChange, onFileSelect }: ErrorPanelProps) { - const [errors, setErrors] = useState([]) - const [isScanning, setIsScanning] = useState(false) - const [isRepairing, setIsRepairing] = useState(false) - const [autoRepairEnabled, setAutoRepairEnabled] = useState(false) - const [expandedErrors, setExpandedErrors] = useState>(new Set()) - - const scanForErrors = async () => { - setIsScanning(true) - try { - const allErrors: CodeError[] = [] - - for (const file of files) { - const fileErrors = await ErrorRepairService.detectErrors(file) - allErrors.push(...fileErrors) - } - - setErrors(allErrors) - - if (allErrors.length === 0) { - toast.success('No errors found!') - } else { - toast.info(`Found ${allErrors.length} issue${allErrors.length > 1 ? 's' : ''}`) - } - } catch (error) { - toast.error('Error scanning failed') - console.error(error) - } finally { - setIsScanning(false) - } - } - - const repairSingleError = async (error: CodeError) => { - const file = files.find(f => f.id === error.fileId) - if (!file) return - - setIsRepairing(true) - try { - const result = await ErrorRepairService.repairCode(file, [error]) - - if (result.success && result.fixedCode) { - onFileChange(file.id, result.fixedCode) - - setErrors(prev => prev.map(e => - e.id === error.id ? { ...e, isFixed: true, fixedCode: result.fixedCode } : e - )) - - toast.success(`Fixed: ${error.message}`, { - description: result.explanation, - }) - - await scanForErrors() - } else { - toast.error('Failed to repair error') - } - } catch (error) { - toast.error('Repair failed') - console.error(error) - } finally { - setIsRepairing(false) - } - } - - const repairAllErrors = async () => { - setIsRepairing(true) - try { - const results = await ErrorRepairService.repairMultipleFiles(files, errors) - - let fixedCount = 0 - results.forEach((result, fileId) => { - if (result.success && result.fixedCode) { - onFileChange(fileId, result.fixedCode) - fixedCount++ - } - }) - - if (fixedCount > 0) { - toast.success(`Repaired ${fixedCount} file${fixedCount > 1 ? 's' : ''}`) - await scanForErrors() - } else { - toast.error('No files could be repaired') - } - } catch (error) { - toast.error('Batch repair failed') - console.error(error) - } finally { - setIsRepairing(false) - } - } - - const repairFileWithContext = async (fileId: string) => { - const file = files.find(f => f.id === fileId) - if (!file) return - - const fileErrors = errors.filter(e => e.fileId === fileId) - if (fileErrors.length === 0) return - - setIsRepairing(true) - try { - const relatedFiles = files.filter(f => f.id !== fileId).slice(0, 3) - - const result = await ErrorRepairService.repairWithContext(file, fileErrors, relatedFiles) - - if (result.success && result.fixedCode) { - onFileChange(file.id, result.fixedCode) - - toast.success(`Repaired ${file.name}`, { - description: result.explanation, - }) - - await scanForErrors() - } else { - toast.error('Failed to repair file') - } - } catch (error) { - toast.error('Context-aware repair failed') - console.error(error) - } finally { - setIsRepairing(false) - } - } - - const toggleErrorExpanded = (errorId: string) => { - setExpandedErrors(prev => { - const next = new Set(prev) - if (next.has(errorId)) { - next.delete(errorId) - } else { - next.add(errorId) - } - return next - }) - } - - const getSeverityIcon = (severity: string) => { - switch (severity) { - case 'error': - return - case 'warning': - return - case 'info': - return - default: - return - } - } - - const getSeverityColor = (severity: string) => { - switch (severity) { - case 'error': - return 'destructive' - case 'warning': - return 'secondary' - case 'info': - return 'outline' - default: - return 'outline' - } - } - - const errorsByFile = errors.reduce((acc, error) => { - if (!acc[error.fileId]) { - acc[error.fileId] = [] - } - acc[error.fileId].push(error) - return acc - }, {} as Record) - - const errorCount = errors.filter(e => e.severity === 'error').length - const warningCount = errors.filter(e => e.severity === 'warning').length - - useEffect(() => { - if (files.length > 0 && errors.length === 0) { - scanForErrors() - } - }, []) + const { + errors, + errorsByFile, + errorCount, + warningCount, + isScanning, + isRepairing, + scanForErrors, + repairAllErrors, + repairFileWithContext, + repairSingleError, + } = useErrorPanelState({ files, onFileChange }) return (
-
- - - }> - Error Detection & Repair - - {errors.length > 0 && ( - - {errorCount > 0 && ( - - {errorCount} {errorCount === 1 ? 'Error' : 'Errors'} - - )} - {warningCount > 0 && ( - - {warningCount} {warningCount === 1 ? 'Warning' : 'Warnings'} - - )} - - )} - - - } - label={isScanning ? 'Scanning...' : 'Scan'} - onClick={scanForErrors} - disabled={isScanning || isRepairing} - variant="outline" - /> - } - label={isRepairing ? 'Repairing...' : 'Repair All'} - onClick={repairAllErrors} - disabled={errors.length === 0 || isRepairing || isScanning} - variant="default" - /> - - -
+
- {errors.length === 0 && !isScanning && ( - } - title="No Issues Found" - description="All files are looking good! Click 'Scan' to check again." - /> - )} - - {isScanning && ( - } - title="Scanning Files..." - description="Analyzing your code for errors and issues" + {errors.length === 0 && ( + )} {errors.length > 0 && ( - - {Object.entries(errorsByFile).map(([fileId, fileErrors]) => { - const file = files.find(f => f.id === fileId) - if (!file) return null - - return ( - -
- - - - {file.name} - - {fileErrors.length} {fileErrors.length === 1 ? 'issue' : 'issues'} - - - - } - label="Open" - onClick={() => onFileSelect(fileId)} - variant="outline" - size="sm" - /> - } - label="Repair" - onClick={() => repairFileWithContext(fileId)} - disabled={isRepairing} - variant="default" - size="sm" - /> - - -
- -
- {fileErrors.map((error) => ( - -
-
- {getSeverityIcon(error.severity)} -
-
- - - {error.type} - - {error.line && ( - - Line {error.line} - - )} - {error.isFixed && ( - - - Fixed - - )} - - {error.message} - {error.code && ( - - - - )} -
- } - label="" - onClick={() => repairSingleError(error)} - disabled={isRepairing || error.isFixed} - variant="outline" - size="sm" - /> -
- {error.code && ( - -
- {error.code} -
-
- )} -
- ))} -
-
- ) - })} -
+ )}
diff --git a/src/components/error-panel/ErrorPanelEmptyState.tsx b/src/components/error-panel/ErrorPanelEmptyState.tsx new file mode 100644 index 0000000..6368019 --- /dev/null +++ b/src/components/error-panel/ErrorPanelEmptyState.tsx @@ -0,0 +1,36 @@ +import { CheckCircle, Lightning } from '@phosphor-icons/react' +import { EmptyState } from '@/components/atoms' + +interface ErrorPanelEmptyStateProps { + isScanning: boolean + noIssuesTitle: string + noIssuesDescription: string + scanningTitle: string + scanningDescription: string +} + +export function ErrorPanelEmptyState({ + isScanning, + noIssuesTitle, + noIssuesDescription, + scanningTitle, + scanningDescription, +}: ErrorPanelEmptyStateProps) { + if (isScanning) { + return ( + } + title={scanningTitle} + description={scanningDescription} + /> + ) + } + + return ( + } + title={noIssuesTitle} + description={noIssuesDescription} + /> + ) +} diff --git a/src/components/error-panel/ErrorPanelErrorItem.tsx b/src/components/error-panel/ErrorPanelErrorItem.tsx new file mode 100644 index 0000000..0a9f4bb --- /dev/null +++ b/src/components/error-panel/ErrorPanelErrorItem.tsx @@ -0,0 +1,104 @@ +import { useState } from 'react' +import { CheckCircle, Info, Warning, Wrench, X } from '@phosphor-icons/react' +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' +import { ActionButton, Badge, Code, Flex, Text } from '@/components/atoms' +import { CodeError } from '@/types/errors' + +interface ErrorPanelErrorItemProps { + error: CodeError + isRepairing: boolean + lineLabel: string + fixedLabel: string + showCodeLabel: string + hideCodeLabel: string + onRepair: (error: CodeError) => void +} + +const getSeverityIcon = (severity: string) => { + switch (severity) { + case 'error': + return + case 'warning': + return + case 'info': + return + default: + return + } +} + +const getSeverityColor = (severity: string) => { + switch (severity) { + case 'error': + return 'destructive' + case 'warning': + return 'secondary' + case 'info': + return 'outline' + default: + return 'outline' + } +} + +export function ErrorPanelErrorItem({ + error, + isRepairing, + lineLabel, + fixedLabel, + showCodeLabel, + hideCodeLabel, + onRepair, +}: ErrorPanelErrorItemProps) { + const [isExpanded, setIsExpanded] = useState(false) + + return ( + +
+
{getSeverityIcon(error.severity)}
+
+ + + {error.type} + + {error.line && ( + + {lineLabel} {error.line} + + )} + {error.isFixed && ( + + + {fixedLabel} + + )} + + + {error.message} + + {error.code && ( + + + + )} +
+ } + label="" + onClick={() => onRepair(error)} + disabled={isRepairing || error.isFixed} + variant="outline" + size="sm" + /> +
+ {error.code && ( + +
+ {error.code} +
+
+ )} +
+ ) +} diff --git a/src/components/error-panel/ErrorPanelFileCard.tsx b/src/components/error-panel/ErrorPanelFileCard.tsx new file mode 100644 index 0000000..be3dc2c --- /dev/null +++ b/src/components/error-panel/ErrorPanelFileCard.tsx @@ -0,0 +1,88 @@ +import { ArrowRight, FileCode, Wrench } from '@phosphor-icons/react' +import { Card } from '@/components/ui/card' +import { ActionButton, Badge, Flex, Text } from '@/components/atoms' +import { CodeError } from '@/types/errors' +import { ProjectFile } from '@/types/project' +import { ErrorPanelErrorItem } from './ErrorPanelErrorItem' + +interface ErrorPanelFileCardProps { + file: ProjectFile + errors: CodeError[] + issueLabel: string + issuesLabel: string + openLabel: string + repairLabel: string + lineLabel: string + fixedLabel: string + showCodeLabel: string + hideCodeLabel: string + isRepairing: boolean + onFileSelect: (fileId: string) => void + onRepairFile: (fileId: string) => void + onRepairError: (error: CodeError) => void +} + +export function ErrorPanelFileCard({ + file, + errors, + issueLabel, + issuesLabel, + openLabel, + repairLabel, + lineLabel, + fixedLabel, + showCodeLabel, + hideCodeLabel, + isRepairing, + onFileSelect, + onRepairFile, + onRepairError, +}: ErrorPanelFileCardProps) { + return ( + +
+ + + + {file.name} + + {errors.length} {errors.length === 1 ? issueLabel : issuesLabel} + + + + } + label={openLabel} + onClick={() => onFileSelect(file.id)} + variant="outline" + size="sm" + /> + } + label={repairLabel} + onClick={() => onRepairFile(file.id)} + disabled={isRepairing} + variant="default" + size="sm" + /> + + +
+ +
+ {errors.map((error) => ( + + ))} +
+
+ ) +} diff --git a/src/components/error-panel/ErrorPanelFileList.tsx b/src/components/error-panel/ErrorPanelFileList.tsx new file mode 100644 index 0000000..b609534 --- /dev/null +++ b/src/components/error-panel/ErrorPanelFileList.tsx @@ -0,0 +1,67 @@ +import { Stack } from '@/components/atoms' +import { CodeError } from '@/types/errors' +import { ProjectFile } from '@/types/project' +import { ErrorPanelFileCard } from './ErrorPanelFileCard' + +interface ErrorPanelFileListProps { + files: ProjectFile[] + errorsByFile: Record + issueLabel: string + issuesLabel: string + openLabel: string + repairLabel: string + lineLabel: string + fixedLabel: string + showCodeLabel: string + hideCodeLabel: string + isRepairing: boolean + onFileSelect: (fileId: string) => void + onRepairFile: (fileId: string) => void + onRepairError: (error: CodeError) => void +} + +export function ErrorPanelFileList({ + files, + errorsByFile, + issueLabel, + issuesLabel, + openLabel, + repairLabel, + lineLabel, + fixedLabel, + showCodeLabel, + hideCodeLabel, + isRepairing, + onFileSelect, + onRepairFile, + onRepairError, +}: ErrorPanelFileListProps) { + return ( + + {Object.entries(errorsByFile).map(([fileId, fileErrors]) => { + const file = files.find((entry) => entry.id === fileId) + if (!file) return null + + return ( + + ) + })} + + ) +} diff --git a/src/components/error-panel/ErrorPanelHeader.tsx b/src/components/error-panel/ErrorPanelHeader.tsx new file mode 100644 index 0000000..06a8951 --- /dev/null +++ b/src/components/error-panel/ErrorPanelHeader.tsx @@ -0,0 +1,80 @@ +import { Lightning, Wrench } from '@phosphor-icons/react' +import { Badge, ActionButton, Flex, Heading, IconText } from '@/components/atoms' + +interface ErrorPanelHeaderProps { + title: string + scanLabel: string + scanningLabel: string + repairAllLabel: string + repairingLabel: string + errorCount: number + warningCount: number + errorLabel: string + errorsLabel: string + warningLabel: string + warningsLabel: string + isScanning: boolean + isRepairing: boolean + onScan: () => void + onRepairAll: () => void +} + +export function ErrorPanelHeader({ + title, + scanLabel, + scanningLabel, + repairAllLabel, + repairingLabel, + errorCount, + warningCount, + errorLabel, + errorsLabel, + warningLabel, + warningsLabel, + isScanning, + isRepairing, + onScan, + onRepairAll, +}: ErrorPanelHeaderProps) { + return ( +
+ + + }> + {title} + + {(errorCount > 0 || warningCount > 0) && ( + + {errorCount > 0 && ( + + {errorCount} {errorCount === 1 ? errorLabel : errorsLabel} + + )} + {warningCount > 0 && ( + + {warningCount} {warningCount === 1 ? warningLabel : warningsLabel} + + )} + + )} + + + } + label={isScanning ? scanningLabel : scanLabel} + onClick={onScan} + disabled={isScanning || isRepairing} + variant="outline" + /> + } + label={isRepairing ? repairingLabel : repairAllLabel} + onClick={onRepairAll} + disabled={errorCount + warningCount === 0 || isRepairing || isScanning} + variant="default" + /> + + +
+ ) +} diff --git a/src/components/error-panel/error-panel-repair.ts b/src/components/error-panel/error-panel-repair.ts new file mode 100644 index 0000000..415b214 --- /dev/null +++ b/src/components/error-panel/error-panel-repair.ts @@ -0,0 +1,142 @@ +import type { Dispatch, SetStateAction } from 'react' +import { toast } from 'sonner' +import { CodeError } from '@/types/errors' +import { ProjectFile } from '@/types/project' +import { ErrorRepairService } from '@/lib/error-repair-service' +import errorPanelCopy from '@/data/error-panel.json' + +const formatWithCount = (template: string, count: number) => + template + .replace('{count}', String(count)) + .replace('{plural}', count === 1 ? '' : 's') + +const formatWithValue = (template: string, token: string, value: string) => + template.replace(token, value) + +interface RepairHandlersParams { + files: ProjectFile[] + errors: CodeError[] + onFileChange: (fileId: string, content: string) => void + scanForErrors: () => Promise + setErrors: Dispatch> + setIsRepairing: Dispatch> +} + +export function createRepairHandlers({ + files, + errors, + onFileChange, + scanForErrors, + setErrors, + setIsRepairing, +}: RepairHandlersParams) { + const repairSingleError = async (error: CodeError) => { + const file = files.find((entry) => entry.id === error.fileId) + if (!file) return + + setIsRepairing(true) + try { + const result = await ErrorRepairService.repairCode(file, [error]) + + if (result.success && result.fixedCode) { + onFileChange(file.id, result.fixedCode) + + setErrors((prev) => + prev.map((entry) => + entry.id === error.id + ? { ...entry, isFixed: true, fixedCode: result.fixedCode } + : entry + ) + ) + + toast.success( + formatWithValue(errorPanelCopy.toast.fixedSingle, '{message}', error.message), + { + description: result.explanation, + } + ) + + await scanForErrors() + } else { + toast.error(errorPanelCopy.toast.repairErrorFailed) + } + } catch (error) { + toast.error(errorPanelCopy.toast.repairFailed) + console.error(error) + } finally { + setIsRepairing(false) + } + } + + const repairAllErrors = async () => { + setIsRepairing(true) + try { + const results = await ErrorRepairService.repairMultipleFiles(files, errors) + + let fixedCount = 0 + results.forEach((result, fileId) => { + if (result.success && result.fixedCode) { + onFileChange(fileId, result.fixedCode) + fixedCount++ + } + }) + + if (fixedCount > 0) { + toast.success(formatWithCount(errorPanelCopy.toast.repairedFiles, fixedCount)) + await scanForErrors() + } else { + toast.error(errorPanelCopy.toast.noFilesRepaired) + } + } catch (error) { + toast.error(errorPanelCopy.toast.batchRepairFailed) + console.error(error) + } finally { + setIsRepairing(false) + } + } + + const repairFileWithContext = async (fileId: string) => { + const file = files.find((entry) => entry.id === fileId) + if (!file) return + + const fileErrors = errors.filter((entry) => entry.fileId === fileId) + if (fileErrors.length === 0) return + + setIsRepairing(true) + try { + const relatedFiles = files.filter((entry) => entry.id !== fileId).slice(0, 3) + + const result = await ErrorRepairService.repairWithContext( + file, + fileErrors, + relatedFiles + ) + + if (result.success && result.fixedCode) { + onFileChange(file.id, result.fixedCode) + + toast.success( + formatWithValue(errorPanelCopy.toast.repairedFile, '{fileName}', file.name), + { + description: result.explanation, + } + ) + + await scanForErrors() + } else { + toast.error(errorPanelCopy.toast.repairFileFailed) + } + } catch (error) { + toast.error(errorPanelCopy.toast.contextRepairFailed) + console.error(error) + } finally { + setIsRepairing(false) + } + } + + return { + repairSingleError, + repairAllErrors, + repairFileWithContext, + } +} diff --git a/src/components/error-panel/error-panel-scan.ts b/src/components/error-panel/error-panel-scan.ts new file mode 100644 index 0000000..0b25291 --- /dev/null +++ b/src/components/error-panel/error-panel-scan.ts @@ -0,0 +1,48 @@ +import type { Dispatch, SetStateAction } from 'react' +import { toast } from 'sonner' +import { CodeError } from '@/types/errors' +import { ProjectFile } from '@/types/project' +import { ErrorRepairService } from '@/lib/error-repair-service' +import errorPanelCopy from '@/data/error-panel.json' + +const formatWithCount = (template: string, count: number) => + template + .replace('{count}', String(count)) + .replace('{plural}', count === 1 ? '' : 's') + +interface ScanForErrorsParams { + files: ProjectFile[] + setErrors: Dispatch> + setIsScanning: Dispatch> +} + +export function createScanForErrors({ + files, + setErrors, + setIsScanning, +}: ScanForErrorsParams) { + return async () => { + setIsScanning(true) + try { + const allErrors: CodeError[] = [] + + for (const file of files) { + const fileErrors = await ErrorRepairService.detectErrors(file) + allErrors.push(...fileErrors) + } + + setErrors(allErrors) + + if (allErrors.length === 0) { + toast.success(errorPanelCopy.toast.noErrorsFound) + } else { + toast.info(formatWithCount(errorPanelCopy.toast.foundIssues, allErrors.length)) + } + } catch (error) { + toast.error(errorPanelCopy.toast.scanFailed) + console.error(error) + } finally { + setIsScanning(false) + } + } +} diff --git a/src/components/error-panel/useErrorPanelState.ts b/src/components/error-panel/useErrorPanelState.ts new file mode 100644 index 0000000..bfd0850 --- /dev/null +++ b/src/components/error-panel/useErrorPanelState.ts @@ -0,0 +1,64 @@ +import { useEffect, useMemo, useState } from 'react' +import { CodeError } from '@/types/errors' +import { ProjectFile } from '@/types/project' +import { createScanForErrors } from './error-panel-scan' +import { createRepairHandlers } from './error-panel-repair' + +interface UseErrorPanelStateParams { + files: ProjectFile[] + onFileChange: (fileId: string, content: string) => void +} + +export function useErrorPanelState({ files, onFileChange }: UseErrorPanelStateParams) { + const [errors, setErrors] = useState([]) + const [isScanning, setIsScanning] = useState(false) + const [isRepairing, setIsRepairing] = useState(false) + + const scanForErrors = useMemo( + () => createScanForErrors({ files, setErrors, setIsScanning }), + [files] + ) + + const repairHandlers = useMemo( + () => + createRepairHandlers({ + files, + errors, + onFileChange, + scanForErrors, + setErrors, + setIsRepairing, + }), + [errors, files, onFileChange, scanForErrors] + ) + + const errorsByFile = errors.reduce((acc, error) => { + if (!acc[error.fileId]) { + acc[error.fileId] = [] + } + acc[error.fileId].push(error) + return acc + }, {} as Record) + + const errorCount = errors.filter((error) => error.severity === 'error').length + const warningCount = errors.filter((error) => error.severity === 'warning').length + + useEffect(() => { + if (files.length > 0 && errors.length === 0) { + scanForErrors() + } + }, []) + + return { + errors, + errorsByFile, + errorCount, + warningCount, + isScanning, + isRepairing, + scanForErrors, + repairAllErrors: repairHandlers.repairAllErrors, + repairFileWithContext: repairHandlers.repairFileWithContext, + repairSingleError: repairHandlers.repairSingleError, + } +} diff --git a/src/data/error-panel.json b/src/data/error-panel.json new file mode 100644 index 0000000..89b0cfc --- /dev/null +++ b/src/data/error-panel.json @@ -0,0 +1,47 @@ +{ + "header": { + "title": "Error Detection & Repair", + "scan": "Scan", + "scanning": "Scanning...", + "repairAll": "Repair All", + "repairing": "Repairing..." + }, + "counts": { + "errorSingular": "Error", + "errorPlural": "Errors", + "warningSingular": "Warning", + "warningPlural": "Warnings", + "issueSingular": "issue", + "issuePlural": "issues" + }, + "actions": { + "open": "Open", + "repair": "Repair", + "fixed": "Fixed", + "showCode": "Show code", + "hideCode": "Hide code" + }, + "labels": { + "line": "Line" + }, + "emptyStates": { + "noIssuesTitle": "No Issues Found", + "noIssuesDescription": "All files are looking good! Click 'Scan' to check again.", + "scanningTitle": "Scanning Files...", + "scanningDescription": "Analyzing your code for errors and issues" + }, + "toast": { + "noErrorsFound": "No errors found!", + "foundIssues": "Found {count} issue{plural}", + "scanFailed": "Error scanning failed", + "fixedSingle": "Fixed: {message}", + "repairErrorFailed": "Failed to repair error", + "repairFailed": "Repair failed", + "repairedFiles": "Repaired {count} file{plural}", + "noFilesRepaired": "No files could be repaired", + "batchRepairFailed": "Batch repair failed", + "repairedFile": "Repaired {fileName}", + "repairFileFailed": "Failed to repair file", + "contextRepairFailed": "Context-aware repair failed" + } +}