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.
Files changed (271) hide show
  1. package/.eslintrc.json +43 -0
  2. package/.github/workflows/build.yml +64 -0
  3. package/.github/workflows/ci.yml +39 -0
  4. package/.vscode/extensions.json +3 -0
  5. package/Current.md +97 -0
  6. package/DocHub_Image.png +0 -0
  7. package/README.md +666 -0
  8. package/USER_GUIDE.md +1173 -0
  9. package/Updater.md +311 -0
  10. package/build/256x256.png +0 -0
  11. package/build/512x512.png +0 -0
  12. package/build/app-update.yml +4 -0
  13. package/build/create-icon.js +208 -0
  14. package/build/icon.ico +0 -0
  15. package/build/icon.png +0 -0
  16. package/build/icon_1024x1024.png +0 -0
  17. package/dist/assets/Analytics-BpsG9895.js +1 -0
  18. package/dist/assets/Card-IAZin8kp.js +1 -0
  19. package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
  20. package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
  21. package/dist/assets/Documents-CqZ25axS.js +1 -0
  22. package/dist/assets/Input-l89xwXBi.js +1 -0
  23. package/dist/assets/Reporting-DqdHJY_a.js +1 -0
  24. package/dist/assets/Search-XNbu5z_3.js +1 -0
  25. package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
  26. package/dist/assets/Sessions-ClZOPYNc.js +1 -0
  27. package/dist/assets/Settings-DUEHGURa.js +11 -0
  28. package/dist/assets/index-8xUe8ptc.js +24 -0
  29. package/dist/assets/index-RYyJqF7O.css +1 -0
  30. package/dist/assets/path-BkOl0AGO.js +1 -0
  31. package/dist/assets/promises-ID_B9S-h.js +1 -0
  32. package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
  33. package/dist/assets/useToast-yRSO1dkm.js +1 -0
  34. package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
  35. package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
  36. package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
  37. package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
  38. package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
  39. package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
  40. package/dist/electron/main-CXkNtyv-.js +19789 -0
  41. package/dist/electron/main.js +5 -0
  42. package/dist/electron/preload.js +1 -0
  43. package/dist/icon.png +0 -0
  44. package/dist/index.html +27 -0
  45. package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
  46. package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
  47. package/docs/README.md +115 -0
  48. package/docs/TOC_WIRING_GUIDE.md +344 -0
  49. package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
  50. package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
  51. package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
  52. package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
  53. package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
  54. package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
  55. package/docs/analysis/List_Implementation.md +206 -0
  56. package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
  57. package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
  58. package/docs/analysis/RefactorStyles.md +852 -0
  59. package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
  60. package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
  61. package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
  62. package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
  63. package/docs/analysis/github-issues-to-create.md +237 -0
  64. package/docs/api/API_README.md +538 -0
  65. package/docs/api/API_REFERENCE.md +751 -0
  66. package/docs/api/TYPE_DEFINITIONS.md +869 -0
  67. package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
  68. package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
  69. package/docs/docxmlater-readme.md +1341 -0
  70. package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
  71. package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
  72. package/docs/fixes/README.md +37 -0
  73. package/docs/github-issues/issue-1-body.md +125 -0
  74. package/docs/github-issues/issue-10-body.md +850 -0
  75. package/docs/github-issues/issue-2-body.md +200 -0
  76. package/docs/github-issues/issue-3-body.md +270 -0
  77. package/docs/github-issues/issue-4-body.md +169 -0
  78. package/docs/github-issues/issue-5-body.md +173 -0
  79. package/docs/github-issues/issue-6-body.md +158 -0
  80. package/docs/github-issues/issue-7-body.md +171 -0
  81. package/docs/github-issues/issue-8-body.md +407 -0
  82. package/docs/github-issues/issue-9-body.md +515 -0
  83. package/docs/github-issues/issue-tracker.md +274 -0
  84. package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
  85. package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
  86. package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
  87. package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
  88. package/docs/implementation/RefactorStyles.md +588 -0
  89. package/docs/implementation/implement-plan.md +489 -0
  90. package/docs/implementation/missing-helpers-implementation.md +391 -0
  91. package/docs/implementation/refactor-plan.md +520 -0
  92. package/docs/implementation/session-implementation-complete.md +233 -0
  93. package/docs/implementation/session-management-plan.md +250 -0
  94. package/docs/setup-checklist.md +77 -0
  95. package/docs/versions/changelog.md +345 -0
  96. package/electron/customUpdater.ts +656 -0
  97. package/electron/main.ts +2441 -0
  98. package/electron/memoryConfig.ts +187 -0
  99. package/electron/preload.ts +394 -0
  100. package/electron/proxyConfig.ts +340 -0
  101. package/electron/services/BackupService.ts +452 -0
  102. package/electron/services/DictionaryService.ts +402 -0
  103. package/electron/services/LocalDictionaryLookupService.ts +147 -0
  104. package/electron/services/PowerAutomateApiService.ts +231 -0
  105. package/electron/services/SharePointSyncService.ts +474 -0
  106. package/electron/windowsCertStore.ts +427 -0
  107. package/electron/zscalerConfig.ts +381 -0
  108. package/eslint.config.js +92 -0
  109. package/jest.config.js +52 -0
  110. package/package.json +214 -0
  111. package/postcss.config.mjs +6 -0
  112. package/public/icon.png +0 -0
  113. package/publish-release.ps1 +5 -0
  114. package/renovate.json +30 -0
  115. package/src/App.tsx +216 -0
  116. package/src/__mocks__/p-limit.js +12 -0
  117. package/src/__mocks__/styleMock.js +1 -0
  118. package/src/components/common/BugReportButton.tsx +44 -0
  119. package/src/components/common/BugReportDialog.tsx +193 -0
  120. package/src/components/common/Button.tsx +153 -0
  121. package/src/components/common/Card.tsx +86 -0
  122. package/src/components/common/ColorPickerDialog.tsx +177 -0
  123. package/src/components/common/ConfirmDialog.tsx +96 -0
  124. package/src/components/common/DebugConsole.tsx +275 -0
  125. package/src/components/common/EmptyState.tsx +183 -0
  126. package/src/components/common/ErrorBoundary.tsx +98 -0
  127. package/src/components/common/ErrorDetailsDialog.tsx +153 -0
  128. package/src/components/common/ErrorFallback.tsx +218 -0
  129. package/src/components/common/Input.tsx +109 -0
  130. package/src/components/common/Skeleton.tsx +184 -0
  131. package/src/components/common/SplashScreen.tsx +81 -0
  132. package/src/components/common/Toast.tsx +155 -0
  133. package/src/components/common/Tooltip.tsx +79 -0
  134. package/src/components/common/UpdateNotification.tsx +320 -0
  135. package/src/components/comparison/ComparisonWindow.tsx +374 -0
  136. package/src/components/comparison/SideBySideDiff.tsx +486 -0
  137. package/src/components/comparison/index.ts +8 -0
  138. package/src/components/document/DocumentUploader.tsx +288 -0
  139. package/src/components/document/HyperlinkPreview.tsx +430 -0
  140. package/src/components/document/HyperlinkService.md +1484 -0
  141. package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
  142. package/src/components/document/InlineChangesView.tsx +707 -0
  143. package/src/components/document/ProcessingProgress.tsx +303 -0
  144. package/src/components/document/ProcessingResults.tsx +256 -0
  145. package/src/components/document/TrackedChangesDetail.tsx +530 -0
  146. package/src/components/document/TrackedChangesPanel.tsx +546 -0
  147. package/src/components/document/VirtualDocumentList.tsx +240 -0
  148. package/src/components/editor/DocumentEditor.tsx +723 -0
  149. package/src/components/editor/DocumentEditorModal.tsx +640 -0
  150. package/src/components/editor/EditorQuickActions.tsx +502 -0
  151. package/src/components/editor/EditorToolbar.tsx +312 -0
  152. package/src/components/editor/TableEditor.tsx +926 -0
  153. package/src/components/editor/index.ts +18 -0
  154. package/src/components/layout/Header.tsx +190 -0
  155. package/src/components/layout/Sidebar.tsx +313 -0
  156. package/src/components/layout/TitleBar.tsx +190 -0
  157. package/src/components/navigation/CommandPalette.tsx +233 -0
  158. package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
  159. package/src/components/sessions/ChangeItem.tsx +408 -0
  160. package/src/components/sessions/ChangeViewer.tsx +1155 -0
  161. package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
  162. package/src/components/sessions/ProcessingOptions.tsx +297 -0
  163. package/src/components/sessions/ReplacementsTab.tsx +438 -0
  164. package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
  165. package/src/components/sessions/SessionManager.tsx +188 -0
  166. package/src/components/sessions/StylesEditor.tsx +1335 -0
  167. package/src/components/sessions/TabContainer.tsx +151 -0
  168. package/src/components/sessions/VirtualSessionList.tsx +157 -0
  169. package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
  170. package/src/components/settings/CertificateManager.tsx +410 -0
  171. package/src/components/settings/SegmentedControl.tsx +88 -0
  172. package/src/components/settings/SettingRow.tsx +52 -0
  173. package/src/contexts/GlobalStatsContext.tsx +396 -0
  174. package/src/contexts/SessionContext.tsx +2129 -0
  175. package/src/contexts/ThemeContext.tsx +428 -0
  176. package/src/contexts/UserSettingsContext.tsx +290 -0
  177. package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
  178. package/src/global.d.ts +273 -0
  179. package/src/hooks/useDocumentQueue.tsx +210 -0
  180. package/src/hooks/useToast.tsx +55 -0
  181. package/src/main.tsx +10 -0
  182. package/src/pages/Analytics.tsx +386 -0
  183. package/src/pages/CurrentSession.tsx +1174 -0
  184. package/src/pages/Dashboard.tsx +319 -0
  185. package/src/pages/Documents.tsx +317 -0
  186. package/src/pages/Projects.tsx +250 -0
  187. package/src/pages/Reporting.tsx +386 -0
  188. package/src/pages/Search.tsx +349 -0
  189. package/src/pages/Sessions.tsx +285 -0
  190. package/src/pages/Settings.tsx +2662 -0
  191. package/src/services/HyperlinkService.ts +1085 -0
  192. package/src/services/document/DocXMLaterProcessor.ts +617 -0
  193. package/src/services/document/DocumentProcessingComparison.ts +856 -0
  194. package/src/services/document/DocumentSnapshotService.ts +575 -0
  195. package/src/services/document/WordDocumentProcessor.ts +10509 -0
  196. package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
  197. package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
  198. package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
  199. package/src/services/document/blanklines/BlankLineManager.ts +658 -0
  200. package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
  201. package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
  202. package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
  203. package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
  204. package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
  205. package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
  206. package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
  207. package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
  208. package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
  209. package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
  210. package/src/services/document/blanklines/index.ts +67 -0
  211. package/src/services/document/blanklines/rules/additionRules.ts +337 -0
  212. package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
  213. package/src/services/document/blanklines/rules/removalRules.ts +362 -0
  214. package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
  215. package/src/services/document/blanklines/types.ts +29 -0
  216. package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
  217. package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
  218. package/src/services/document/helpers/whitespace.ts +117 -0
  219. package/src/services/document/list/ListNormalizer.ts +947 -0
  220. package/src/services/document/list/index.ts +45 -0
  221. package/src/services/document/list/list-detection.ts +275 -0
  222. package/src/services/document/list/list-types.ts +162 -0
  223. package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
  224. package/src/services/document/processors/ListProcessor.ts +257 -0
  225. package/src/services/document/processors/StructureProcessor.ts +176 -0
  226. package/src/services/document/processors/StyleProcessor.ts +389 -0
  227. package/src/services/document/processors/TableProcessor.ts +2238 -0
  228. package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
  229. package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
  230. package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
  231. package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
  232. package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
  233. package/src/services/document/processors/index.ts +28 -0
  234. package/src/services/document/types/docx-processing.ts +310 -0
  235. package/src/services/editor/EditorActionHandlers.ts +901 -0
  236. package/src/services/editor/index.ts +13 -0
  237. package/src/setupTests.ts +47 -0
  238. package/src/styles/global.css +782 -0
  239. package/src/types/backup.ts +132 -0
  240. package/src/types/dictionary.ts +125 -0
  241. package/src/types/document-processing.ts +331 -0
  242. package/src/types/docxmlater-augments.d.ts +142 -0
  243. package/src/types/editor.ts +280 -0
  244. package/src/types/electron.ts +340 -0
  245. package/src/types/globalStats.ts +155 -0
  246. package/src/types/hyperlink.ts +471 -0
  247. package/src/types/operations.ts +354 -0
  248. package/src/types/session.ts +427 -0
  249. package/src/types/settings.ts +112 -0
  250. package/src/utils/MemoryMonitor.ts +248 -0
  251. package/src/utils/cn.ts +6 -0
  252. package/src/utils/colorConvert.ts +306 -0
  253. package/src/utils/diffUtils.ts +347 -0
  254. package/src/utils/documentUtils.ts +202 -0
  255. package/src/utils/electronGuard.ts +62 -0
  256. package/src/utils/indexedDB.ts +915 -0
  257. package/src/utils/logger.ts +717 -0
  258. package/src/utils/pathSecurity.ts +232 -0
  259. package/src/utils/pathValidator.ts +236 -0
  260. package/src/utils/processingTimeEstimator.ts +153 -0
  261. package/src/utils/safeJsonParse.ts +62 -0
  262. package/src/utils/textSanitizer.ts +162 -0
  263. package/src/utils/urlHelpers.ts +304 -0
  264. package/src/utils/urlPatterns.ts +198 -0
  265. package/src/utils/urlSanitizer.ts +152 -0
  266. package/src/vite-env.d.ts +11 -0
  267. package/tsconfig.electron.json +19 -0
  268. package/tsconfig.json +36 -0
  269. package/tsconfig.node.json +12 -0
  270. package/typedoc.json +45 -0
  271. package/vite.config.ts +152 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * EditorToolbar - Toolbar for the document editor modal
