@actuate-media/cms-admin 0.1.0

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 (295) hide show
  1. package/dist/AdminRoot.d.ts +21 -0
  2. package/dist/AdminRoot.d.ts.map +1 -0
  3. package/dist/AdminRoot.js +136 -0
  4. package/dist/AdminRoot.js.map +1 -0
  5. package/dist/components/Breadcrumbs.d.ts +6 -0
  6. package/dist/components/Breadcrumbs.d.ts.map +1 -0
  7. package/dist/components/Breadcrumbs.js +52 -0
  8. package/dist/components/Breadcrumbs.js.map +1 -0
  9. package/dist/components/CommandPalette.d.ts +7 -0
  10. package/dist/components/CommandPalette.d.ts.map +1 -0
  11. package/dist/components/CommandPalette.js +152 -0
  12. package/dist/components/CommandPalette.js.map +1 -0
  13. package/dist/components/ErrorBoundary.d.ts +17 -0
  14. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  15. package/dist/components/ErrorBoundary.js +24 -0
  16. package/dist/components/ErrorBoundary.js.map +1 -0
  17. package/dist/components/FocalPointPicker.d.ts +9 -0
  18. package/dist/components/FocalPointPicker.d.ts.map +1 -0
  19. package/dist/components/FocalPointPicker.js +19 -0
  20. package/dist/components/FocalPointPicker.js.map +1 -0
  21. package/dist/components/FolderTree.d.ts +28 -0
  22. package/dist/components/FolderTree.d.ts.map +1 -0
  23. package/dist/components/FolderTree.js +198 -0
  24. package/dist/components/FolderTree.js.map +1 -0
  25. package/dist/components/LivePreview.d.ts +10 -0
  26. package/dist/components/LivePreview.d.ts.map +1 -0
  27. package/dist/components/LivePreview.js +62 -0
  28. package/dist/components/LivePreview.js.map +1 -0
  29. package/dist/components/LocaleProvider.d.ts +28 -0
  30. package/dist/components/LocaleProvider.d.ts.map +1 -0
  31. package/dist/components/LocaleProvider.js +29 -0
  32. package/dist/components/LocaleProvider.js.map +1 -0
  33. package/dist/components/LocaleSwitcher.d.ts +2 -0
  34. package/dist/components/LocaleSwitcher.d.ts.map +1 -0
  35. package/dist/components/LocaleSwitcher.js +13 -0
  36. package/dist/components/LocaleSwitcher.js.map +1 -0
  37. package/dist/components/MediaPickerModal.d.ts +8 -0
  38. package/dist/components/MediaPickerModal.d.ts.map +1 -0
  39. package/dist/components/MediaPickerModal.js +53 -0
  40. package/dist/components/MediaPickerModal.js.map +1 -0
  41. package/dist/components/PresenceIndicator.d.ts +7 -0
  42. package/dist/components/PresenceIndicator.d.ts.map +1 -0
  43. package/dist/components/PresenceIndicator.js +37 -0
  44. package/dist/components/PresenceIndicator.js.map +1 -0
  45. package/dist/components/SEOPanel.d.ts +26 -0
  46. package/dist/components/SEOPanel.d.ts.map +1 -0
  47. package/dist/components/SEOPanel.js +249 -0
  48. package/dist/components/SEOPanel.js.map +1 -0
  49. package/dist/components/ThemeProvider.d.ts +13 -0
  50. package/dist/components/ThemeProvider.d.ts.map +1 -0
  51. package/dist/components/ThemeProvider.js +62 -0
  52. package/dist/components/ThemeProvider.js.map +1 -0
  53. package/dist/components/TipTapEditor.d.ts +9 -0
  54. package/dist/components/TipTapEditor.d.ts.map +1 -0
  55. package/dist/components/TipTapEditor.js +167 -0
  56. package/dist/components/TipTapEditor.js.map +1 -0
  57. package/dist/components/VersionHistory.d.ts +9 -0
  58. package/dist/components/VersionHistory.d.ts.map +1 -0
  59. package/dist/components/VersionHistory.js +70 -0
  60. package/dist/components/VersionHistory.js.map +1 -0
  61. package/dist/components/ui/Avatar.d.ts +9 -0
  62. package/dist/components/ui/Avatar.d.ts.map +1 -0
  63. package/dist/components/ui/Avatar.js +21 -0
  64. package/dist/components/ui/Avatar.js.map +1 -0
  65. package/dist/components/ui/Badge.d.ts +5 -0
  66. package/dist/components/ui/Badge.d.ts.map +1 -0
  67. package/dist/components/ui/Badge.js +17 -0
  68. package/dist/components/ui/Badge.js.map +1 -0
  69. package/dist/components/ui/Button.d.ts +12 -0
  70. package/dist/components/ui/Button.d.ts.map +1 -0
  71. package/dist/components/ui/Button.js +17 -0
  72. package/dist/components/ui/Button.js.map +1 -0
  73. package/dist/components/ui/CommandPalette.d.ts +14 -0
  74. package/dist/components/ui/CommandPalette.d.ts.map +1 -0
  75. package/dist/components/ui/CommandPalette.js +52 -0
  76. package/dist/components/ui/CommandPalette.js.map +1 -0
  77. package/dist/components/ui/ConfirmDialog.d.ts +12 -0
  78. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -0
  79. package/dist/components/ui/ConfirmDialog.js +11 -0
  80. package/dist/components/ui/ConfirmDialog.js.map +1 -0
  81. package/dist/components/ui/DataTable.d.ts +30 -0
  82. package/dist/components/ui/DataTable.d.ts.map +1 -0
  83. package/dist/components/ui/DataTable.js +40 -0
  84. package/dist/components/ui/DataTable.js.map +1 -0
  85. package/dist/components/ui/EmptyState.d.ts +10 -0
  86. package/dist/components/ui/EmptyState.d.ts.map +1 -0
  87. package/dist/components/ui/EmptyState.js +6 -0
  88. package/dist/components/ui/EmptyState.js.map +1 -0
  89. package/dist/components/ui/Modal.d.ts +10 -0
  90. package/dist/components/ui/Modal.d.ts.map +1 -0
  91. package/dist/components/ui/Modal.js +19 -0
  92. package/dist/components/ui/Modal.js.map +1 -0
  93. package/dist/components/ui/Pagination.d.ts +9 -0
  94. package/dist/components/ui/Pagination.d.ts.map +1 -0
  95. package/dist/components/ui/Pagination.js +21 -0
  96. package/dist/components/ui/Pagination.js.map +1 -0
  97. package/dist/components/ui/SearchInput.d.ts +7 -0
  98. package/dist/components/ui/SearchInput.d.ts.map +1 -0
  99. package/dist/components/ui/SearchInput.js +6 -0
  100. package/dist/components/ui/SearchInput.js.map +1 -0
  101. package/dist/components/ui/Skeleton.d.ts +9 -0
  102. package/dist/components/ui/Skeleton.d.ts.map +1 -0
  103. package/dist/components/ui/Skeleton.js +11 -0
  104. package/dist/components/ui/Skeleton.js.map +1 -0
  105. package/dist/components/ui/Toast.d.ts +18 -0
  106. package/dist/components/ui/Toast.d.ts.map +1 -0
  107. package/dist/components/ui/Toast.js +29 -0
  108. package/dist/components/ui/Toast.js.map +1 -0
  109. package/dist/components/ui/index.d.ts +25 -0
  110. package/dist/components/ui/index.d.ts.map +1 -0
  111. package/dist/components/ui/index.js +13 -0
  112. package/dist/components/ui/index.js.map +1 -0
  113. package/dist/fields/ArrayField.d.ts +9 -0
  114. package/dist/fields/ArrayField.d.ts.map +1 -0
  115. package/dist/fields/ArrayField.js +21 -0
  116. package/dist/fields/ArrayField.js.map +1 -0
  117. package/dist/fields/BlockBuilderField.d.ts +16 -0
  118. package/dist/fields/BlockBuilderField.d.ts.map +1 -0
  119. package/dist/fields/BlockBuilderField.js +110 -0
  120. package/dist/fields/BlockBuilderField.js.map +1 -0
  121. package/dist/fields/DateField.d.ts +9 -0
  122. package/dist/fields/DateField.d.ts.map +1 -0
  123. package/dist/fields/DateField.js +6 -0
  124. package/dist/fields/DateField.js.map +1 -0
  125. package/dist/fields/FieldRenderer.d.ts +22 -0
  126. package/dist/fields/FieldRenderer.d.ts.map +1 -0
  127. package/dist/fields/FieldRenderer.js +38 -0
  128. package/dist/fields/FieldRenderer.js.map +1 -0
  129. package/dist/fields/GroupField.d.ts +8 -0
  130. package/dist/fields/GroupField.d.ts.map +1 -0
  131. package/dist/fields/GroupField.js +8 -0
  132. package/dist/fields/GroupField.js.map +1 -0
  133. package/dist/fields/MediaField.d.ts +13 -0
  134. package/dist/fields/MediaField.d.ts.map +1 -0
  135. package/dist/fields/MediaField.js +6 -0
  136. package/dist/fields/MediaField.js.map +1 -0
  137. package/dist/fields/NavBuilderField.d.ts +15 -0
  138. package/dist/fields/NavBuilderField.d.ts.map +1 -0
  139. package/dist/fields/NavBuilderField.js +19 -0
  140. package/dist/fields/NavBuilderField.js.map +1 -0
  141. package/dist/fields/NumberField.d.ts +12 -0
  142. package/dist/fields/NumberField.d.ts.map +1 -0
  143. package/dist/fields/NumberField.js +6 -0
  144. package/dist/fields/NumberField.js.map +1 -0
  145. package/dist/fields/RelationshipField.d.ts +13 -0
  146. package/dist/fields/RelationshipField.d.ts.map +1 -0
  147. package/dist/fields/RelationshipField.js +119 -0
  148. package/dist/fields/RelationshipField.js.map +1 -0
  149. package/dist/fields/RichTextField.d.ts +9 -0
  150. package/dist/fields/RichTextField.d.ts.map +1 -0
  151. package/dist/fields/RichTextField.js +7 -0
  152. package/dist/fields/RichTextField.js.map +1 -0
  153. package/dist/fields/SelectField.d.ts +11 -0
  154. package/dist/fields/SelectField.d.ts.map +1 -0
  155. package/dist/fields/SelectField.js +31 -0
  156. package/dist/fields/SelectField.js.map +1 -0
  157. package/dist/fields/SlugField.d.ts +10 -0
  158. package/dist/fields/SlugField.d.ts.map +1 -0
  159. package/dist/fields/SlugField.js +15 -0
  160. package/dist/fields/SlugField.js.map +1 -0
  161. package/dist/fields/TextField.d.ts +11 -0
  162. package/dist/fields/TextField.d.ts.map +1 -0
  163. package/dist/fields/TextField.js +8 -0
  164. package/dist/fields/TextField.js.map +1 -0
  165. package/dist/fields/ToggleField.d.ts +8 -0
  166. package/dist/fields/ToggleField.d.ts.map +1 -0
  167. package/dist/fields/ToggleField.js +6 -0
  168. package/dist/fields/ToggleField.js.map +1 -0
  169. package/dist/fields/block-types.d.ts +18 -0
  170. package/dist/fields/block-types.d.ts.map +1 -0
  171. package/dist/fields/block-types.js +88 -0
  172. package/dist/fields/block-types.js.map +1 -0
  173. package/dist/fields/index.d.ts +18 -0
  174. package/dist/fields/index.d.ts.map +1 -0
  175. package/dist/fields/index.js +16 -0
  176. package/dist/fields/index.js.map +1 -0
  177. package/dist/hooks/useContentLock.d.ts +12 -0
  178. package/dist/hooks/useContentLock.d.ts.map +1 -0
  179. package/dist/hooks/useContentLock.js +38 -0
  180. package/dist/hooks/useContentLock.js.map +1 -0
  181. package/dist/hooks/useDebounce.d.ts +2 -0
  182. package/dist/hooks/useDebounce.d.ts.map +1 -0
  183. package/dist/hooks/useDebounce.js +11 -0
  184. package/dist/hooks/useDebounce.js.map +1 -0
  185. package/dist/hooks/useKeyboardShortcuts.d.ts +6 -0
  186. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  187. package/dist/hooks/useKeyboardShortcuts.js +26 -0
  188. package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
  189. package/dist/index.d.ts +52 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +39 -0
  192. package/dist/index.js.map +1 -0
  193. package/dist/layout/Header.d.ts +7 -0
  194. package/dist/layout/Header.d.ts.map +1 -0
  195. package/dist/layout/Header.js +18 -0
  196. package/dist/layout/Header.js.map +1 -0
  197. package/dist/layout/Layout.d.ts +10 -0
  198. package/dist/layout/Layout.d.ts.map +1 -0
  199. package/dist/layout/Layout.js +25 -0
  200. package/dist/layout/Layout.js.map +1 -0
  201. package/dist/layout/Sidebar.d.ts +9 -0
  202. package/dist/layout/Sidebar.d.ts.map +1 -0
  203. package/dist/layout/Sidebar.js +63 -0
  204. package/dist/layout/Sidebar.js.map +1 -0
  205. package/dist/lib/api.d.ts +8 -0
  206. package/dist/lib/api.d.ts.map +1 -0
  207. package/dist/lib/api.js +59 -0
  208. package/dist/lib/api.js.map +1 -0
  209. package/dist/lib/search.d.ts +11 -0
  210. package/dist/lib/search.d.ts.map +1 -0
  211. package/dist/lib/search.js +46 -0
  212. package/dist/lib/search.js.map +1 -0
  213. package/dist/lib/useApiData.d.ts +8 -0
  214. package/dist/lib/useApiData.d.ts.map +1 -0
  215. package/dist/lib/useApiData.js +36 -0
  216. package/dist/lib/useApiData.js.map +1 -0
  217. package/dist/lib/utils.d.ts +3 -0
  218. package/dist/lib/utils.d.ts.map +1 -0
  219. package/dist/lib/utils.js +6 -0
  220. package/dist/lib/utils.js.map +1 -0
  221. package/dist/router/index.d.ts +10 -0
  222. package/dist/router/index.d.ts.map +1 -0
  223. package/dist/router/index.js +61 -0
  224. package/dist/router/index.js.map +1 -0
  225. package/dist/views/CollectionList.d.ts +7 -0
  226. package/dist/views/CollectionList.d.ts.map +1 -0
  227. package/dist/views/CollectionList.js +107 -0
  228. package/dist/views/CollectionList.js.map +1 -0
  229. package/dist/views/Dashboard.d.ts +5 -0
  230. package/dist/views/Dashboard.d.ts.map +1 -0
  231. package/dist/views/Dashboard.js +17 -0
  232. package/dist/views/Dashboard.js.map +1 -0
  233. package/dist/views/DocumentEdit.d.ts +8 -0
  234. package/dist/views/DocumentEdit.d.ts.map +1 -0
  235. package/dist/views/DocumentEdit.js +210 -0
  236. package/dist/views/DocumentEdit.js.map +1 -0
  237. package/dist/views/FormEditor.d.ts +6 -0
  238. package/dist/views/FormEditor.d.ts.map +1 -0
  239. package/dist/views/FormEditor.js +126 -0
  240. package/dist/views/FormEditor.js.map +1 -0
  241. package/dist/views/FormSubmissions.d.ts +6 -0
  242. package/dist/views/FormSubmissions.d.ts.map +1 -0
  243. package/dist/views/FormSubmissions.js +88 -0
  244. package/dist/views/FormSubmissions.js.map +1 -0
  245. package/dist/views/Forms.d.ts +5 -0
  246. package/dist/views/Forms.d.ts.map +1 -0
  247. package/dist/views/Forms.js +24 -0
  248. package/dist/views/Forms.js.map +1 -0
  249. package/dist/views/Login.d.ts +10 -0
  250. package/dist/views/Login.d.ts.map +1 -0
  251. package/dist/views/Login.js +83 -0
  252. package/dist/views/Login.js.map +1 -0
  253. package/dist/views/MediaBrowser.d.ts +5 -0
  254. package/dist/views/MediaBrowser.d.ts.map +1 -0
  255. package/dist/views/MediaBrowser.js +245 -0
  256. package/dist/views/MediaBrowser.js.map +1 -0
  257. package/dist/views/PageEditor.d.ts +6 -0
  258. package/dist/views/PageEditor.d.ts.map +1 -0
  259. package/dist/views/PageEditor.js +74 -0
  260. package/dist/views/PageEditor.js.map +1 -0
  261. package/dist/views/Pages.d.ts +5 -0
  262. package/dist/views/Pages.d.ts.map +1 -0
  263. package/dist/views/Pages.js +127 -0
  264. package/dist/views/Pages.js.map +1 -0
  265. package/dist/views/PostEditor.d.ts +6 -0
  266. package/dist/views/PostEditor.d.ts.map +1 -0
  267. package/dist/views/PostEditor.js +79 -0
  268. package/dist/views/PostEditor.js.map +1 -0
  269. package/dist/views/Posts.d.ts +5 -0
  270. package/dist/views/Posts.d.ts.map +1 -0
  271. package/dist/views/Posts.js +67 -0
  272. package/dist/views/Posts.js.map +1 -0
  273. package/dist/views/Redirects.d.ts +5 -0
  274. package/dist/views/Redirects.d.ts.map +1 -0
  275. package/dist/views/Redirects.js +79 -0
  276. package/dist/views/Redirects.js.map +1 -0
  277. package/dist/views/SEO.d.ts +6 -0
  278. package/dist/views/SEO.d.ts.map +1 -0
  279. package/dist/views/SEO.js +120 -0
  280. package/dist/views/SEO.js.map +1 -0
  281. package/dist/views/Settings.d.ts +5 -0
  282. package/dist/views/Settings.d.ts.map +1 -0
  283. package/dist/views/Settings.js +95 -0
  284. package/dist/views/Settings.js.map +1 -0
  285. package/dist/views/SetupWizard.d.ts +13 -0
  286. package/dist/views/SetupWizard.d.ts.map +1 -0
  287. package/dist/views/SetupWizard.js +68 -0
  288. package/dist/views/SetupWizard.js.map +1 -0
  289. package/dist/views/Users.d.ts +5 -0
  290. package/dist/views/Users.d.ts.map +1 -0
  291. package/dist/views/Users.js +69 -0
  292. package/dist/views/Users.js.map +1 -0
  293. package/package.json +71 -0
  294. package/src/styles/tailwind.css +2 -0
  295. package/src/styles/theme.css +175 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pages.js","sourceRoot":"","sources":["../../src/views/Pages.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnK,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAmB,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,UAAU,EAAwB,MAAM,0BAA0B,CAAC;AAQ5E,SAAS,WAAW,CAAC,SAA0B;IAC7C,MAAM,IAAI,GAAG,iCAAiC,CAAC;IAC/C,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC/B,IAAI,SAAS,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,GAAG,IAAI,wCAAwC,CAAC;QACzF,IAAI,SAAS,CAAC,KAAK,KAAK,eAAe;YAAE,OAAO,GAAG,IAAI,gBAAgB,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,IAAI,aAAa,SAAS,CAAC,QAAQ,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAE,UAAU,EAAc;IAC9C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAkB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7F,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAClE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAAiC,MAAM,CAAC,CAAC;IAE7F,MAAM,OAAO,GAAG,UAAU,CAAiC,+BAA+B,CAAC,CAAC;IAC5F,MAAM,SAAS,GAAG,UAAU,CAAiC,6CAA6C,CAAC,CAAC;IAE5G,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,CAAC;IAChE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,CAAC;IACpE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAiC,IAAI,CAAC,CAAC;IAEnF,MAAM,KAAK,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;IAE/B,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE;YACvC,MAAM,aAAa,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;gBACxF,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;YACxE,MAAM,aAAa,GAAG,YAAY,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,WAAW,EAAE,CAAC;YACjH,MAAM,eAAe,GAAG,cAAc,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,WAAW,EAAE,CAAC;YACzH,OAAO,aAAa,IAAI,aAAa,IAAI,eAAe,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3G,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE;gBAC7C,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrD,OAAO,UAAU,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAEnE,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAE,EAAE;QAC3C,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,EAAU,EAAE,EAAE;QACtC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,sBAAsB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,gBAAgB,CAAC,CAAC;QACvD,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;QACnC,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,sBAAsB,EAAE,EAAE,EAAE;gBACvC,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;aAC9C,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,kBAAkB,CAAC,CAAC;QACzD,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE;QACrC,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,sBAAsB,EAAE,EAAE,EAAE;gBACvC,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAC3D,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,EAAE,EAAU,EAAE,EAAE;QACxC,MAAM,MAAM,CAAC,sBAAsB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC9B,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,EAAE,MAAc,EAAE,QAAuB,EAAE,EAAE;QACnF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,cAAc,MAAM,SAAS,EAAE;YACtD,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;SACnC,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;YACpE,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,eAAe,GAAG,CAAC,CAAkB,EAAE,EAAU,EAAE,EAAE;QACzD,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,CAAC;IAEF,SAAS,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAA2C;QAC7E,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,KAAK,OAAO,CAAC;QAC3C,OAAO,CACL,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,EAC7D,SAAS,EAAC,iGAAiG,aAE1G,KAAK,EACL,MAAM,CAAC,CAAC,CAAC,CACR,UAAW,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,CACtG,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,IAAC,SAAS,EAAC,uBAAuB,GAAG,CAClD,IACM,CACV,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,cAAK,SAAS,EAAC,+DAA+D,YAC5E,KAAC,OAAO,IAAC,SAAS,EAAC,oCAAoC,GAAG,GACtD,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,8CAA8C,aAC1D,KAAK,IAAI,CACR,eAAK,SAAS,EAAC,6EAA6E,aAC1F,KAAC,aAAa,IAAC,SAAS,EAAC,+BAA+B,GAAG,EAC3D,eAAM,SAAS,EAAC,6BAA6B,YAAE,KAAK,GAAQ,EAC5D,iBAAQ,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,oGAAoG,sBAAe,IACnJ,CACP,EAED,eAAK,SAAS,EAAC,sEAAsE,aACnF,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAC5C,SAAS,EAAC,sDAAsD,EAChE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,YAEpD,KAAC,WAAW,IAAC,SAAS,EAAC,uBAAuB,GAAG,GAC1C,EACT,0BACE,aAAI,SAAS,EAAC,sDAAsD,sBAAW,EAC/E,aAAG,SAAS,EAAC,uBAAuB,aAAE,iBAAiB,CAAC,MAAM,oBAAiB,IAC3E,IACF,EACN,kBACE,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,EACzC,SAAS,EAAC,gIAAgI,aAE1I,KAAC,IAAI,IAAC,SAAS,EAAC,SAAS,GAAG,EAC5B,eAAM,SAAS,EAAC,kBAAkB,yBAAgB,EAClD,eAAM,SAAS,EAAC,WAAW,oBAAW,IAC/B,IACL,EAEN,eAAK,SAAS,EAAC,2CAA2C,aACvD,WAAW,IAAI,CACd,cAAK,SAAS,EAAC,wFAAwF,YACrG,KAAC,UAAU,IACT,KAAK,EAAC,OAAO,EACb,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAC/D,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAC/B,kBAAkB,EAAE,SAAS,CAAC,IAAI,EAAE,KAAK,EACzC,UAAU,EAAE,cAAc,GAC1B,GACE,CACP,EAED,eAAK,SAAS,EAAC,8BAA8B,aAC3C,cAAK,SAAS,EAAC,iDAAiD,YAC9D,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAK,SAAS,EAAC,UAAU,aACvB,KAAC,MAAM,IAAC,SAAS,EAAC,gEAAgE,GAAG,EACrF,gBAAO,IAAI,EAAC,MAAM,EAAC,WAAW,EAAC,iBAAiB,EAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,qHAAqH,GAAG,IACpP,EACN,eAAK,SAAS,EAAC,iCAAiC,aAC9C,kBAAQ,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,gHAAgH,aACvM,iBAAQ,KAAK,EAAC,KAAK,2BAAoB,EACvC,iBAAQ,KAAK,EAAC,WAAW,0BAAmB,EAC5C,iBAAQ,KAAK,EAAC,OAAO,sBAAe,IAC7B,EACT,kBAAQ,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,gHAAgH,aAC3M,iBAAQ,KAAK,EAAC,KAAK,8BAAuB,EAC1C,iBAAQ,KAAK,EAAC,SAAS,wBAAiB,EACxC,iBAAQ,KAAK,EAAC,UAAU,yBAAkB,EAC1C,iBAAQ,KAAK,EAAC,WAAW,0BAAmB,EAC5C,iBAAQ,KAAK,EAAC,MAAM,qBAAc,IAC3B,EACT,kBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,+HAA+H,aAC7J,KAAC,iBAAiB,IAAC,SAAS,EAAC,SAAS,GAAG,EACzC,eAAM,SAAS,EAAC,kBAAkB,6BAAoB,IAC/C,IACL,IACF,GACF,EAEL,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAC3B,cAAK,SAAS,EAAC,uDAAuD,YACpE,eAAK,SAAS,EAAC,iEAAiE,aAC9E,gBAAM,SAAS,EAAC,uBAAuB,aAAE,aAAa,CAAC,MAAM,WAAO,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAC1H,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAC,iHAAiH,wBAAiB,EAC9L,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAC,mHAAmH,0BAAmB,EACpM,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAC,6GAA6G,uBAAgB,EACxL,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,uHAAuH,uBAAgB,IACxM,IACF,GACF,CACP,EAEA,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAC1C,eAAK,SAAS,EAAC,6GAA6G,aAC1H,YAAG,SAAS,EAAC,4BAA4B,YACtC,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,KAAK,KAAK,eAAe;4CAChE,CAAC,CAAC,wBAAwB;4CAC1B,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,QAAQ;gDAC7B,CAAC,CAAC,yBAAyB;gDAC3B,CAAC,CAAC,cAAc,GAChB,EACJ,iBAAQ,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,SAAS,EAAC,yFAAyF,uCAAgC,IAClL,CACP,CAAC,CAAC,CAAC,CACF,8BACE,cAAK,SAAS,EAAC,mFAAmF,YAChG,cAAK,SAAS,EAAC,wBAAwB,YACrC,iBAAO,SAAS,EAAC,QAAQ,aACvB,gBAAO,SAAS,EAAC,kDAAkD,YACjE,yBACE,aAAI,SAAS,EAAC,yBAAyB,YACrC,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,aAAa,CAAC,MAAM,KAAK,iBAAiB,CAAC,MAAM,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,EAAC,yBAAyB,GAAG,GAC1M,EACL,aAAI,SAAS,EAAC,eAAe,GAAM,EACnC,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,OAAO,EAAC,OAAO,EAAC,OAAO,GAAG,GAAK,EACrF,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,QAAQ,GAAG,GAAK,EACvF,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,UAAU,EAAC,OAAO,EAAC,UAAU,GAAG,GAAK,EAC3F,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,QAAQ,GAAG,GAAK,EACvF,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,GAAG,GAAK,EACnF,aAAI,SAAS,EAAC,uDAAuD,wBAAa,IAC/E,GACC,EACR,gBAAO,SAAS,EAAC,0BAA0B,YACxC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CACpC,cAEE,SAAS,EAAC,oCAAoC,EAC9C,SAAS,QACT,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,aAE/C,aAAI,SAAS,EAAC,WAAW,YACvB,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,yBAAyB,GAAG,GAC/I,EACL,aAAI,SAAS,EAAC,uBAAuB,YACnC,KAAC,YAAY,IAAC,SAAS,EAAC,uBAAuB,GAAG,GAC/C,EACL,aAAI,SAAS,EAAC,WAAW,YACvB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,iEAAiE,YAAE,IAAI,CAAC,KAAK,GAAU,GACtK,EACL,aAAI,SAAS,EAAC,iCAAiC,YAAE,IAAI,CAAC,MAAM,GAAM,EAClE,aAAI,SAAS,EAAC,iCAAiC,YAAE,IAAI,CAAC,QAAQ,GAAM,EACpE,aAAI,SAAS,EAAC,WAAW,YACvB,eAAM,SAAS,EAAE,yEAAyE,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,2BAA2B,EAAE,YAAG,IAAI,CAAC,MAAM,GAAQ,GACxM,EACL,aAAI,SAAS,EAAC,iCAAiC,YAAE,IAAI,CAAC,IAAI,GAAM,EAChE,aAAI,SAAS,EAAC,WAAW,YACvB,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,mDAAmD,EAAC,KAAK,EAAC,MAAM,YAChJ,KAAC,MAAM,IAAC,SAAS,EAAC,uBAAuB,GAAG,GACrC,EACT,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,mDAAmD,EAAC,KAAK,EAAC,QAAQ,YACtI,KAAC,MAAM,IAAC,SAAS,EAAC,sBAAsB,GAAG,GACpC,IACL,GACH,KA7BA,IAAI,CAAC,EAAE,CA8BT,CACN,CAAC,GACI,IACF,GACJ,GACF,EAEN,cAAK,SAAS,EAAC,2EAA2E,YACxF,cAAK,SAAS,EAAC,0BAA0B,YACtC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CACpC,cAEE,SAAS,EAAC,KAAK,EACf,SAAS,QACT,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,YAE/C,eAAK,SAAS,EAAC,wBAAwB,aACrC,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,8BAA8B,GAAG,EACvJ,eAAK,SAAS,EAAC,gBAAgB,aAC7B,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,4EAA4E,YAAE,IAAI,CAAC,KAAK,GAAU,EACpL,eAAK,SAAS,EAAC,8DAA8D,aAC3E,yBAAO,IAAI,CAAC,MAAM,GAAQ,EAC1B,oCAAc,EACd,yBAAO,IAAI,CAAC,IAAI,GAAQ,EACxB,eAAM,SAAS,EAAE,gDAAgD,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,2BAA2B,EAAE,YAAG,IAAI,CAAC,MAAM,GAAQ,IAC9K,IACF,EACN,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,mDAAmD,YACvH,KAAC,MAAM,IAAC,SAAS,EAAC,sBAAsB,GAAG,GACpC,IACL,IAnBD,IAAI,CAAC,EAAE,CAoBR,CACP,CAAC,GACE,GACF,IACL,CACJ,IACG,IACF,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface PostEditorProps {
2
+ id?: string;
3
+ onNavigate?: (path: string) => void;
4
+ }
5
+ export declare function PostEditor({ id, onNavigate }: PostEditorProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=PostEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostEditor.d.ts","sourceRoot":"","sources":["../../src/views/PostEditor.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,eAAe,2CA2O7D"}
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useEffect } from 'react';
4
+ import { ArrowLeft, Eye, Loader2, AlertTriangle } from 'lucide-react';
5
+ import { toast } from 'sonner';
6
+ import { TipTapEditor } from '../components/TipTapEditor';
7
+ import { SEOPanel } from '../components/SEOPanel';
8
+ import { useApiData } from '../lib/useApiData';
9
+ import { cmsApi } from '../lib/api';
10
+ export function PostEditor({ id, onNavigate }) {
11
+ const isNew = !id;
12
+ const { data, loading, error } = useApiData(isNew ? '' : `/collections/posts/${id}`);
13
+ const [title, setTitle] = useState('');
14
+ const [content, setContent] = useState('');
15
+ const [status, setStatus] = useState('draft');
16
+ const [slug, setSlug] = useState('');
17
+ const [saving, setSaving] = useState(false);
18
+ const [initialized, setInitialized] = useState(isNew);
19
+ const [seoData, setSeoData] = useState({});
20
+ useEffect(() => {
21
+ if (data && !initialized) {
22
+ setTitle(data.title ?? '');
23
+ setContent(data.content ?? data.data?.content ?? '');
24
+ setStatus(data.status === 'PUBLISHED' ? 'published' : 'draft');
25
+ setSlug(data.slug ?? '');
26
+ setInitialized(true);
27
+ }
28
+ }, [data, initialized]);
29
+ const savePost = async () => {
30
+ setSaving(true);
31
+ const body = JSON.stringify({
32
+ title,
33
+ content,
34
+ slug,
35
+ status: status === 'published' ? 'PUBLISHED' : 'DRAFT',
36
+ });
37
+ const res = isNew
38
+ ? await cmsApi('/collections/posts', { method: 'POST', body })
39
+ : await cmsApi(`/collections/posts/${id}`, { method: 'PUT', body });
40
+ setSaving(false);
41
+ if (res.error) {
42
+ toast.error(res.error);
43
+ }
44
+ else {
45
+ toast.success('Post saved successfully!');
46
+ if (isNew && res.data?.id) {
47
+ onNavigate?.(`/posts/${res.data.id}`);
48
+ }
49
+ }
50
+ };
51
+ const publishPost = async () => {
52
+ setSaving(true);
53
+ const body = JSON.stringify({
54
+ title,
55
+ content,
56
+ slug,
57
+ status: 'PUBLISHED',
58
+ });
59
+ const endpoint = isNew ? '/collections/posts' : `/collections/posts/${id}`;
60
+ const method = isNew ? 'POST' : 'PUT';
61
+ const res = await cmsApi(endpoint, { method, body });
62
+ setSaving(false);
63
+ if (res.error) {
64
+ toast.error(res.error);
65
+ }
66
+ else {
67
+ setStatus('published');
68
+ toast.success('Post published!');
69
+ if (isNew && res.data?.id) {
70
+ onNavigate?.(`/posts/${res.data.id}`);
71
+ }
72
+ }
73
+ };
74
+ if (!isNew && loading) {
75
+ return (_jsx("div", { className: "h-full flex items-center justify-center", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
76
+ }
77
+ return (_jsxs("div", { className: "h-full flex flex-col bg-white", children: [error && (_jsxs("div", { className: "mx-4 mt-3 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: error })] })), _jsx("div", { className: "border-b border-gray-200 px-3 sm:px-4 py-3", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("button", { onClick: () => onNavigate?.('/posts'), className: "inline-flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900 transition-colors", children: [_jsx(ArrowLeft, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "Back to Posts" }), _jsx("span", { className: "sm:hidden", children: "Back" })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs("button", { className: "px-3 py-1.5 text-sm border border-gray-300 rounded-lg flex items-center gap-2 hover:bg-gray-50 transition-colors", children: [_jsx(Eye, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "Preview" })] }) })] }) }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-col lg:flex-row", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsxs("div", { className: "max-w-4xl mx-auto p-3 pr-6 sm:p-4 sm:pr-8", children: [_jsx("input", { type: "text", value: title, onChange: (e) => setTitle(e.target.value), placeholder: "Post title", className: "w-full text-2xl sm:text-3xl font-bold mb-4 px-0 border-none focus:outline-none focus:ring-0 placeholder:text-gray-300" }), _jsxs("div", { className: "mb-4", children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "URL Slug" }), _jsx("input", { type: "text", value: slug, onChange: (e) => setSlug(e.target.value), placeholder: "url-slug", className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsx("div", { className: "mb-4", children: _jsx(TipTapEditor, { content: content, onChange: setContent }) })] }) }), _jsx("div", { className: "hidden lg:block w-[30%] border-l border-gray-200 overflow-y-auto bg-gray-50", children: _jsxs("div", { className: "p-4 space-y-4", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("h3", { className: "font-semibold text-gray-900 mb-3 text-sm", children: "Publish" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Status" }), _jsxs("select", { value: status, onChange: (e) => setStatus(e.target.value), className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "draft", children: "Draft" }), _jsx("option", { value: "published", children: "Published" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Publish Date" }), _jsx("input", { type: "datetime-local", className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsx("button", { onClick: savePost, disabled: saving, className: "w-full py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium disabled:opacity-50", children: saving ? 'Saving...' : 'Save Post' }), status === 'draft' && (_jsx("button", { onClick: publishPost, disabled: saving, className: "w-full py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium disabled:opacity-50", children: saving ? 'Publishing...' : 'Publish' }))] })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("h3", { className: "font-semibold text-gray-900 mb-3 text-sm", children: "Categories & Tags" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Category" }), _jsxs("select", { className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { children: "Technology" }), _jsx("option", { children: "Design" }), _jsx("option", { children: "Business" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Tags" }), _jsx("input", { type: "text", placeholder: "Add tags...", className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] })] })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("h3", { className: "font-semibold text-gray-900 mb-3 text-sm", children: "Featured Image" }), _jsx("button", { className: "w-full py-2 border-2 border-dashed border-gray-300 rounded-lg hover:border-gray-400 transition-colors text-sm text-gray-600", children: "Upload Image" })] }), _jsx(SEOPanel, { title: title, slug: slug, content: content, seoData: seoData, onChange: setSeoData })] }) }), _jsx("div", { className: "lg:hidden border-t border-gray-200 p-3 bg-white", children: _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: savePost, disabled: saving, className: "flex-1 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium disabled:opacity-50", children: saving ? 'Saving...' : 'Save Post' }), status === 'draft' && (_jsx("button", { onClick: publishPost, disabled: saving, className: "flex-1 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium disabled:opacity-50", children: "Publish" }))] }) })] })] }));
78
+ }
79
+ //# sourceMappingURL=PostEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostEditor.js","sourceRoot":"","sources":["../../src/views/PostEditor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface PostsProps {
2
+ onNavigate?: (path: string) => void;
3
+ }
4
+ export declare function Posts({ onNavigate }: PostsProps): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=Posts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Posts.d.ts","sourceRoot":"","sources":["../../src/views/Posts.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,2CAmO/C"}
@@ -0,0 +1,67 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { Plus, Search, Trash2, SlidersHorizontal, Pencil, ArrowUpDown, ArrowUp, ArrowDown, Loader2, AlertTriangle } from 'lucide-react';
4
+ import { useState, useMemo } from 'react';
5
+ import { toast } from 'sonner';
6
+ import { sortByRelevance, toggleSort } from '../lib/search';
7
+ import { useApiData } from '../lib/useApiData';
8
+ import { cmsApi } from '../lib/api';
9
+ export function Posts({ onNavigate }) {
10
+ const { data, loading, error, refetch } = useApiData('/collections/posts?pageSize=100');
11
+ const [searchQuery, setSearchQuery] = useState('');
12
+ const [filterStatus, setFilterStatus] = useState('all');
13
+ const [filterCategory, setFilterCategory] = useState('all');
14
+ const [selectedPosts, setSelectedPosts] = useState([]);
15
+ const [sortConfig, setSortConfig] = useState(null);
16
+ const posts = data?.docs ?? [];
17
+ const filteredAndSorted = useMemo(() => {
18
+ let results = posts.filter((post) => {
19
+ const matchesSearch = post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
20
+ (post.author ?? '').toLowerCase().includes(searchQuery.toLowerCase());
21
+ const matchesStatus = filterStatus === 'all' || (post.status ?? '').toLowerCase() === filterStatus.toLowerCase();
22
+ const matchesCategory = filterCategory === 'all' || (post.category ?? '').toLowerCase() === filterCategory.toLowerCase();
23
+ return matchesSearch && matchesStatus && matchesCategory;
24
+ });
25
+ if (searchQuery.trim()) {
26
+ results = sortByRelevance(results, searchQuery, (p) => [p.title, p.author ?? '', p.category ?? '']);
27
+ }
28
+ else if (sortConfig) {
29
+ results = [...results].sort((a, b) => {
30
+ const aVal = a[sortConfig.key] ?? '';
31
+ const bVal = b[sortConfig.key] ?? '';
32
+ const cmp = String(aVal).localeCompare(String(bVal));
33
+ return sortConfig.direction === 'asc' ? cmp : -cmp;
34
+ });
35
+ }
36
+ return results;
37
+ }, [posts, searchQuery, filterStatus, filterCategory, sortConfig]);
38
+ const handleSelectAll = (checked) => {
39
+ setSelectedPosts(checked ? filteredAndSorted.map((p) => p.id) : []);
40
+ };
41
+ const handleSelectPost = (id) => {
42
+ setSelectedPosts(prev => prev.includes(id) ? prev.filter(pid => pid !== id) : [...prev, id]);
43
+ };
44
+ const handleBulkDelete = async () => {
45
+ for (const id of selectedPosts) {
46
+ await cmsApi(`/collections/posts/${id}`, { method: 'DELETE' });
47
+ }
48
+ toast.success(`${selectedPosts.length} posts deleted`);
49
+ setSelectedPosts([]);
50
+ refetch();
51
+ };
52
+ const handleDelete = async (id) => {
53
+ await cmsApi(`/collections/posts/${id}`, { method: 'DELETE' });
54
+ toast.success('Post deleted');
55
+ setSelectedPosts(prev => prev.filter(pid => pid !== id));
56
+ refetch();
57
+ };
58
+ function SortHeader({ label, sortKey }) {
59
+ const active = sortConfig?.key === sortKey;
60
+ return (_jsxs("button", { type: "button", onClick: () => setSortConfig(toggleSort(sortConfig, sortKey)), className: "flex items-center gap-1 text-xs font-medium text-gray-700 hover:text-gray-900 transition-colors", children: [label, active ? (sortConfig.direction === 'asc' ? _jsx(ArrowUp, { className: "w-3 h-3" }) : _jsx(ArrowDown, { className: "w-3 h-3" })) : (_jsx(ArrowUpDown, { className: "w-3 h-3 text-gray-400" }))] }));
61
+ }
62
+ if (loading) {
63
+ return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
64
+ }
65
+ return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 h-full flex flex-col", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: error }), _jsx("button", { onClick: refetch, className: "px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors", children: "Retry" })] })), _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between mb-4 gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl sm:text-2xl font-semibold text-gray-900 mb-1", children: "Posts" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " total posts"] })] }), _jsxs("button", { onClick: () => onNavigate?.('/posts/new'), className: "flex items-center justify-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm", children: [_jsx(Plus, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "New Post" }), _jsx("span", { className: "sm:hidden", children: "New" })] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex flex-col gap-3", children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search posts...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-2", children: [_jsxs("select", { value: filterStatus, onChange: (e) => setFilterStatus(e.target.value), className: "flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Status" }), _jsx("option", { value: "published", children: "Published" }), _jsx("option", { value: "draft", children: "Draft" })] }), _jsxs("select", { value: filterCategory, onChange: (e) => setFilterCategory(e.target.value), className: "flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Categories" }), _jsx("option", { value: "technology", children: "Technology" }), _jsx("option", { value: "design", children: "Design" }), _jsx("option", { value: "business", children: "Business" })] }), _jsxs("button", { type: "button", className: "flex items-center justify-center gap-2 px-3 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors", children: [_jsx(SlidersHorizontal, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "More Filters" })] })] })] }) }), selectedPosts.length > 0 && (_jsx("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 mb-4", children: _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-2", children: [_jsxs("span", { className: "text-sm text-blue-900", children: [selectedPosts.length, " post", selectedPosts.length !== 1 ? 's' : '', " selected"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: handleBulkDelete, className: "flex-1 sm:flex-none px-3 py-1.5 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors", children: "Delete" }), _jsx("button", { type: "button", onClick: () => setSelectedPosts([]), className: "flex-1 sm:flex-none px-3 py-1.5 text-sm border border-gray-300 bg-white rounded-lg hover:bg-gray-50 transition-colors", children: "Cancel" })] })] }) })), filteredAndSorted.length === 0 && !error ? (_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-8 text-center flex-1 flex flex-col items-center justify-center", children: [_jsx("p", { className: "text-sm text-gray-500 mb-2", children: "No posts yet" }), _jsx("button", { onClick: () => onNavigate?.('/posts/new'), className: "px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors", children: "Create your first post" })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "hidden md:block bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "w-8 px-3 py-2 text-left", children: _jsx("input", { type: "checkbox", checked: selectedPosts.length === filteredAndSorted.length && filteredAndSorted.length > 0, onChange: (e) => handleSelectAll(e.target.checked), className: "rounded border-gray-300" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Title", sortKey: "title" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Author", sortKey: "author" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Category", sortKey: "category" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Status", sortKey: "status" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Date", sortKey: "date" }) }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((post) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-3 py-2", children: _jsx("input", { type: "checkbox", checked: selectedPosts.includes(post.id), onChange: () => handleSelectPost(post.id), className: "rounded border-gray-300" }) }), _jsx("td", { className: "px-3 py-2", children: _jsx("button", { type: "button", onClick: () => onNavigate?.(`/posts/${post.id}`), className: "font-medium text-gray-900 hover:text-blue-600 text-sm text-left", children: post.title }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: post.author }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: post.category }), _jsx("td", { className: "px-3 py-2", children: _jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${post.status === 'Published' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: post.status }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: post.date }), _jsx("td", { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/posts/${post.id}`), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Edit", children: _jsx(Pencil, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(post.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Delete", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) })] }, post.id))) })] }) }) }), _jsx("div", { className: "md:hidden bg-white rounded-lg border border-gray-200 flex-1 overflow-auto", children: _jsx("div", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((post) => (_jsx("div", { className: "p-3", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("input", { type: "checkbox", checked: selectedPosts.includes(post.id), onChange: () => handleSelectPost(post.id), className: "rounded border-gray-300 mt-1" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/posts/${post.id}`), className: "font-medium text-sm text-gray-900 hover:text-blue-600 block mb-1 text-left", children: post.title }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-gray-600 mb-2", children: [_jsx("span", { children: post.author }), _jsx("span", { children: "\u2022" }), _jsx("span", { children: post.date }), _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${post.status === 'Published' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: post.status })] })] }), _jsx("button", { type: "button", onClick: () => handleDelete(post.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) }, post.id))) }) })] }))] }));
66
+ }
67
+ //# sourceMappingURL=Posts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Posts.js","sourceRoot":"","sources":["../../src/views/Posts.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxI,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAmB,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAQpC,MAAM,UAAU,KAAK,CAAC,EAAE,UAAU,EAAc;IAC9C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAAiC,iCAAiC,CAAC,CAAC;IACxH,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,CAAC;IAChE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,CAAC;IACpE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAiC,IAAI,CAAC,CAAC;IAEnF,MAAM,KAAK,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;IAE/B,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE;YACvC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;gBAChF,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;YACxE,MAAM,aAAa,GAAG,YAAY,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,WAAW,EAAE,CAAC;YACjH,MAAM,eAAe,GAAG,cAAc,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,WAAW,EAAE,CAAC;YACzH,OAAO,aAAa,IAAI,aAAa,IAAI,eAAe,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACvB,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3G,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE;gBAC7C,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrD,OAAO,UAAU,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACrD,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAEnE,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAE,EAAE;QAC3C,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,EAAU,EAAE,EAAE;QACtC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;YAC/B,MAAM,MAAM,CAAC,sBAAsB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,MAAM,gBAAgB,CAAC,CAAC;QACvD,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,EAAE,EAAU,EAAE,EAAE;QACxC,MAAM,MAAM,CAAC,sBAAsB,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC9B,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,SAAS,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAA2C;QAC7E,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,KAAK,OAAO,CAAC;QAC3C,OAAO,CACL,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,EAC7D,SAAS,EAAC,iGAAiG,aAE1G,KAAK,EACL,MAAM,CAAC,CAAC,CAAC,CACR,UAAW,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,CACtG,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,IAAC,SAAS,EAAC,uBAAuB,GAAG,CAClD,IACM,CACV,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CACL,cAAK,SAAS,EAAC,+DAA+D,YAC5E,KAAC,OAAO,IAAC,SAAS,EAAC,oCAAoC,GAAG,GACtD,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,8CAA8C,aAC1D,KAAK,IAAI,CACR,eAAK,SAAS,EAAC,6EAA6E,aAC1F,KAAC,aAAa,IAAC,SAAS,EAAC,+BAA+B,GAAG,EAC3D,eAAM,SAAS,EAAC,6BAA6B,YAAE,KAAK,GAAQ,EAC5D,iBAAQ,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,oGAAoG,sBAAe,IACnJ,CACP,EAED,eAAK,SAAS,EAAC,sEAAsE,aACnF,0BACE,aAAI,SAAS,EAAC,sDAAsD,sBAAW,EAC/E,aAAG,SAAS,EAAC,uBAAuB,aAAE,iBAAiB,CAAC,MAAM,oBAAiB,IAC3E,EACN,kBACE,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,EACzC,SAAS,EAAC,gIAAgI,aAE1I,KAAC,IAAI,IAAC,SAAS,EAAC,SAAS,GAAG,EAC5B,eAAM,SAAS,EAAC,kBAAkB,yBAAgB,EAClD,eAAM,SAAS,EAAC,WAAW,oBAAW,IAC/B,IACL,EAEN,cAAK,SAAS,EAAC,iDAAiD,YAC9D,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAK,SAAS,EAAC,UAAU,aACvB,KAAC,MAAM,IAAC,SAAS,EAAC,gEAAgE,GAAG,EACrF,gBAAO,IAAI,EAAC,MAAM,EAAC,WAAW,EAAC,iBAAiB,EAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,qHAAqH,GAAG,IACpP,EACN,eAAK,SAAS,EAAC,iCAAiC,aAC9C,kBAAQ,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,gHAAgH,aACvM,iBAAQ,KAAK,EAAC,KAAK,2BAAoB,EACvC,iBAAQ,KAAK,EAAC,WAAW,0BAAmB,EAC5C,iBAAQ,KAAK,EAAC,OAAO,sBAAe,IAC7B,EACT,kBAAQ,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,SAAS,EAAC,gHAAgH,aAC3M,iBAAQ,KAAK,EAAC,KAAK,+BAAwB,EAC3C,iBAAQ,KAAK,EAAC,YAAY,2BAAoB,EAC9C,iBAAQ,KAAK,EAAC,QAAQ,uBAAgB,EACtC,iBAAQ,KAAK,EAAC,UAAU,yBAAkB,IACnC,EACT,kBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,+HAA+H,aAC7J,KAAC,iBAAiB,IAAC,SAAS,EAAC,SAAS,GAAG,EACzC,eAAM,SAAS,EAAC,kBAAkB,6BAAoB,IAC/C,IACL,IACF,GACF,EAEL,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAC3B,cAAK,SAAS,EAAC,uDAAuD,YACpE,eAAK,SAAS,EAAC,iEAAiE,aAC9E,gBAAM,SAAS,EAAC,uBAAuB,aAAE,aAAa,CAAC,MAAM,WAAO,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAC1H,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAC,6GAA6G,uBAAgB,EACxL,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,uHAAuH,uBAAgB,IACxM,IACF,GACF,CACP,EAEA,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAC1C,eAAK,SAAS,EAAC,6GAA6G,aAC1H,YAAG,SAAS,EAAC,4BAA4B,6BAAiB,EAC1D,iBAAQ,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,SAAS,EAAC,yFAAyF,uCAAgC,IAClL,CACP,CAAC,CAAC,CAAC,CACF,8BACE,cAAK,SAAS,EAAC,mFAAmF,YAChG,cAAK,SAAS,EAAC,wBAAwB,YACrC,iBAAO,SAAS,EAAC,QAAQ,aACvB,gBAAO,SAAS,EAAC,kDAAkD,YACjE,yBACE,aAAI,SAAS,EAAC,yBAAyB,YACrC,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,aAAa,CAAC,MAAM,KAAK,iBAAiB,CAAC,MAAM,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,SAAS,EAAC,yBAAyB,GAAG,GAC1M,EACL,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,OAAO,EAAC,OAAO,EAAC,OAAO,GAAG,GAAK,EACrF,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,QAAQ,GAAG,GAAK,EACvF,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,UAAU,EAAC,OAAO,EAAC,UAAU,GAAG,GAAK,EAC3F,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,QAAQ,GAAG,GAAK,EACvF,aAAI,SAAS,EAAC,qBAAqB,YAAC,KAAC,UAAU,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,GAAG,GAAK,EACnF,aAAI,SAAS,EAAC,uDAAuD,wBAAa,IAC/E,GACC,EACR,gBAAO,SAAS,EAAC,0BAA0B,YACxC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CACpC,cAAkB,SAAS,EAAC,oCAAoC,aAC9D,aAAI,SAAS,EAAC,WAAW,YACvB,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,yBAAyB,GAAG,GAC/I,EACL,aAAI,SAAS,EAAC,WAAW,YACvB,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,iEAAiE,YAAE,IAAI,CAAC,KAAK,GAAU,GACtK,EACL,aAAI,SAAS,EAAC,iCAAiC,YAAE,IAAI,CAAC,MAAM,GAAM,EAClE,aAAI,SAAS,EAAC,iCAAiC,YAAE,IAAI,CAAC,QAAQ,GAAM,EACpE,aAAI,SAAS,EAAC,WAAW,YACvB,eAAM,SAAS,EAAE,yEAAyE,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,2BAA2B,EAAE,YAAG,IAAI,CAAC,MAAM,GAAQ,GACxM,EACL,aAAI,SAAS,EAAC,iCAAiC,YAAE,IAAI,CAAC,IAAI,GAAM,EAChE,aAAI,SAAS,EAAC,WAAW,YACvB,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,mDAAmD,EAAC,KAAK,EAAC,MAAM,YAChJ,KAAC,MAAM,IAAC,SAAS,EAAC,uBAAuB,GAAG,GACrC,EACT,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,mDAAmD,EAAC,KAAK,EAAC,QAAQ,YACtI,KAAC,MAAM,IAAC,SAAS,EAAC,sBAAsB,GAAG,GACpC,IACL,GACH,KAtBE,IAAI,CAAC,EAAE,CAuBX,CACN,CAAC,GACI,IACF,GACJ,GACF,EAEN,cAAK,SAAS,EAAC,2EAA2E,YACxF,cAAK,SAAS,EAAC,0BAA0B,YACtC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CACpC,cAAmB,SAAS,EAAC,KAAK,YAChC,eAAK,SAAS,EAAC,wBAAwB,aACrC,gBAAO,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,8BAA8B,GAAG,EACvJ,eAAK,SAAS,EAAC,gBAAgB,aAC7B,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,EAAC,4EAA4E,YAAE,IAAI,CAAC,KAAK,GAAU,EACpL,eAAK,SAAS,EAAC,8DAA8D,aAC3E,yBAAO,IAAI,CAAC,MAAM,GAAQ,EAC1B,oCAAc,EACd,yBAAO,IAAI,CAAC,IAAI,GAAQ,EACxB,eAAM,SAAS,EAAE,gDAAgD,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,2BAA2B,EAAE,YAAG,IAAI,CAAC,MAAM,GAAQ,IAC9K,IACF,EACN,iBAAQ,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS,EAAC,mDAAmD,YACvH,KAAC,MAAM,IAAC,SAAS,EAAC,sBAAsB,GAAG,GACpC,IACL,IAfE,IAAI,CAAC,EAAE,CAgBX,CACP,CAAC,GACE,GACF,IACL,CACJ,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface RedirectsProps {
2
+ onNavigate?: (path: string) => void;
3
+ }
4
+ export declare function Redirects({ onNavigate }: RedirectsProps): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=Redirects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Redirects.d.ts","sourceRoot":"","sources":["../../src/views/Redirects.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,cAAc,2CAoRvD"}
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as Dialog from '@radix-ui/react-dialog';
4
+ import { Pencil, Plus, Trash2, Search, ArrowUpDown, ArrowUp, ArrowDown, ArrowRightLeft, Loader2, AlertTriangle } from 'lucide-react';
5
+ import { useState, useMemo } from 'react';
6
+ import { toast } from 'sonner';
7
+ import { sortByRelevance, toggleSort } from '../lib/search';
8
+ import { useApiData } from '../lib/useApiData';
9
+ import { cmsApi } from '../lib/api';
10
+ export function Redirects({ onNavigate }) {
11
+ const { data, loading, error, refetch } = useApiData('/redirects');
12
+ const [showAddDialog, setShowAddDialog] = useState(false);
13
+ const [newRedirect, setNewRedirect] = useState({ source: '', destination: '', type: '301' });
14
+ const [searchQuery, setSearchQuery] = useState('');
15
+ const [filterType, setFilterType] = useState('all');
16
+ const [sortConfig, setSortConfig] = useState(null);
17
+ const redirects = data ?? [];
18
+ const filteredAndSorted = useMemo(() => {
19
+ let results = redirects.filter((r) => {
20
+ const matchesSearch = r.from.toLowerCase().includes(searchQuery.toLowerCase()) ||
21
+ r.to.toLowerCase().includes(searchQuery.toLowerCase());
22
+ const matchesType = filterType === 'all' || r.type === filterType;
23
+ return matchesSearch && matchesType;
24
+ });
25
+ if (searchQuery.trim()) {
26
+ results = sortByRelevance(results, searchQuery, (r) => [r.from, r.to]);
27
+ }
28
+ else if (sortConfig) {
29
+ results = [...results].sort((a, b) => {
30
+ let cmp;
31
+ if (sortConfig.key === 'hits') {
32
+ cmp = a.hits - b.hits;
33
+ }
34
+ else if (sortConfig.key === 'active') {
35
+ cmp = Number(a.active) - Number(b.active);
36
+ }
37
+ else {
38
+ cmp = String(a[sortConfig.key]).localeCompare(String(b[sortConfig.key]));
39
+ }
40
+ return sortConfig.direction === 'asc' ? cmp : -cmp;
41
+ });
42
+ }
43
+ return results;
44
+ }, [redirects, searchQuery, filterType, sortConfig]);
45
+ const handleSubmit = async (e) => {
46
+ e.preventDefault();
47
+ const res = await cmsApi('/redirects', {
48
+ method: 'POST',
49
+ body: JSON.stringify({ from: newRedirect.source, to: newRedirect.destination, type: newRedirect.type }),
50
+ });
51
+ if (res.error) {
52
+ toast.error(res.error);
53
+ }
54
+ else {
55
+ toast.success('Redirect added');
56
+ refetch();
57
+ }
58
+ setShowAddDialog(false);
59
+ };
60
+ const handleDelete = async (id) => {
61
+ const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' });
62
+ if (res.error) {
63
+ toast.error(res.error);
64
+ }
65
+ else {
66
+ toast.success('Redirect deleted');
67
+ refetch();
68
+ }
69
+ };
70
+ function SortHeader({ label, sortKey }) {
71
+ const active = sortConfig?.key === sortKey;
72
+ return (_jsxs("button", { type: "button", onClick: () => setSortConfig(toggleSort(sortConfig, sortKey)), className: "flex items-center gap-1 text-xs font-medium text-gray-700 hover:text-gray-900 transition-colors", children: [label, active ? (sortConfig.direction === 'asc' ? _jsx(ArrowUp, { className: "w-3 h-3" }) : _jsx(ArrowDown, { className: "w-3 h-3" })) : (_jsx(ArrowUpDown, { className: "w-3 h-3 text-gray-400" }))] }));
73
+ }
74
+ if (loading) {
75
+ return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
76
+ }
77
+ return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: error }), _jsx("button", { onClick: refetch, className: "px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors", children: "Retry" })] })), _jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "mb-1 text-xl font-semibold text-gray-900 sm:text-2xl", children: "Redirects" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " total redirects"] })] }), _jsxs("button", { type: "button", onClick: () => setShowAddDialog(true), className: "flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: [_jsx(Plus, { className: "h-4 w-4" }), "Add Redirect"] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search by source or destination URL...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("select", { value: filterType, onChange: (e) => setFilterType(e.target.value), className: "px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Types" }), _jsx("option", { value: "301", children: "301 (Permanent)" }), _jsx("option", { value: "302", children: "302 (Temporary)" })] })] }) }), filteredAndSorted.length === 0 && !loading ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [_jsx("div", { className: "w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-4", children: _jsx(ArrowRightLeft, { className: "w-6 h-6 text-gray-400" }) }), _jsx("h3", { className: "text-sm font-medium text-gray-900 mb-1", children: "No redirects yet" }), _jsx("p", { className: "text-sm text-gray-500", children: "Add your first redirect to get started." })] })) : (_jsx("div", { className: "rounded-lg border border-gray-200 bg-white", children: _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "border-b border-gray-200 bg-gray-50", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Source URL", sortKey: "from" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Destination URL", sortKey: "to" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Type", sortKey: "type" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Hits", sortKey: "hits" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Status", sortKey: "active" }) }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((redirect) => (_jsxs("tr", { className: "transition-colors hover:bg-gray-50", children: [_jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: redirect.from }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: redirect.to }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${redirect.type === '301' ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800'}`, children: redirect.type }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: redirect.hits.toLocaleString() }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${redirect.active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: redirect.active ? 'Active' : 'Inactive' }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/redirects/${redirect.id}/edit`), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": "Edit redirect", children: _jsx(Pencil, { className: "h-4 w-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(redirect.id), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": "Delete redirect", children: _jsx(Trash2, { className: "h-4 w-4 text-red-600" }) })] }) })] }, redirect.id))) })] }) }) })), _jsx(Dialog.Root, { open: showAddDialog, onOpenChange: setShowAddDialog, children: _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }), _jsxs(Dialog.Content, { className: "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg", children: [_jsx(Dialog.Title, { className: "mb-4 text-lg font-semibold text-gray-900", children: "Add Redirect" }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Source URL" }), _jsx("input", { type: "text", value: newRedirect.source, onChange: (e) => setNewRedirect({ ...newRedirect, source: e.target.value }), placeholder: "/old-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Destination URL" }), _jsx("input", { type: "text", value: newRedirect.destination, onChange: (e) => setNewRedirect({ ...newRedirect, destination: e.target.value }), placeholder: "/new-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Redirect Type" }), _jsxs("select", { value: newRedirect.type, onChange: (e) => setNewRedirect({ ...newRedirect, type: e.target.value }), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "301", children: "301 (Permanent)" }), _jsx("option", { value: "302", children: "302 (Temporary)" })] })] }), _jsxs("div", { className: "flex items-center justify-end gap-3 pt-4", children: [_jsx(Dialog.Close, { asChild: true, children: _jsx("button", { type: "button", className: "rounded-lg border border-gray-300 px-4 py-2 text-sm transition-colors hover:bg-gray-50", children: "Cancel" }) }), _jsx("button", { type: "submit", className: "rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: "Add Redirect" })] })] })] })] }) })] }));
78
+ }
79
+ //# sourceMappingURL=Redirects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Redirects.js","sourceRoot":"","sources":["../../src/views/Redirects.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface SEOProps {
2
+ onNavigate?: (path: string) => void;
3
+ initialTab?: string;
4
+ }
5
+ export declare function SEO({ onNavigate, initialTab }: SEOProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=SEO.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SEO.d.ts","sourceRoot":"","sources":["../../src/views/SEO.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,GAAG,CAAC,EAAE,UAAU,EAAE,UAAoB,EAAE,EAAE,QAAQ,2CAsbjE"}
@@ -0,0 +1,120 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as Tabs from '@radix-ui/react-tabs';
4
+ import { Search, Globe, FileCode2, BarChart3, AlertTriangle, CheckCircle2, XCircle, ArrowUpRight, RefreshCw, BookOpen, Link2, Bot, Plus, Pencil, Trash2, ExternalLink, ArrowRightLeft, Copy, ShieldCheck, Loader2, } from 'lucide-react';
5
+ import { useState } from 'react';
6
+ import { toast } from 'sonner';
7
+ import * as Dialog from '@radix-ui/react-dialog';
8
+ import { useApiData } from '../lib/useApiData';
9
+ import { cmsApi } from '../lib/api';
10
+ export function SEO({ onNavigate, initialTab = 'pages' }) {
11
+ const { data: seoData, loading: seoLoading, error: seoError, refetch: seoRefetch } = useApiData('/seo/pages');
12
+ const { data: redirectsData, loading: redirectsLoading, error: redirectsError, refetch: redirectsRefetch } = useApiData('/redirects');
13
+ const { data: linkHealthData, loading: linkHealthLoading } = useApiData('/seo/link-health');
14
+ const [activeTab, setActiveTab] = useState(initialTab);
15
+ const [searchQuery, setSearchQuery] = useState('');
16
+ const [filterScore, setFilterScore] = useState('all');
17
+ const [scanning, setScanning] = useState(false);
18
+ const [showAddRedirect, setShowAddRedirect] = useState(false);
19
+ const [newRedirect, setNewRedirect] = useState({ source: '', destination: '', type: '301' });
20
+ const [redirectSearch, setRedirectSearch] = useState('');
21
+ const seoPages = seoData ?? [];
22
+ const redirects = redirectsData ?? [];
23
+ const linkHealth = linkHealthData ?? [];
24
+ const handleTabChange = (tab) => {
25
+ setActiveTab(tab);
26
+ const path = tab === 'pages' ? '/seo' : `/seo/${tab}`;
27
+ onNavigate?.(path);
28
+ };
29
+ // --- Pages tab data ---
30
+ const filtered = seoPages
31
+ .filter((page) => {
32
+ const matchesSearch = page.url.toLowerCase().includes(searchQuery.toLowerCase()) || page.title.toLowerCase().includes(searchQuery.toLowerCase());
33
+ const matchesScore = filterScore === 'all' || (filterScore === 'good' && page.score >= 80) || (filterScore === 'warning' && page.score >= 50 && page.score < 80) || (filterScore === 'critical' && page.score < 50);
34
+ return matchesSearch && matchesScore;
35
+ })
36
+ .sort((a, b) => !searchQuery ? b.issues - a.issues : 0);
37
+ const totalIssues = seoPages.reduce((sum, p) => sum + p.issues, 0);
38
+ const avgScore = seoPages.length > 0 ? Math.round(seoPages.reduce((sum, p) => sum + p.score, 0) / seoPages.length) : 0;
39
+ const missingMeta = seoPages.filter((p) => !p.metaTitle || !p.metaDescription).length;
40
+ const missingSchema = seoPages.filter((p) => !p.schemaType).length;
41
+ // --- Canonical data ---
42
+ const missingCanonical = seoPages.filter((p) => !p.canonical);
43
+ const allCanonicals = seoPages.filter((p) => p.canonical);
44
+ const canonicalDomains = [...new Set(allCanonicals.map((p) => { try {
45
+ return new URL(p.canonical).hostname;
46
+ }
47
+ catch {
48
+ return '';
49
+ } }).filter(Boolean))];
50
+ // --- Redirects data ---
51
+ const filteredRedirects = redirects.filter((r) => r.from.toLowerCase().includes(redirectSearch.toLowerCase()) ||
52
+ r.to.toLowerCase().includes(redirectSearch.toLowerCase()));
53
+ const handleScan = async () => {
54
+ setScanning(true);
55
+ try {
56
+ const res = await cmsApi('/seo/scan', { method: 'POST' });
57
+ if (res.error) {
58
+ toast.error(res.error);
59
+ }
60
+ else {
61
+ const d = res.data;
62
+ toast.success(`SEO scan complete — ${d.totalProblems} issues found across ${d.pagesWithIssues} of ${d.total} pages`);
63
+ seoRefetch();
64
+ }
65
+ }
66
+ catch {
67
+ toast.error('SEO scan failed');
68
+ }
69
+ finally {
70
+ setScanning(false);
71
+ }
72
+ };
73
+ const handleAddRedirect = async (e) => {
74
+ e.preventDefault();
75
+ const res = await cmsApi('/redirects', {
76
+ method: 'POST',
77
+ body: JSON.stringify({ from: newRedirect.source, to: newRedirect.destination, type: newRedirect.type }),
78
+ });
79
+ if (res.error) {
80
+ toast.error(res.error);
81
+ }
82
+ else {
83
+ toast.success('Redirect added');
84
+ redirectsRefetch();
85
+ }
86
+ setShowAddRedirect(false);
87
+ setNewRedirect({ source: '', destination: '', type: '301' });
88
+ };
89
+ const handleDeleteRedirect = async (id) => {
90
+ const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' });
91
+ if (res.error) {
92
+ toast.error(res.error);
93
+ }
94
+ else {
95
+ toast.success('Redirect deleted');
96
+ redirectsRefetch();
97
+ }
98
+ };
99
+ function scoreBadge(score) {
100
+ if (score >= 80)
101
+ return 'bg-green-100 text-green-800';
102
+ if (score >= 50)
103
+ return 'bg-yellow-100 text-yellow-800';
104
+ return 'bg-red-100 text-red-800';
105
+ }
106
+ function scoreIcon(score) {
107
+ if (score >= 80)
108
+ return _jsx(CheckCircle2, { className: "w-4 h-4 text-green-600" });
109
+ if (score >= 50)
110
+ return _jsx(AlertTriangle, { className: "w-4 h-4 text-yellow-600" });
111
+ return _jsx(XCircle, { className: "w-4 h-4 text-red-600" });
112
+ }
113
+ const tabClass = "px-4 py-2 text-sm font-medium text-gray-600 transition-colors hover:text-gray-900 data-[state=active]:border-b-2 data-[state=active]:border-blue-600 data-[state=active]:text-blue-600 shrink-0";
114
+ const isLoading = seoLoading || redirectsLoading || linkHealthLoading;
115
+ if (isLoading) {
116
+ return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
117
+ }
118
+ return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 h-full flex flex-col", children: [(seoError || redirectsError) && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: seoError || redirectsError }), _jsx("button", { onClick: () => { seoRefetch(); redirectsRefetch(); }, className: "px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors", children: "Retry" })] })), _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between mb-4 gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl sm:text-2xl font-semibold text-gray-900 mb-1", children: "SEO & Redirects" }), _jsx("p", { className: "text-sm text-gray-600", children: "Search optimization, redirects, canonicalization, and link health" })] }), _jsxs("button", { onClick: handleScan, disabled: scanning, className: "flex items-center justify-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm disabled:opacity-60", children: [_jsx(RefreshCw, { className: `w-4 h-4 ${scanning ? 'animate-spin' : ''}` }), scanning ? 'Scanning...' : 'Run SEO Scan'] })] }), _jsxs(Tabs.Root, { value: activeTab, onValueChange: handleTabChange, children: [_jsxs(Tabs.List, { className: "mb-4 flex gap-1 border-b border-gray-200 overflow-x-auto", children: [_jsx(Tabs.Trigger, { value: "pages", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(BarChart3, { className: "w-4 h-4" }), "Pages"] }) }), _jsx(Tabs.Trigger, { value: "redirects", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(ArrowRightLeft, { className: "w-4 h-4" }), "Redirects"] }) }), _jsx(Tabs.Trigger, { value: "canonicals", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Copy, { className: "w-4 h-4" }), "Canonicalization"] }) }), _jsx(Tabs.Trigger, { value: "links", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Link2, { className: "w-4 h-4" }), "Link Health"] }) })] }), _jsxs(Tabs.Content, { value: "pages", className: "flex flex-col flex-1 min-h-0", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 mb-4", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(BarChart3, { className: "w-4 h-4 text-blue-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Avg SEO Score" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: avgScore }), _jsx("div", { className: `text-xs mt-1 ${avgScore >= 80 ? 'text-green-600' : avgScore >= 50 ? 'text-yellow-600' : 'text-red-600'}`, children: avgScore >= 80 ? 'Good' : avgScore >= 50 ? 'Needs improvement' : 'Critical' })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(AlertTriangle, { className: "w-4 h-4 text-yellow-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Total Issues" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: totalIssues }), _jsxs("div", { className: "text-xs text-gray-500 mt-1", children: ["Across ", seoPages.filter((p) => p.issues > 0).length, " pages"] })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(FileCode2, { className: "w-4 h-4 text-purple-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Missing Meta" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: missingMeta }), _jsx("div", { className: "text-xs text-gray-500 mt-1", children: "Title or description" })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(Globe, { className: "w-4 h-4 text-green-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Missing Schema" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: missingSchema }), _jsx("div", { className: "text-xs text-gray-500 mt-1", children: "No Schema.org markup" })] })] }), _jsx("div", { className: "bg-linear-to-r from-indigo-50 to-purple-50 border border-indigo-200 rounded-lg p-4 mb-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Bot, { className: "w-5 h-5 text-indigo-600 mt-0.5 shrink-0" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-sm font-semibold text-indigo-900 mb-1", children: "AI SEO Recommendations" }), _jsxs("p", { className: "text-sm text-indigo-700 mb-2", children: [missingMeta, " pages missing meta descriptions. ", missingCanonical.length, " pages without canonical URLs. AI can auto-generate these from page content."] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: () => onNavigate?.('/settings'), className: "px-3 py-1.5 text-xs bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors", children: "Configure AI" }), _jsx("button", { className: "px-3 py-1.5 text-xs border border-indigo-300 text-indigo-700 rounded-lg hover:bg-indigo-50 transition-colors", children: "Auto-fix All" })] })] })] }) }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search pages by URL or title...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("select", { value: filterScore, onChange: (e) => setFilterScore(e.target.value), className: "px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Scores" }), _jsx("option", { value: "good", children: "Good (80+)" }), _jsx("option", { value: "warning", children: "Needs Work (50-79)" }), _jsx("option", { value: "critical", children: "Critical (<50)" })] })] }) }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Page" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Score" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Readability" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Schema" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Meta" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Issues" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filtered.map((page) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsxs("td", { className: "px-4 py-3", children: [_jsx("div", { className: "text-sm font-medium text-gray-900", children: page.title }), _jsx("div", { className: "text-xs text-gray-500", children: page.url })] }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [scoreIcon(page.score), _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${scoreBadge(page.score)}`, children: page.score })] }) }), _jsx("td", { className: "px-4 py-3", children: page.readability > 0 ? _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(BookOpen, { className: "w-3.5 h-3.5 text-gray-400" }), _jsx("span", { className: `text-sm ${page.readability >= 80 ? 'text-green-700' : page.readability >= 60 ? 'text-yellow-700' : 'text-red-700'}`, children: page.readability })] }) : _jsx("span", { className: "text-xs text-gray-400", children: "\u2014" }) }), _jsx("td", { className: "px-4 py-3", children: page.schemaType ? _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800", children: page.schemaType }) : _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800", children: "Missing" }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: `text-xs ${page.metaTitle ? 'text-green-700' : 'text-red-600'}`, children: page.metaTitle ? '✓ Title' : '✗ Title' }), _jsx("span", { className: `text-xs ${page.metaDescription ? 'text-green-700' : 'text-red-600'}`, children: page.metaDescription ? '✓ Desc' : '✗ Desc' })] }) }), _jsx("td", { className: "px-4 py-3", children: page.issues > 0 ? _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800", children: page.issues }) : _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: "\u2713" }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: () => onNavigate?.(`/pages/${page.id}`), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Edit", children: _jsx(ArrowUpRight, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "AI analyze", children: _jsx(Bot, { className: "w-4 h-4 text-indigo-600" }) })] }) })] }, page.id))) })] }) }) })] }), _jsxs(Tabs.Content, { value: "redirects", className: "flex flex-col flex-1 min-h-0", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 mb-4", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Total Redirects" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: redirects.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Active" }), _jsx("div", { className: "text-2xl font-semibold text-green-600", children: redirects.filter((r) => r.active).length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Total Hits" }), _jsx("div", { className: "text-2xl font-semibold text-blue-600", children: redirects.reduce((s, r) => s + r.hits, 0).toLocaleString() })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "301 Permanent" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: redirects.filter((r) => r.type === '301').length })] })] }), _jsxs("div", { className: "flex items-center gap-3 mb-4", children: [_jsxs("div", { className: "relative flex-1 max-w-md", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search redirects...", value: redirectSearch, onChange: (e) => setRedirectSearch(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("button", { onClick: () => setShowAddRedirect(true), className: "flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm shrink-0", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Redirect"] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Source" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Destination" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Type" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Hits" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredRedirects.map((r) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: r.from }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: r.to }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${r.type === '301' ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800'}`, children: r.type }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: r.hits.toLocaleString() }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${r.active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: r.active ? 'Active' : 'Inactive' }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Pencil, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { onClick: () => handleDeleteRedirect(r.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) })] }, r.id))) })] }) }) }), _jsx(Dialog.Root, { open: showAddRedirect, onOpenChange: setShowAddRedirect, children: _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }), _jsxs(Dialog.Content, { className: "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg", children: [_jsx(Dialog.Title, { className: "mb-4 text-lg font-semibold text-gray-900", children: "Add Redirect" }), _jsxs("form", { onSubmit: handleAddRedirect, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Source URL" }), _jsx("input", { type: "text", value: newRedirect.source, onChange: (e) => setNewRedirect({ ...newRedirect, source: e.target.value }), placeholder: "/old-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Destination URL" }), _jsx("input", { type: "text", value: newRedirect.destination, onChange: (e) => setNewRedirect({ ...newRedirect, destination: e.target.value }), placeholder: "/new-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Type" }), _jsxs("select", { value: newRedirect.type, onChange: (e) => setNewRedirect({ ...newRedirect, type: e.target.value }), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "301", children: "301 (Permanent)" }), _jsx("option", { value: "302", children: "302 (Temporary)" })] })] }), _jsxs("div", { className: "flex justify-end gap-3 pt-4", children: [_jsx(Dialog.Close, { asChild: true, children: _jsx("button", { type: "button", className: "rounded-lg border border-gray-300 px-4 py-2 text-sm hover:bg-gray-50", children: "Cancel" }) }), _jsx("button", { type: "submit", className: "rounded-lg bg-blue-600 px-4 py-2 text-sm text-white hover:bg-blue-700", children: "Add Redirect" })] })] })] })] }) })] }), _jsxs(Tabs.Content, { value: "canonicals", className: "flex flex-col flex-1 min-h-0 space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(ShieldCheck, { className: "w-4 h-4 text-green-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "With Canonical" })] }), _jsx("div", { className: "text-2xl font-semibold text-green-700", children: allCanonicals.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(AlertTriangle, { className: "w-4 h-4 text-red-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Missing Canonical" })] }), _jsx("div", { className: "text-2xl font-semibold text-red-700", children: missingCanonical.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(Globe, { className: "w-4 h-4 text-blue-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Canonical Domains" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: canonicalDomains.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(CheckCircle2, { className: "w-4 h-4 text-green-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Self-Referencing" })] }), _jsx("div", { className: "text-2xl font-semibold text-green-700", children: allCanonicals.length }), _jsx("div", { className: "text-xs text-gray-500 mt-1", children: "Correct pattern" })] })] }), missingCanonical.length > 0 && (_jsx("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-yellow-600 mt-0.5 shrink-0" }), _jsxs("div", { className: "flex-1", children: [_jsxs("h3", { className: "text-sm font-semibold text-yellow-900 mb-1", children: [missingCanonical.length, " page", missingCanonical.length !== 1 ? 's' : '', " missing canonical URLs"] }), _jsx("p", { className: "text-sm text-yellow-700 mb-2", children: "Without canonical tags, search engines may index duplicate versions of these pages, diluting your ranking signals." }), _jsx("div", { className: "flex flex-wrap gap-2", children: missingCanonical.map((p) => (_jsxs("button", { onClick: () => onNavigate?.(`/pages/${p.id}`), className: "px-2.5 py-1 text-xs bg-yellow-100 text-yellow-900 rounded-lg hover:bg-yellow-200 transition-colors", children: [p.title, " (", p.url, ")"] }, p.id))) })] })] }) })), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Page" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "URL" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Canonical URL" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: seoPages.map((page) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-4 py-3 text-sm font-medium text-gray-900", children: page.title }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "text-xs bg-gray-100 px-2 py-1 rounded text-gray-700", children: page.url }) }), _jsx("td", { className: "px-4 py-3", children: page.canonical ? _jsx("code", { className: "text-xs bg-gray-100 px-2 py-1 rounded text-gray-700 truncate max-w-[200px] block", children: page.canonical }) : _jsx("span", { className: "text-xs text-red-600 font-medium", children: "Not set" }) }), _jsx("td", { className: "px-4 py-3", children: page.canonical ? _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: "\u2713 Set" }) : _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800", children: "Missing" }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("button", { onClick: () => onNavigate?.(`/pages/${page.id}`), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Edit", children: _jsx(Pencil, { className: "w-4 h-4 text-gray-600" }) }) })] }, page.id))) })] }) }) })] }), _jsxs(Tabs.Content, { value: "links", className: "flex flex-col flex-1 min-h-0 space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Broken Links" }), _jsx("div", { className: "text-2xl font-semibold text-red-600", children: linkHealth.filter((l) => l.status === 404).length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Redirect Chains" }), _jsx("div", { className: "text-2xl font-semibold text-yellow-600", children: linkHealth.filter((l) => l.status === 301).length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Internal Issues" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: linkHealth.filter((l) => l.type === 'internal').length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "External Issues" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: linkHealth.filter((l) => l.type === 'external').length })] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Found On" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Broken URL" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Type" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Last Checked" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: linkHealth.map((link) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "text-xs bg-gray-100 px-2 py-1 rounded text-gray-700", children: link.page }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "text-xs bg-red-50 px-2 py-1 rounded text-red-800 truncate max-w-[200px] block", children: link.url }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${link.status === 404 ? 'bg-red-100 text-red-800' : 'bg-yellow-100 text-yellow-800'}`, children: link.status }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${link.type === 'internal' ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 text-gray-800'}`, children: link.type }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: link.lastChecked }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Create redirect", children: _jsx(ArrowRightLeft, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Open URL", children: _jsx(ExternalLink, { className: "w-4 h-4 text-gray-600" }) })] }) })] }, link.id))) })] }) }) })] })] })] }));
119
+ }
120
+ //# sourceMappingURL=SEO.js.map