documentation-hub 5.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +43 -0
- package/.github/workflows/build.yml +64 -0
- package/.github/workflows/ci.yml +39 -0
- package/.vscode/extensions.json +3 -0
- package/Current.md +97 -0
- package/DocHub_Image.png +0 -0
- package/README.md +666 -0
- package/USER_GUIDE.md +1173 -0
- package/Updater.md +311 -0
- package/build/256x256.png +0 -0
- package/build/512x512.png +0 -0
- package/build/app-update.yml +4 -0
- package/build/create-icon.js +208 -0
- package/build/icon.ico +0 -0
- package/build/icon.png +0 -0
- package/build/icon_1024x1024.png +0 -0
- package/dist/assets/Analytics-BpsG9895.js +1 -0
- package/dist/assets/Card-IAZin8kp.js +1 -0
- package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
- package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
- package/dist/assets/Documents-CqZ25axS.js +1 -0
- package/dist/assets/Input-l89xwXBi.js +1 -0
- package/dist/assets/Reporting-DqdHJY_a.js +1 -0
- package/dist/assets/Search-XNbu5z_3.js +1 -0
- package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
- package/dist/assets/Sessions-ClZOPYNc.js +1 -0
- package/dist/assets/Settings-DUEHGURa.js +11 -0
- package/dist/assets/index-8xUe8ptc.js +24 -0
- package/dist/assets/index-RYyJqF7O.css +1 -0
- package/dist/assets/path-BkOl0AGO.js +1 -0
- package/dist/assets/promises-ID_B9S-h.js +1 -0
- package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
- package/dist/assets/useToast-yRSO1dkm.js +1 -0
- package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
- package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
- package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
- package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
- package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
- package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
- package/dist/electron/main-CXkNtyv-.js +19789 -0
- package/dist/electron/main.js +5 -0
- package/dist/electron/preload.js +1 -0
- package/dist/icon.png +0 -0
- package/dist/index.html +27 -0
- package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
- package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
- package/docs/README.md +115 -0
- package/docs/TOC_WIRING_GUIDE.md +344 -0
- package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
- package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
- package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
- package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
- package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
- package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
- package/docs/analysis/List_Implementation.md +206 -0
- package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
- package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
- package/docs/analysis/RefactorStyles.md +852 -0
- package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
- package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
- package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
- package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
- package/docs/analysis/github-issues-to-create.md +237 -0
- package/docs/api/API_README.md +538 -0
- package/docs/api/API_REFERENCE.md +751 -0
- package/docs/api/TYPE_DEFINITIONS.md +869 -0
- package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
- package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
- package/docs/docxmlater-readme.md +1341 -0
- package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
- package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
- package/docs/fixes/README.md +37 -0
- package/docs/github-issues/issue-1-body.md +125 -0
- package/docs/github-issues/issue-10-body.md +850 -0
- package/docs/github-issues/issue-2-body.md +200 -0
- package/docs/github-issues/issue-3-body.md +270 -0
- package/docs/github-issues/issue-4-body.md +169 -0
- package/docs/github-issues/issue-5-body.md +173 -0
- package/docs/github-issues/issue-6-body.md +158 -0
- package/docs/github-issues/issue-7-body.md +171 -0
- package/docs/github-issues/issue-8-body.md +407 -0
- package/docs/github-issues/issue-9-body.md +515 -0
- package/docs/github-issues/issue-tracker.md +274 -0
- package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
- package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
- package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
- package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
- package/docs/implementation/RefactorStyles.md +588 -0
- package/docs/implementation/implement-plan.md +489 -0
- package/docs/implementation/missing-helpers-implementation.md +391 -0
- package/docs/implementation/refactor-plan.md +520 -0
- package/docs/implementation/session-implementation-complete.md +233 -0
- package/docs/implementation/session-management-plan.md +250 -0
- package/docs/setup-checklist.md +77 -0
- package/docs/versions/changelog.md +345 -0
- package/electron/customUpdater.ts +656 -0
- package/electron/main.ts +2441 -0
- package/electron/memoryConfig.ts +187 -0
- package/electron/preload.ts +394 -0
- package/electron/proxyConfig.ts +340 -0
- package/electron/services/BackupService.ts +452 -0
- package/electron/services/DictionaryService.ts +402 -0
- package/electron/services/LocalDictionaryLookupService.ts +147 -0
- package/electron/services/PowerAutomateApiService.ts +231 -0
- package/electron/services/SharePointSyncService.ts +474 -0
- package/electron/windowsCertStore.ts +427 -0
- package/electron/zscalerConfig.ts +381 -0
- package/eslint.config.js +92 -0
- package/jest.config.js +52 -0
- package/package.json +214 -0
- package/postcss.config.mjs +6 -0
- package/public/icon.png +0 -0
- package/publish-release.ps1 +5 -0
- package/renovate.json +30 -0
- package/src/App.tsx +216 -0
- package/src/__mocks__/p-limit.js +12 -0
- package/src/__mocks__/styleMock.js +1 -0
- package/src/components/common/BugReportButton.tsx +44 -0
- package/src/components/common/BugReportDialog.tsx +193 -0
- package/src/components/common/Button.tsx +153 -0
- package/src/components/common/Card.tsx +86 -0
- package/src/components/common/ColorPickerDialog.tsx +177 -0
- package/src/components/common/ConfirmDialog.tsx +96 -0
- package/src/components/common/DebugConsole.tsx +275 -0
- package/src/components/common/EmptyState.tsx +183 -0
- package/src/components/common/ErrorBoundary.tsx +98 -0
- package/src/components/common/ErrorDetailsDialog.tsx +153 -0
- package/src/components/common/ErrorFallback.tsx +218 -0
- package/src/components/common/Input.tsx +109 -0
- package/src/components/common/Skeleton.tsx +184 -0
- package/src/components/common/SplashScreen.tsx +81 -0
- package/src/components/common/Toast.tsx +155 -0
- package/src/components/common/Tooltip.tsx +79 -0
- package/src/components/common/UpdateNotification.tsx +320 -0
- package/src/components/comparison/ComparisonWindow.tsx +374 -0
- package/src/components/comparison/SideBySideDiff.tsx +486 -0
- package/src/components/comparison/index.ts +8 -0
- package/src/components/document/DocumentUploader.tsx +288 -0
- package/src/components/document/HyperlinkPreview.tsx +430 -0
- package/src/components/document/HyperlinkService.md +1484 -0
- package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
- package/src/components/document/InlineChangesView.tsx +707 -0
- package/src/components/document/ProcessingProgress.tsx +303 -0
- package/src/components/document/ProcessingResults.tsx +256 -0
- package/src/components/document/TrackedChangesDetail.tsx +530 -0
- package/src/components/document/TrackedChangesPanel.tsx +546 -0
- package/src/components/document/VirtualDocumentList.tsx +240 -0
- package/src/components/editor/DocumentEditor.tsx +723 -0
- package/src/components/editor/DocumentEditorModal.tsx +640 -0
- package/src/components/editor/EditorQuickActions.tsx +502 -0
- package/src/components/editor/EditorToolbar.tsx +312 -0
- package/src/components/editor/TableEditor.tsx +926 -0
- package/src/components/editor/index.ts +18 -0
- package/src/components/layout/Header.tsx +190 -0
- package/src/components/layout/Sidebar.tsx +313 -0
- package/src/components/layout/TitleBar.tsx +190 -0
- package/src/components/navigation/CommandPalette.tsx +233 -0
- package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
- package/src/components/sessions/ChangeItem.tsx +408 -0
- package/src/components/sessions/ChangeViewer.tsx +1155 -0
- package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
- package/src/components/sessions/ProcessingOptions.tsx +297 -0
- package/src/components/sessions/ReplacementsTab.tsx +438 -0
- package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
- package/src/components/sessions/SessionManager.tsx +188 -0
- package/src/components/sessions/StylesEditor.tsx +1335 -0
- package/src/components/sessions/TabContainer.tsx +151 -0
- package/src/components/sessions/VirtualSessionList.tsx +157 -0
- package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
- package/src/components/settings/CertificateManager.tsx +410 -0
- package/src/components/settings/SegmentedControl.tsx +88 -0
- package/src/components/settings/SettingRow.tsx +52 -0
- package/src/contexts/GlobalStatsContext.tsx +396 -0
- package/src/contexts/SessionContext.tsx +2129 -0
- package/src/contexts/ThemeContext.tsx +428 -0
- package/src/contexts/UserSettingsContext.tsx +290 -0
- package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
- package/src/global.d.ts +273 -0
- package/src/hooks/useDocumentQueue.tsx +210 -0
- package/src/hooks/useToast.tsx +55 -0
- package/src/main.tsx +10 -0
- package/src/pages/Analytics.tsx +386 -0
- package/src/pages/CurrentSession.tsx +1174 -0
- package/src/pages/Dashboard.tsx +319 -0
- package/src/pages/Documents.tsx +317 -0
- package/src/pages/Projects.tsx +250 -0
- package/src/pages/Reporting.tsx +386 -0
- package/src/pages/Search.tsx +349 -0
- package/src/pages/Sessions.tsx +285 -0
- package/src/pages/Settings.tsx +2662 -0
- package/src/services/HyperlinkService.ts +1085 -0
- package/src/services/document/DocXMLaterProcessor.ts +617 -0
- package/src/services/document/DocumentProcessingComparison.ts +856 -0
- package/src/services/document/DocumentSnapshotService.ts +575 -0
- package/src/services/document/WordDocumentProcessor.ts +10509 -0
- package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
- package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
- package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
- package/src/services/document/blanklines/BlankLineManager.ts +658 -0
- package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
- package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
- package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
- package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
- package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
- package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
- package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
- package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
- package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
- package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
- package/src/services/document/blanklines/index.ts +67 -0
- package/src/services/document/blanklines/rules/additionRules.ts +337 -0
- package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
- package/src/services/document/blanklines/rules/removalRules.ts +362 -0
- package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
- package/src/services/document/blanklines/types.ts +29 -0
- package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
- package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
- package/src/services/document/helpers/whitespace.ts +117 -0
- package/src/services/document/list/ListNormalizer.ts +947 -0
- package/src/services/document/list/index.ts +45 -0
- package/src/services/document/list/list-detection.ts +275 -0
- package/src/services/document/list/list-types.ts +162 -0
- package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
- package/src/services/document/processors/ListProcessor.ts +257 -0
- package/src/services/document/processors/StructureProcessor.ts +176 -0
- package/src/services/document/processors/StyleProcessor.ts +389 -0
- package/src/services/document/processors/TableProcessor.ts +2238 -0
- package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
- package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
- package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
- package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
- package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
- package/src/services/document/processors/index.ts +28 -0
- package/src/services/document/types/docx-processing.ts +310 -0
- package/src/services/editor/EditorActionHandlers.ts +901 -0
- package/src/services/editor/index.ts +13 -0
- package/src/setupTests.ts +47 -0
- package/src/styles/global.css +782 -0
- package/src/types/backup.ts +132 -0
- package/src/types/dictionary.ts +125 -0
- package/src/types/document-processing.ts +331 -0
- package/src/types/docxmlater-augments.d.ts +142 -0
- package/src/types/editor.ts +280 -0
- package/src/types/electron.ts +340 -0
- package/src/types/globalStats.ts +155 -0
- package/src/types/hyperlink.ts +471 -0
- package/src/types/operations.ts +354 -0
- package/src/types/session.ts +427 -0
- package/src/types/settings.ts +112 -0
- package/src/utils/MemoryMonitor.ts +248 -0
- package/src/utils/cn.ts +6 -0
- package/src/utils/colorConvert.ts +306 -0
- package/src/utils/diffUtils.ts +347 -0
- package/src/utils/documentUtils.ts +202 -0
- package/src/utils/electronGuard.ts +62 -0
- package/src/utils/indexedDB.ts +915 -0
- package/src/utils/logger.ts +717 -0
- package/src/utils/pathSecurity.ts +232 -0
- package/src/utils/pathValidator.ts +236 -0
- package/src/utils/processingTimeEstimator.ts +153 -0
- package/src/utils/safeJsonParse.ts +62 -0
- package/src/utils/textSanitizer.ts +162 -0
- package/src/utils/urlHelpers.ts +304 -0
- package/src/utils/urlPatterns.ts +198 -0
- package/src/utils/urlSanitizer.ts +152 -0
- package/src/vite-env.d.ts +11 -0
- package/tsconfig.electron.json +19 -0
- package/tsconfig.json +36 -0
- package/tsconfig.node.json +12 -0
- package/typedoc.json +45 -0
- package/vite.config.ts +152 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComparisonWindow - Displays before/after document processing changes
|
|
3
|
+
*
|
|
4
|
+
* This component shows a detailed comparison of what changed during
|
|
5
|
+
* document processing in a separate Electron window.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useState } from 'react';
|
|
9
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
10
|
+
import {
|
|
11
|
+
FileText,
|
|
12
|
+
Link,
|
|
13
|
+
Type,
|
|
14
|
+
Palette,
|
|
15
|
+
Activity,
|
|
16
|
+
ChevronDown,
|
|
17
|
+
ChevronUp,
|
|
18
|
+
Clock,
|
|
19
|
+
CheckCircle,
|
|
20
|
+
AlertCircle,
|
|
21
|
+
X,
|
|
22
|
+
} from 'lucide-react';
|
|
23
|
+
import {
|
|
24
|
+
ProcessingComparison,
|
|
25
|
+
HyperlinkChange,
|
|
26
|
+
StyleChange,
|
|
27
|
+
} from '@/services/document/DocumentProcessingComparison';
|
|
28
|
+
import { cn } from '@/utils/cn';
|
|
29
|
+
|
|
30
|
+
interface ComparisonWindowProps {
|
|
31
|
+
comparison: ProcessingComparison;
|
|
32
|
+
onClose?: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const ComparisonWindow: React.FC<ComparisonWindowProps> = ({ comparison, onClose }) => {
|
|
36
|
+
const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set(['hyperlinks']));
|
|
37
|
+
const [filter, setFilter] = useState<'all' | 'urls' | 'texts' | 'styles'>('all');
|
|
38
|
+
|
|
39
|
+
// Toggle section expansion
|
|
40
|
+
const toggleSection = (section: string) => {
|
|
41
|
+
setExpandedSections((prev) => {
|
|
42
|
+
const next = new Set(prev);
|
|
43
|
+
if (next.has(section)) {
|
|
44
|
+
next.delete(section);
|
|
45
|
+
} else {
|
|
46
|
+
next.add(section);
|
|
47
|
+
}
|
|
48
|
+
return next;
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Calculate processing time
|
|
53
|
+
const processingTime = comparison.statistics.processingDurationMs;
|
|
54
|
+
const formattedTime =
|
|
55
|
+
processingTime < 1000
|
|
56
|
+
? `${processingTime.toFixed(0)}ms`
|
|
57
|
+
: `${(processingTime / 1000).toFixed(2)}s`;
|
|
58
|
+
|
|
59
|
+
// Filter changes based on selected filter
|
|
60
|
+
const filteredHyperlinkChanges = comparison.hyperlinkChanges.filter((change) => {
|
|
61
|
+
if (filter === 'all') return true;
|
|
62
|
+
if (filter === 'urls') return change.originalUrl !== change.modifiedUrl;
|
|
63
|
+
if (filter === 'texts') return change.originalText !== change.modifiedText;
|
|
64
|
+
return false;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
|
|
69
|
+
{/* Header */}
|
|
70
|
+
<div className="sticky top-0 z-50 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
|
|
71
|
+
<div className="px-6 py-4">
|
|
72
|
+
<div className="flex items-center justify-between">
|
|
73
|
+
<div className="flex items-center gap-3">
|
|
74
|
+
<FileText className="w-6 h-6 text-blue-500" />
|
|
75
|
+
<div>
|
|
76
|
+
<h1 className="text-xl font-semibold text-gray-900 dark:text-white">
|
|
77
|
+
Document Processing Comparison
|
|
78
|
+
</h1>
|
|
79
|
+
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
80
|
+
{comparison.documentPath.split('/').pop()}
|
|
81
|
+
</p>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
{onClose && (
|
|
85
|
+
<button
|
|
86
|
+
onClick={onClose}
|
|
87
|
+
className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
|
|
88
|
+
aria-label="Close comparison window"
|
|
89
|
+
>
|
|
90
|
+
<X className="w-5 h-5 text-gray-500 dark:text-gray-400" />
|
|
91
|
+
</button>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
{/* Statistics Bar */}
|
|
96
|
+
<div className="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-6 gap-3 mt-4">
|
|
97
|
+
<StatCard
|
|
98
|
+
icon={<Activity className="w-4 h-4" />}
|
|
99
|
+
label="Total Changes"
|
|
100
|
+
value={comparison.statistics.totalChanges}
|
|
101
|
+
color="blue"
|
|
102
|
+
/>
|
|
103
|
+
<StatCard
|
|
104
|
+
icon={<Link className="w-4 h-4" />}
|
|
105
|
+
label="URLs Modified"
|
|
106
|
+
value={comparison.statistics.urlsChanged}
|
|
107
|
+
color="purple"
|
|
108
|
+
/>
|
|
109
|
+
<StatCard
|
|
110
|
+
icon={<Type className="w-4 h-4" />}
|
|
111
|
+
label="Texts Updated"
|
|
112
|
+
value={comparison.statistics.displayTextsChanged}
|
|
113
|
+
color="green"
|
|
114
|
+
/>
|
|
115
|
+
<StatCard
|
|
116
|
+
icon={<Palette className="w-4 h-4" />}
|
|
117
|
+
label="Styles Applied"
|
|
118
|
+
value={comparison.statistics.stylesApplied}
|
|
119
|
+
color="orange"
|
|
120
|
+
/>
|
|
121
|
+
<StatCard
|
|
122
|
+
icon={<CheckCircle className="w-4 h-4" />}
|
|
123
|
+
label="Content IDs"
|
|
124
|
+
value={comparison.statistics.contentIdsAppended}
|
|
125
|
+
color="teal"
|
|
126
|
+
/>
|
|
127
|
+
<StatCard
|
|
128
|
+
icon={<Clock className="w-4 h-4" />}
|
|
129
|
+
label="Processing Time"
|
|
130
|
+
value={formattedTime}
|
|
131
|
+
color="gray"
|
|
132
|
+
/>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
{/* Filter Tabs */}
|
|
136
|
+
<div className="flex gap-2 mt-4">
|
|
137
|
+
{(['all', 'urls', 'texts', 'styles'] as const).map((tab) => (
|
|
138
|
+
<button
|
|
139
|
+
key={tab}
|
|
140
|
+
onClick={() => setFilter(tab)}
|
|
141
|
+
className={cn(
|
|
142
|
+
'px-4 py-2 rounded-lg text-sm font-medium transition-colors',
|
|
143
|
+
filter === tab
|
|
144
|
+
? 'bg-blue-500 text-white'
|
|
145
|
+
: 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
|
|
146
|
+
)}
|
|
147
|
+
>
|
|
148
|
+
{tab.charAt(0).toUpperCase() + tab.slice(1)}
|
|
149
|
+
{tab === 'all' && ` (${comparison.statistics.totalChanges})`}
|
|
150
|
+
{tab === 'urls' && ` (${comparison.statistics.urlsChanged})`}
|
|
151
|
+
{tab === 'texts' && ` (${comparison.statistics.displayTextsChanged})`}
|
|
152
|
+
{tab === 'styles' && ` (${comparison.statistics.stylesApplied})`}
|
|
153
|
+
</button>
|
|
154
|
+
))}
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
{/* Main Content */}
|
|
160
|
+
<div className="max-w-7xl mx-auto px-6 py-6">
|
|
161
|
+
{/* Hyperlink Changes Section */}
|
|
162
|
+
{(filter === 'all' || filter === 'urls' || filter === 'texts') &&
|
|
163
|
+
filteredHyperlinkChanges.length > 0 && (
|
|
164
|
+
<Section
|
|
165
|
+
title="Hyperlink Changes"
|
|
166
|
+
icon={<Link className="w-5 h-5" />}
|
|
167
|
+
count={filteredHyperlinkChanges.length}
|
|
168
|
+
expanded={expandedSections.has('hyperlinks')}
|
|
169
|
+
onToggle={() => toggleSection('hyperlinks')}
|
|
170
|
+
>
|
|
171
|
+
<div className="space-y-3">
|
|
172
|
+
{filteredHyperlinkChanges.map((change, index) => (
|
|
173
|
+
<HyperlinkChangeCard key={index} change={change} />
|
|
174
|
+
))}
|
|
175
|
+
</div>
|
|
176
|
+
</Section>
|
|
177
|
+
)}
|
|
178
|
+
|
|
179
|
+
{/* Style Changes Section */}
|
|
180
|
+
{(filter === 'all' || filter === 'styles') && comparison.styleChanges.length > 0 && (
|
|
181
|
+
<Section
|
|
182
|
+
title="Style Changes"
|
|
183
|
+
icon={<Palette className="w-5 h-5" />}
|
|
184
|
+
count={comparison.styleChanges.length}
|
|
185
|
+
expanded={expandedSections.has('styles')}
|
|
186
|
+
onToggle={() => toggleSection('styles')}
|
|
187
|
+
>
|
|
188
|
+
<div className="space-y-3">
|
|
189
|
+
{comparison.styleChanges.map((change, index) => (
|
|
190
|
+
<StyleChangeCard key={index} change={change} />
|
|
191
|
+
))}
|
|
192
|
+
</div>
|
|
193
|
+
</Section>
|
|
194
|
+
)}
|
|
195
|
+
|
|
196
|
+
{/* Empty State */}
|
|
197
|
+
{filteredHyperlinkChanges.length === 0 &&
|
|
198
|
+
(filter === 'styles' ? comparison.styleChanges.length === 0 : true) && (
|
|
199
|
+
<div className="text-center py-12">
|
|
200
|
+
<AlertCircle className="w-12 h-12 text-gray-400 mx-auto mb-4" />
|
|
201
|
+
<p className="text-gray-500 dark:text-gray-400">
|
|
202
|
+
No changes found for the selected filter
|
|
203
|
+
</p>
|
|
204
|
+
</div>
|
|
205
|
+
)}
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Stat Card Component
|
|
212
|
+
const StatCard: React.FC<{
|
|
213
|
+
icon: React.ReactNode;
|
|
214
|
+
label: string;
|
|
215
|
+
value: string | number;
|
|
216
|
+
color: 'blue' | 'purple' | 'green' | 'orange' | 'teal' | 'gray';
|
|
217
|
+
}> = ({ icon, label, value, color }) => {
|
|
218
|
+
const colorClasses = {
|
|
219
|
+
blue: 'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400',
|
|
220
|
+
purple: 'bg-purple-50 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400',
|
|
221
|
+
green: 'bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400',
|
|
222
|
+
orange: 'bg-orange-50 dark:bg-orange-900/20 text-orange-600 dark:text-orange-400',
|
|
223
|
+
teal: 'bg-teal-50 dark:bg-teal-900/20 text-teal-600 dark:text-teal-400',
|
|
224
|
+
gray: 'bg-gray-50 dark:bg-gray-900/20 text-gray-600 dark:text-gray-400',
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
return (
|
|
228
|
+
<div className={cn('p-3 rounded-lg', colorClasses[color])}>
|
|
229
|
+
<div className="flex items-center gap-2 mb-1">
|
|
230
|
+
{icon}
|
|
231
|
+
<span className="text-xs font-medium opacity-80">{label}</span>
|
|
232
|
+
</div>
|
|
233
|
+
<div className="text-xl font-bold">{value}</div>
|
|
234
|
+
</div>
|
|
235
|
+
);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// Section Component
|
|
239
|
+
const Section: React.FC<{
|
|
240
|
+
title: string;
|
|
241
|
+
icon: React.ReactNode;
|
|
242
|
+
count: number;
|
|
243
|
+
expanded: boolean;
|
|
244
|
+
onToggle: () => void;
|
|
245
|
+
children: React.ReactNode;
|
|
246
|
+
}> = ({ title, icon, count, expanded, onToggle, children }) => {
|
|
247
|
+
return (
|
|
248
|
+
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="mb-6">
|
|
249
|
+
<button
|
|
250
|
+
onClick={onToggle}
|
|
251
|
+
className="w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm hover:shadow-md transition-shadow"
|
|
252
|
+
>
|
|
253
|
+
<div className="px-6 py-4 flex items-center justify-between">
|
|
254
|
+
<div className="flex items-center gap-3">
|
|
255
|
+
{icon}
|
|
256
|
+
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">{title}</h2>
|
|
257
|
+
<span className="px-2.5 py-1 bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 text-sm rounded-full">
|
|
258
|
+
{count}
|
|
259
|
+
</span>
|
|
260
|
+
</div>
|
|
261
|
+
{expanded ? (
|
|
262
|
+
<ChevronUp className="w-5 h-5 text-gray-400" />
|
|
263
|
+
) : (
|
|
264
|
+
<ChevronDown className="w-5 h-5 text-gray-400" />
|
|
265
|
+
)}
|
|
266
|
+
</div>
|
|
267
|
+
</button>
|
|
268
|
+
|
|
269
|
+
<AnimatePresence>
|
|
270
|
+
{expanded && (
|
|
271
|
+
<motion.div
|
|
272
|
+
initial={{ height: 0, opacity: 0 }}
|
|
273
|
+
animate={{ height: 'auto', opacity: 1 }}
|
|
274
|
+
exit={{ height: 0, opacity: 0 }}
|
|
275
|
+
transition={{ duration: 0.2 }}
|
|
276
|
+
className="overflow-hidden"
|
|
277
|
+
>
|
|
278
|
+
<div className="pt-4">{children}</div>
|
|
279
|
+
</motion.div>
|
|
280
|
+
)}
|
|
281
|
+
</AnimatePresence>
|
|
282
|
+
</motion.div>
|
|
283
|
+
);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// Hyperlink Change Card
|
|
287
|
+
const HyperlinkChangeCard: React.FC<{ change: HyperlinkChange }> = ({ change }) => {
|
|
288
|
+
const urlChanged = change.originalUrl !== change.modifiedUrl;
|
|
289
|
+
const textChanged = change.originalText !== change.modifiedText;
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
|
|
293
|
+
<div className="flex items-start justify-between mb-3">
|
|
294
|
+
<div className="text-sm text-gray-500 dark:text-gray-400">
|
|
295
|
+
Paragraph {change.paragraphIndex + 1}, Hyperlink {change.hyperlinkIndex + 1}
|
|
296
|
+
</div>
|
|
297
|
+
<div className="text-xs text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 px-2 py-1 rounded">
|
|
298
|
+
{change.changeReason}
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
{urlChanged && (
|
|
303
|
+
<div className="mb-3">
|
|
304
|
+
<div className="text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
|
|
305
|
+
URL Changed:
|
|
306
|
+
</div>
|
|
307
|
+
<div className="space-y-1">
|
|
308
|
+
<div className="flex items-start gap-2">
|
|
309
|
+
<span className="text-red-500">−</span>
|
|
310
|
+
<code className="text-xs bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 p-1.5 rounded flex-1 break-all">
|
|
311
|
+
{change.originalUrl}
|
|
312
|
+
</code>
|
|
313
|
+
</div>
|
|
314
|
+
<div className="flex items-start gap-2">
|
|
315
|
+
<span className="text-green-500">+</span>
|
|
316
|
+
<code className="text-xs bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400 p-1.5 rounded flex-1 break-all">
|
|
317
|
+
{change.modifiedUrl}
|
|
318
|
+
</code>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
)}
|
|
323
|
+
|
|
324
|
+
{textChanged && (
|
|
325
|
+
<div>
|
|
326
|
+
<div className="text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
|
|
327
|
+
Display Text Changed:
|
|
328
|
+
</div>
|
|
329
|
+
<div className="space-y-1">
|
|
330
|
+
<div className="flex items-start gap-2">
|
|
331
|
+
<span className="text-red-500">−</span>
|
|
332
|
+
<div className="text-sm bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 p-1.5 rounded flex-1">
|
|
333
|
+
{change.originalText}
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
<div className="flex items-start gap-2">
|
|
337
|
+
<span className="text-green-500">+</span>
|
|
338
|
+
<div className="text-sm bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400 p-1.5 rounded flex-1">
|
|
339
|
+
{change.modifiedText}
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
)}
|
|
345
|
+
</div>
|
|
346
|
+
);
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
// Style Change Card
|
|
350
|
+
const StyleChangeCard: React.FC<{ change: StyleChange }> = ({ change }) => {
|
|
351
|
+
return (
|
|
352
|
+
<div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
|
|
353
|
+
<div className="flex items-start justify-between mb-3">
|
|
354
|
+
<div className="text-sm text-gray-500 dark:text-gray-400">
|
|
355
|
+
Paragraph {change.paragraphIndex + 1}
|
|
356
|
+
</div>
|
|
357
|
+
<div className="text-xs text-purple-600 dark:text-purple-400 bg-purple-50 dark:bg-purple-900/20 px-2 py-1 rounded">
|
|
358
|
+
{change.styleName}
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
|
|
362
|
+
<div className="space-y-1">
|
|
363
|
+
{Object.entries(change.properties).map(([key, value]) => (
|
|
364
|
+
<div key={key} className="flex items-center gap-2 text-sm">
|
|
365
|
+
<span className="text-gray-500 dark:text-gray-400">{key}:</span>
|
|
366
|
+
<span className="text-gray-900 dark:text-white font-medium">{String(value)}</span>
|
|
367
|
+
</div>
|
|
368
|
+
))}
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
);
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
export default ComparisonWindow;
|