3
+ *
4
+ * Contains:
5
+ * - Document title
6
+ * - Undo/Redo buttons
7
+ * - Quick formatting actions dropdown
8
+ * - Save and Close buttons
9
+ */
10
+
11
+ import { useState, useCallback } from 'react';
12
+ import { motion, AnimatePresence } from 'framer-motion';
13
+ import {
14
+ X,
15
+ Save,
16
+ Undo2,
17
+ Redo2,
18
+ ChevronDown,
19
+ Bold,
20
+ Italic,
21
+ Underline,
22
+ RemoveFormatting,
23
+ Link2,
24
+ Unlink,
25
+ FileText,
26
+ ListOrdered,
27
+ Table2,
28
+ Search,
29
+ Check,
30
+ XCircle,
31
+ Loader2,
32
+ } from 'lucide-react';
33
+ import { cn } from '@/utils/cn';
34
+ import type { QuickActionId, EditorState } from '@/types/editor';
35
+
36
+ interface EditorToolbarProps {
37
+ /** Document name/title */
38
+ documentName: string;
39
+ /** Whether there are unsaved changes */
40
+ isDirty: boolean;
41
+ /** Whether save is in progress */
42
+ isSaving: boolean;
43
+ /** Whether undo is available */
44
+ canUndo: boolean;
45
+ /** Whether redo is available */
46
+ canRedo: boolean;
47
+ /** Close handler */
48
+ onClose: () => void;
49
+ /** Save handler */
50
+ onSave: () => void;
51
+ /** Undo handler */
52
+ onUndo: () => void;
53
+ /** Redo handler */
54
+ onRedo: () => void;
55
+ /** Quick action handler */
56
+ onQuickAction: (actionId: QuickActionId) => void;
57
+ }
58
+
59
+ /**
60
+ * Dropdown menu for quick actions
61
+ */
62
+ function QuickActionsDropdown({
63
+ onAction,
64
+ disabled,
65
+ }: {
66
+ onAction: (actionId: QuickActionId) => void;
67
+ disabled: boolean;
68
+ }) {
69
+ const [isOpen, setIsOpen] = useState(false);
70
+
71
+ const actionGroups = [
72
+ {
73
+ label: 'Text Formatting',
74
+ actions: [
75
+ { id: 'bold' as QuickActionId, icon: Bold, label: 'Bold', shortcut: 'Ctrl+B' },
76
+ { id: 'italic' as QuickActionId, icon: Italic, label: 'Italic', shortcut: 'Ctrl+I' },
77
+ {
78
+ id: 'underline' as QuickActionId,
79
+ icon: Underline,
80
+ label: 'Underline',
81
+ shortcut: 'Ctrl+U',
82
+ },
83
+ {
84
+ id: 'clear-formatting' as QuickActionId,
85
+ icon: RemoveFormatting,
86
+ label: 'Clear Formatting',
87
+ },
88
+ ],
89
+ },
90
+ {
91
+ label: 'Hyperlinks',
92
+ actions: [
93
+ { id: 'insert-hyperlink' as QuickActionId, icon: Link2, label: 'Insert Hyperlink' },
94
+ { id: 'remove-hyperlink' as QuickActionId, icon: Unlink, label: 'Remove Hyperlink' },
95
+ ],
96
+ },
97
+ {
98
+ label: 'Styles',
99
+ actions: [
100
+ { id: 'style-heading1' as QuickActionId, icon: FileText, label: 'Heading 1' },
101
+ { id: 'style-heading2' as QuickActionId, icon: FileText, label: 'Heading 2' },
102
+ { id: 'style-normal' as QuickActionId, icon: FileText, label: 'Normal' },
103
+ { id: 'style-list' as QuickActionId, icon: ListOrdered, label: 'List Paragraph' },
104
+ ],
105
+ },
106
+ {
107
+ label: 'Tracked Changes',
108
+ actions: [
109
+ { id: 'accept-all' as QuickActionId, icon: Check, label: 'Accept All Changes' },
110
+ { id: 'reject-all' as QuickActionId, icon: XCircle, label: 'Reject All Changes' },
111
+ ],
112
+ },
113
+ ];
114
+
115
+ return (
116
+ <div className="relative">
117
+ <button
118
+ onClick={() => setIsOpen(!isOpen)}
119
+ disabled={disabled}
120
+ className={cn(
121
+ 'flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-lg transition-colors',
122
+ 'hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed'
123
+ )}
124
+ >
125
+ Quick Actions
126
+ <ChevronDown
127
+ className={cn('w-4 h-4 transition-transform', isOpen && 'rotate-180')}
128
+ />
129
+ </button>
130
+
131
+ <AnimatePresence>
132
+ {isOpen && (
133
+ <>
134
+ {/* Backdrop */}
135
+ <div
136
+ className="fixed inset-0 z-40"
137
+ onClick={() => setIsOpen(false)}
138
+ />
139
+
140
+ {/* Dropdown */}
141
+ <motion.div
142
+ initial={{ opacity: 0, y: -10 }}
143
+ animate={{ opacity: 1, y: 0 }}
144
+ exit={{ opacity: 0, y: -10 }}
145
+ transition={{ duration: 0.15 }}
146
+ className="absolute right-0 top-full mt-1 z-50 w-64 bg-popover border border-border rounded-lg shadow-lg overflow-hidden"
147
+ >
148
+ {actionGroups.map((group, groupIdx) => (
149
+ <div key={group.label}>
150
+ {groupIdx > 0 && <div className="h-px bg-border" />}
151
+ <div className="px-3 py-2 text-xs font-medium text-muted-foreground bg-muted/30">
152
+ {group.label}
153
+ </div>
154
+ {group.actions.map((action) => (
155
+ <button
156
+ key={action.id}
157
+ onClick={() => {
158
+ onAction(action.id);
159
+ setIsOpen(false);
160
+ }}
161
+ className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted transition-colors"
162
+ >
163
+ <action.icon className="w-4 h-4" />
164
+ <span className="flex-1 text-left">{action.label}</span>
165
+ {action.shortcut && (
166
+ <span className="text-xs text-muted-foreground">
167
+ {action.shortcut}
168
+ </span>
169
+ )}
170
+ </button>
171
+ ))}
172
+ </div>
173
+ ))}
174
+ </motion.div>
175
+ </>
176
+ )}
177
+ </AnimatePresence>
178
+ </div>
179
+ );
180
+ }
181
+
182
+ /**
183
+ * Main EditorToolbar component
184
+ */
185
+ export function EditorToolbar({
186
+ documentName,
187
+ isDirty,
188
+ isSaving,
189
+ canUndo,
190
+ canRedo,
191
+ onClose,
192
+ onSave,
193
+ onUndo,
194
+ onRedo,
195
+ onQuickAction,
196
+ }: EditorToolbarProps) {
197
+ const handleClose = useCallback(() => {
198
+ if (isDirty) {
199
+ // Show confirmation dialog
200
+ const confirmed = window.confirm(
201
+ 'You have unsaved changes. Are you sure you want to close without saving?'
202
+ );
203
+ if (!confirmed) return;
204
+ }
205
+ onClose();
206
+ }, [isDirty, onClose]);
207
+
208
+ return (
209
+ <div className="flex items-center justify-between px-4 py-3 bg-card border-b border-border">
210
+ {/* Left section - Close button and document name */}
211
+ <div className="flex items-center gap-4">
212
+ <button
213
+ onClick={handleClose}
214
+ className="p-1.5 rounded-lg hover:bg-muted transition-colors"
215
+ title="Close (discard changes)"
216
+ >
217
+ <X className="w-5 h-5" />
218
+ </button>
219
+
220
+ <div className="flex items-center gap-2">
221
+ <FileText className="w-5 h-5 text-muted-foreground" />
222
+ <span className="font-medium">{documentName}</span>
223
+ {isDirty && (
224
+ <span className="px-1.5 py-0.5 text-xs bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-300 rounded">
225
+ Unsaved
226
+ </span>
227
+ )}
228
+ </div>
229
+ </div>
230
+
231
+ {/* Center section - Undo/Redo and Quick Actions */}
232
+ <div className="flex items-center gap-2">
233
+ {/* Undo/Redo */}
234
+ <div className="flex items-center gap-1 pr-2 border-r border-border">
235
+ <button
236
+ onClick={onUndo}
237
+ disabled={!canUndo}
238
+ className="p-1.5 rounded-lg hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
239
+ title="Undo (Ctrl+Z)"
240
+ >
241
+ <Undo2 className="w-4 h-4" />
242
+ </button>
243
+ <button
244
+ onClick={onRedo}
245
+ disabled={!canRedo}
246
+ className="p-1.5 rounded-lg hover:bg-muted disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
247
+ title="Redo (Ctrl+Y)"
248
+ >
249
+ <Redo2 className="w-4 h-4" />
250
+ </button>
251
+ </div>
252
+
253
+ {/* Quick formatting buttons */}
254
+ <div className="flex items-center gap-1 pr-2 border-r border-border">
255
+ <button
256
+ onClick={() => onQuickAction('bold')}
257
+ className="p-1.5 rounded-lg hover:bg-muted transition-colors"
258
+ title="Bold (Ctrl+B)"
259
+ >
260
+ <Bold className="w-4 h-4" />
261
+ </button>
262
+ <button
263
+ onClick={() => onQuickAction('italic')}
264
+ className="p-1.5 rounded-lg hover:bg-muted transition-colors"
265
+ title="Italic (Ctrl+I)"
266
+ >
267
+ <Italic className="w-4 h-4" />
268
+ </button>
269
+ <button
270
+ onClick={() => onQuickAction('underline')}
271
+ className="p-1.5 rounded-lg hover:bg-muted transition-colors"
272
+ title="Underline (Ctrl+U)"
273
+ >
274
+ <Underline className="w-4 h-4" />
275
+ </button>
276
+ </div>
277
+
278
+ {/* Quick Actions dropdown */}
279
+ <QuickActionsDropdown onAction={onQuickAction} disabled={isSaving} />
280
+ </div>
281
+
282
+ {/* Right section - Save button */}
283
+ <div className="flex items-center gap-2">
284
+ <button
285
+ onClick={onSave}
286
+ disabled={isSaving || !isDirty}
287
+ className={cn(
288
+ 'flex items-center gap-2 px-4 py-2 rounded-lg font-medium transition-colors',
289
+ isDirty
290
+ ? 'bg-primary text-primary-foreground hover:bg-primary/90'
291
+ : 'bg-muted text-muted-foreground',
292
+ (isSaving || !isDirty) && 'opacity-50 cursor-not-allowed'
293
+ )}
294
+ >
295
+ {isSaving ? (
296
+ <>
297
+ <Loader2 className="w-4 h-4 animate-spin" />
298
+ Saving...
299
+ </>
300
+ ) : (
301
+ <>
302
+ <Save className="w-4 h-4" />
303
+ Save
304
+ </>
305
+ )}
306
+ </button>
307
+ </div>
308
+ </div>
309
+ );
310
+ }
311
+
312
+ export default EditorToolbar;