@locusai/web 0.1.7 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/next.config.js +15 -2
  3. package/package.json +26 -3
  4. package/src/app/(auth)/invite/page.tsx +109 -0
  5. package/src/app/(auth)/layout.tsx +19 -0
  6. package/src/app/(auth)/login/page.tsx +65 -0
  7. package/src/app/(auth)/onboarding/workspace/page.tsx +46 -0
  8. package/src/app/(auth)/register/page.tsx +165 -0
  9. package/src/app/(dashboard)/activity/page.tsx +7 -0
  10. package/src/app/(dashboard)/backlog/page.tsx +195 -0
  11. package/src/app/(dashboard)/board/page.tsx +141 -0
  12. package/src/app/(dashboard)/layout.tsx +32 -0
  13. package/src/app/(dashboard)/page.tsx +14 -0
  14. package/src/app/(dashboard)/settings/page.tsx +161 -0
  15. package/src/app/(dashboard)/settings/team/page.tsx +75 -0
  16. package/src/app/globals.css +259 -0
  17. package/src/app/layout.tsx +10 -20
  18. package/src/app/providers.tsx +26 -3
  19. package/src/components/AuthLayoutUI.tsx +53 -0
  20. package/src/components/BoardFilter.tsx +75 -74
  21. package/src/components/CreateModal/CreateModal.tsx +142 -0
  22. package/src/components/CreateModal/index.ts +1 -0
  23. package/src/components/Editor.tsx +279 -0
  24. package/src/components/Header.tsx +99 -12
  25. package/src/components/PageLayout.tsx +69 -0
  26. package/src/components/PropertyItem.tsx +55 -9
  27. package/src/components/Sidebar.tsx +280 -36
  28. package/src/components/SprintCreateModal.tsx +84 -0
  29. package/src/components/TaskCard.tsx +196 -78
  30. package/src/components/TaskCreateModal.tsx +181 -178
  31. package/src/components/TaskPanel.tsx +140 -692
  32. package/src/components/WorkspaceCreateModal.tsx +97 -0
  33. package/src/components/WorkspaceProtected.tsx +91 -0
  34. package/src/components/auth/InviteSteps.tsx +220 -0
  35. package/src/components/auth/LoginSteps.tsx +86 -0
  36. package/src/components/auth/RegisterSteps.tsx +371 -0
  37. package/src/components/auth/index.ts +3 -0
  38. package/src/components/backlog/BacklogList.tsx +92 -0
  39. package/src/components/backlog/BacklogSection.tsx +137 -0
  40. package/src/components/backlog/CompletedSprintItem.tsx +95 -0
  41. package/src/components/backlog/CompletedSprintsSection.tsx +77 -0
  42. package/src/components/backlog/SprintSection.tsx +155 -0
  43. package/src/components/backlog/constants.ts +26 -0
  44. package/src/components/board/BoardColumn.tsx +97 -0
  45. package/src/components/board/BoardContent.tsx +84 -0
  46. package/src/components/board/BoardEmptyState.tsx +82 -0
  47. package/src/components/board/BoardHeader.tsx +47 -0
  48. package/src/components/board/SprintMindmap.tsx +65 -0
  49. package/src/components/board/constants.ts +40 -0
  50. package/src/components/board/index.ts +5 -0
  51. package/src/components/common/ErrorState.tsx +124 -0
  52. package/src/components/common/LoadingState.tsx +83 -0
  53. package/src/components/common/index.ts +40 -0
  54. package/src/components/dashboard/ActivityFeed.tsx +77 -0
  55. package/src/components/dashboard/ActivityItem.tsx +207 -0
  56. package/src/components/dashboard/QuickActions.tsx +50 -0
  57. package/src/components/dashboard/StatCard.tsx +79 -0
  58. package/src/components/dnd/index.tsx +51 -0
  59. package/src/components/docs/DocsEditorArea.tsx +87 -0
  60. package/src/components/docs/DocsHeaderActions.tsx +121 -0
  61. package/src/components/docs/DocsSidebar.tsx +351 -0
  62. package/src/components/index.ts +7 -0
  63. package/src/components/onboarding/StepProgress.tsx +21 -0
  64. package/src/components/onboarding/index.ts +1 -0
  65. package/src/components/settings/ApiKeyConfirmationModal.tsx +81 -0
  66. package/src/components/settings/ApiKeyCreatedModal.tsx +96 -0
  67. package/src/components/settings/ApiKeysList.tsx +143 -0
  68. package/src/components/settings/ApiKeysSettings.tsx +144 -0
  69. package/src/components/settings/InviteMemberModal.tsx +106 -0
  70. package/src/components/settings/ProjectSetupGuide.tsx +147 -0
  71. package/src/components/settings/SettingItem.tsx +32 -0
  72. package/src/components/settings/SettingSection.tsx +50 -0
  73. package/src/components/settings/TeamInvitationsList.tsx +90 -0
  74. package/src/components/settings/TeamMembersList.tsx +95 -0
  75. package/src/components/settings/index.ts +8 -0
  76. package/src/components/task-panel/TaskActivity.tsx +127 -0
  77. package/src/components/task-panel/TaskChecklist.tsx +142 -0
  78. package/src/components/task-panel/TaskDescription.tsx +201 -0
  79. package/src/components/task-panel/TaskDocs.tsx +137 -0
  80. package/src/components/task-panel/TaskHeader.tsx +125 -0
  81. package/src/components/task-panel/TaskProperties.tsx +111 -0
  82. package/src/components/task-panel/index.ts +12 -0
  83. package/src/components/typography/EmptyStateText.tsx +59 -0
  84. package/src/components/typography/MetadataText.tsx +65 -0
  85. package/src/components/typography/SecondaryText.tsx +60 -0
  86. package/src/components/typography/SectionLabel.tsx +60 -0
  87. package/src/components/typography/index.ts +14 -0
  88. package/src/components/typography-scales.tsx +218 -0
  89. package/src/components/ui/Avatar.tsx +123 -0
  90. package/src/components/ui/Badge.tsx +69 -2
  91. package/src/components/ui/Button.tsx +71 -30
  92. package/src/components/ui/Checkbox.tsx +34 -0
  93. package/src/components/ui/Dropdown.tsx +67 -1
  94. package/src/components/ui/EmptyState.tsx +129 -0
  95. package/src/components/ui/Input.tsx +53 -6
  96. package/src/components/ui/Modal.tsx +45 -12
  97. package/src/components/ui/OtpInput.tsx +148 -0
  98. package/src/components/ui/Skeleton.tsx +36 -0
  99. package/src/components/ui/Spinner.tsx +112 -0
  100. package/src/components/ui/Textarea.tsx +28 -3
  101. package/src/components/ui/Toast.tsx +99 -0
  102. package/src/components/ui/Toggle.tsx +63 -0
  103. package/src/components/ui/constants.ts +108 -0
  104. package/src/components/ui/index.ts +7 -0
  105. package/src/context/AuthContext.tsx +140 -0
  106. package/src/context/index.ts +1 -0
  107. package/src/hooks/backlog/index.ts +13 -0
  108. package/src/hooks/backlog/useBacklogActions.ts +144 -0
  109. package/src/hooks/backlog/useBacklogComposite.ts +73 -0
  110. package/src/hooks/backlog/useBacklogData.ts +74 -0
  111. package/src/hooks/backlog/useBacklogDragDrop.ts +118 -0
  112. package/src/hooks/backlog/useBacklogUI.ts +74 -0
  113. package/src/hooks/index.ts +22 -0
  114. package/src/hooks/task-panel/index.ts +13 -0
  115. package/src/hooks/task-panel/useTaskActions.ts +200 -0
  116. package/src/hooks/task-panel/useTaskComputedValues.ts +30 -0
  117. package/src/hooks/task-panel/useTaskData.ts +78 -0
  118. package/src/hooks/task-panel/useTaskPanelComposite.ts +161 -0
  119. package/src/hooks/task-panel/useTaskUIState.ts +80 -0
  120. package/src/hooks/useAuthLayoutLogic.ts +43 -0
  121. package/src/hooks/useAuthenticatedUser.ts +36 -0
  122. package/src/hooks/useAuthenticatedUserWithOrg.ts +41 -0
  123. package/src/hooks/useBacklog.ts +303 -0
  124. package/src/hooks/useBoard.ts +230 -0
  125. package/src/hooks/useDashboardLayout.ts +49 -0
  126. package/src/hooks/useDocs.ts +279 -0
  127. package/src/hooks/useDocsQuery.ts +99 -0
  128. package/src/hooks/useDocsSidebarState.ts +104 -0
  129. package/src/hooks/useFormState.ts +40 -0
  130. package/src/hooks/useGlobalKeydowns.ts +52 -0
  131. package/src/hooks/useInviteForm.ts +122 -0
  132. package/src/hooks/useLoginForm.ts +84 -0
  133. package/src/hooks/useMutationWithToast.ts +56 -0
  134. package/src/hooks/useOrganizationQuery.ts +55 -0
  135. package/src/hooks/useRegisterForm.ts +216 -0
  136. package/src/hooks/useSprintsQuery.ts +38 -0
  137. package/src/hooks/useTaskDescription.ts +102 -0
  138. package/src/hooks/useTaskPanel.ts +341 -0
  139. package/src/hooks/useTasksQuery.ts +39 -0
  140. package/src/hooks/useTeamManagement.ts +92 -0
  141. package/src/hooks/useWorkspaceCreateForm.ts +70 -0
  142. package/src/hooks/useWorkspaceId.ts +29 -0
  143. package/src/lib/api-client.ts +40 -23
  144. package/src/lib/config.ts +25 -0
  145. package/src/lib/constants.ts +83 -0
  146. package/src/lib/options.ts +96 -0
  147. package/src/lib/query-keys.ts +91 -0
  148. package/src/lib/typography.ts +103 -0
  149. package/src/lib/utils.ts +4 -0
  150. package/src/lib/validation.ts +192 -0
  151. package/src/services/index.ts +7 -3
  152. package/src/services/notifications.ts +80 -0
  153. package/src/utils/env.utils.ts +15 -0
  154. package/src/views/ActivityView.tsx +123 -0
  155. package/src/views/Dashboard.tsx +126 -0
  156. package/src/views/Docs.tsx +98 -612
  157. package/tsconfig.tsbuildinfo +1 -1
  158. package/.next/BUILD_ID +0 -1
  159. package/.next/app-build-manifest.json +0 -55
  160. package/.next/app-path-routes-manifest.json +0 -8
  161. package/.next/build-manifest.json +0 -33
  162. package/.next/cache/.previewinfo +0 -1
  163. package/.next/cache/.rscinfo +0 -1
  164. package/.next/cache/.tsbuildinfo +0 -1
  165. package/.next/cache/config.json +0 -7
  166. package/.next/cache/webpack/client-production/0.pack +0 -0
  167. package/.next/cache/webpack/client-production/index.pack +0 -0
  168. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  169. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  170. package/.next/cache/webpack/server-production/0.pack +0 -0
  171. package/.next/cache/webpack/server-production/index.pack +0 -0
  172. package/.next/diagnostics/build-diagnostics.json +0 -6
  173. package/.next/diagnostics/framework.json +0 -1
  174. package/.next/export-detail.json +0 -5
  175. package/.next/export-marker.json +0 -6
  176. package/.next/images-manifest.json +0 -57
  177. package/.next/next-minimal-server.js.nft.json +0 -1
  178. package/.next/next-server.js.nft.json +0 -1
  179. package/.next/package.json +0 -1
  180. package/.next/prerender-manifest.json +0 -137
  181. package/.next/react-loadable-manifest.json +0 -32
  182. package/.next/required-server-files.json +0 -324
  183. package/.next/routes-manifest.json +0 -77
  184. package/.next/server/app/_not-found/page.js +0 -2
  185. package/.next/server/app/_not-found/page.js.nft.json +0 -1
  186. package/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  187. package/.next/server/app/_not-found.html +0 -1
  188. package/.next/server/app/_not-found.meta +0 -8
  189. package/.next/server/app/_not-found.rsc +0 -21
  190. package/.next/server/app/backlog/page.js +0 -2
  191. package/.next/server/app/backlog/page.js.nft.json +0 -1
  192. package/.next/server/app/backlog/page_client-reference-manifest.js +0 -1
  193. package/.next/server/app/backlog.html +0 -1
  194. package/.next/server/app/backlog.meta +0 -7
  195. package/.next/server/app/backlog.rsc +0 -25
  196. package/.next/server/app/docs/page.js +0 -97
  197. package/.next/server/app/docs/page.js.nft.json +0 -1
  198. package/.next/server/app/docs/page_client-reference-manifest.js +0 -1
  199. package/.next/server/app/docs.html +0 -1
  200. package/.next/server/app/docs.meta +0 -7
  201. package/.next/server/app/docs.rsc +0 -26
  202. package/.next/server/app/favicon.ico/route.js +0 -1
  203. package/.next/server/app/favicon.ico/route.js.nft.json +0 -1
  204. package/.next/server/app/favicon.ico.body +0 -0
  205. package/.next/server/app/favicon.ico.meta +0 -1
  206. package/.next/server/app/index.html +0 -1
  207. package/.next/server/app/index.meta +0 -7
  208. package/.next/server/app/index.rsc +0 -25
  209. package/.next/server/app/page.js +0 -2
  210. package/.next/server/app/page.js.nft.json +0 -1
  211. package/.next/server/app/page_client-reference-manifest.js +0 -1
  212. package/.next/server/app/settings/page.js +0 -2
  213. package/.next/server/app/settings/page.js.nft.json +0 -1
  214. package/.next/server/app/settings/page_client-reference-manifest.js +0 -1
  215. package/.next/server/app/settings.html +0 -1
  216. package/.next/server/app/settings.meta +0 -7
  217. package/.next/server/app/settings.rsc +0 -25
  218. package/.next/server/app-paths-manifest.json +0 -8
  219. package/.next/server/chunks/496.js +0 -6
  220. package/.next/server/chunks/585.js +0 -1
  221. package/.next/server/chunks/665.js +0 -1
  222. package/.next/server/chunks/699.js +0 -22
  223. package/.next/server/chunks/852.js +0 -7
  224. package/.next/server/functions-config-manifest.json +0 -4
  225. package/.next/server/interception-route-rewrite-manifest.js +0 -1
  226. package/.next/server/middleware-build-manifest.js +0 -1
  227. package/.next/server/middleware-manifest.json +0 -6
  228. package/.next/server/middleware-react-loadable-manifest.js +0 -1
  229. package/.next/server/next-font-manifest.js +0 -1
  230. package/.next/server/next-font-manifest.json +0 -1
  231. package/.next/server/pages/404.html +0 -1
  232. package/.next/server/pages/500.html +0 -1
  233. package/.next/server/pages/_app.js +0 -1
  234. package/.next/server/pages/_app.js.nft.json +0 -1
  235. package/.next/server/pages/_document.js +0 -1
  236. package/.next/server/pages/_document.js.nft.json +0 -1
  237. package/.next/server/pages/_error.js +0 -19
  238. package/.next/server/pages/_error.js.nft.json +0 -1
  239. package/.next/server/pages-manifest.json +0 -6
  240. package/.next/server/server-reference-manifest.js +0 -1
  241. package/.next/server/server-reference-manifest.json +0 -1
  242. package/.next/server/webpack-runtime.js +0 -1
  243. package/.next/static/D0NXe04ZCLNDckV_quc8g/_buildManifest.js +0 -1
  244. package/.next/static/D0NXe04ZCLNDckV_quc8g/_ssgManifest.js +0 -1
  245. package/.next/static/chunks/138.b98511c56423f8bb.js +0 -1
  246. package/.next/static/chunks/146-34259952c594a3b0.js +0 -1
  247. package/.next/static/chunks/337-d3bb75304d130513.js +0 -1
  248. package/.next/static/chunks/477.1a6ecfe53375bd9c.js +0 -1
  249. package/.next/static/chunks/487-1808785ba665f784.js +0 -1
  250. package/.next/static/chunks/544.a9569941cc886e9d.js +0 -1
  251. package/.next/static/chunks/87c73c54-1f4741035a95c140.js +0 -1
  252. package/.next/static/chunks/902-d6926825a9fe8784.js +0 -1
  253. package/.next/static/chunks/955-c8f8f6235ae8f8c6.js +0 -1
  254. package/.next/static/chunks/996.e0a334e6ae90900e.js +0 -1
  255. package/.next/static/chunks/app/_not-found/page-44b1804abb44a34d.js +0 -1
  256. package/.next/static/chunks/app/backlog/page-dce1450769bfae8f.js +0 -1
  257. package/.next/static/chunks/app/docs/page-1efee819f25492cb.js +0 -1
  258. package/.next/static/chunks/app/layout-05f504c042b9f7ee.js +0 -1
  259. package/.next/static/chunks/app/page-3fd91aaaa4776ced.js +0 -1
  260. package/.next/static/chunks/app/settings/page-84e16c9638d657e4.js +0 -1
  261. package/.next/static/chunks/framework-152a1bc8c81c7458.js +0 -1
  262. package/.next/static/chunks/main-843ab130fc1be309.js +0 -1
  263. package/.next/static/chunks/main-app-123e879c5a937a00.js +0 -1
  264. package/.next/static/chunks/pages/_app-a050a8e6e4fb04cf.js +0 -1
  265. package/.next/static/chunks/pages/_error-3e422ffd891594de.js +0 -1
  266. package/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  267. package/.next/static/chunks/webpack-99a10a055b5bb9c4.js +0 -1
  268. package/.next/static/css/13e8617b72f9d3aa.css +0 -1
  269. package/.next/static/css/8aea088cdc4338f0.css +0 -1
  270. package/.next/static/css/b301ab0424111664.css +0 -1
  271. package/.next/static/media/24c15609eaa28576-s.woff2 +0 -0
  272. package/.next/static/media/2c07349e02a7b712-s.woff2 +0 -0
  273. package/.next/static/media/456105d6ea6d39e0-s.woff2 +0 -0
  274. package/.next/static/media/47cbc4e2adbc5db9-s.p.woff2 +0 -0
  275. package/.next/static/media/4f77bef990aad698-s.woff2 +0 -0
  276. package/.next/static/media/627d916fd739a539-s.woff2 +0 -0
  277. package/.next/static/media/63b255f18bea0ca9-s.woff2 +0 -0
  278. package/.next/static/media/70bd82ac89b4fa42-s.woff2 +0 -0
  279. package/.next/static/media/84602850c8fd81c3-s.woff2 +0 -0
  280. package/.next/trace +0 -46
  281. package/.next/types/app/backlog/page.ts +0 -84
  282. package/.next/types/app/docs/page.ts +0 -84
  283. package/.next/types/app/layout.ts +0 -84
  284. package/.next/types/app/page.ts +0 -84
  285. package/.next/types/app/settings/page.ts +0 -84
  286. package/.next/types/cache-life.d.ts +0 -141
  287. package/.next/types/package.json +0 -1
  288. package/next-env.d.ts +0 -5
  289. package/out/404.html +0 -1
  290. package/out/_next/static/D0NXe04ZCLNDckV_quc8g/_buildManifest.js +0 -1
  291. package/out/_next/static/D0NXe04ZCLNDckV_quc8g/_ssgManifest.js +0 -1
  292. package/out/_next/static/chunks/138.b98511c56423f8bb.js +0 -1
  293. package/out/_next/static/chunks/146-34259952c594a3b0.js +0 -1
  294. package/out/_next/static/chunks/337-d3bb75304d130513.js +0 -1
  295. package/out/_next/static/chunks/477.1a6ecfe53375bd9c.js +0 -1
  296. package/out/_next/static/chunks/487-1808785ba665f784.js +0 -1
  297. package/out/_next/static/chunks/544.a9569941cc886e9d.js +0 -1
  298. package/out/_next/static/chunks/87c73c54-1f4741035a95c140.js +0 -1
  299. package/out/_next/static/chunks/902-d6926825a9fe8784.js +0 -1
  300. package/out/_next/static/chunks/955-c8f8f6235ae8f8c6.js +0 -1
  301. package/out/_next/static/chunks/996.e0a334e6ae90900e.js +0 -1
  302. package/out/_next/static/chunks/app/_not-found/page-44b1804abb44a34d.js +0 -1
  303. package/out/_next/static/chunks/app/backlog/page-dce1450769bfae8f.js +0 -1
  304. package/out/_next/static/chunks/app/docs/page-1efee819f25492cb.js +0 -1
  305. package/out/_next/static/chunks/app/layout-05f504c042b9f7ee.js +0 -1
  306. package/out/_next/static/chunks/app/page-3fd91aaaa4776ced.js +0 -1
  307. package/out/_next/static/chunks/app/settings/page-84e16c9638d657e4.js +0 -1
  308. package/out/_next/static/chunks/framework-152a1bc8c81c7458.js +0 -1
  309. package/out/_next/static/chunks/main-843ab130fc1be309.js +0 -1
  310. package/out/_next/static/chunks/main-app-123e879c5a937a00.js +0 -1
  311. package/out/_next/static/chunks/pages/_app-a050a8e6e4fb04cf.js +0 -1
  312. package/out/_next/static/chunks/pages/_error-3e422ffd891594de.js +0 -1
  313. package/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  314. package/out/_next/static/chunks/webpack-99a10a055b5bb9c4.js +0 -1
  315. package/out/_next/static/css/13e8617b72f9d3aa.css +0 -1
  316. package/out/_next/static/css/8aea088cdc4338f0.css +0 -1
  317. package/out/_next/static/css/b301ab0424111664.css +0 -1
  318. package/out/_next/static/media/24c15609eaa28576-s.woff2 +0 -0
  319. package/out/_next/static/media/2c07349e02a7b712-s.woff2 +0 -0
  320. package/out/_next/static/media/456105d6ea6d39e0-s.woff2 +0 -0
  321. package/out/_next/static/media/47cbc4e2adbc5db9-s.p.woff2 +0 -0
  322. package/out/_next/static/media/4f77bef990aad698-s.woff2 +0 -0
  323. package/out/_next/static/media/627d916fd739a539-s.woff2 +0 -0
  324. package/out/_next/static/media/63b255f18bea0ca9-s.woff2 +0 -0
  325. package/out/_next/static/media/70bd82ac89b4fa42-s.woff2 +0 -0
  326. package/out/_next/static/media/84602850c8fd81c3-s.woff2 +0 -0
  327. package/out/backlog.html +0 -1
  328. package/out/backlog.txt +0 -25
  329. package/out/docs.html +0 -1
  330. package/out/docs.txt +0 -26
  331. package/out/favicon.ico +0 -0
  332. package/out/index.html +0 -1
  333. package/out/index.txt +0 -25
  334. package/out/logo.png +0 -0
  335. package/out/settings.html +0 -1
  336. package/out/settings.txt +0 -25
  337. package/src/app/backlog/page.tsx +0 -19
  338. package/src/app/page.tsx +0 -16
  339. package/src/app/settings/page.tsx +0 -194
  340. package/src/hooks/useTasks.ts +0 -119
  341. package/src/services/doc.service.ts +0 -27
  342. package/src/services/sprint.service.ts +0 -24
  343. package/src/services/task.service.ts +0 -75
  344. package/src/views/Backlog.tsx +0 -691
  345. package/src/views/Board.tsx +0 -306
  346. /package/src/app/{docs → (dashboard)/docs}/page.tsx +0 -0
@@ -1,4 +1,5 @@
1
1
  @import "tailwindcss";
2
+ @plugin "@tailwindcss/typography";
2
3
 
3
4
  @theme {
4
5
  /* Shadcn-like Design System */
@@ -601,3 +602,261 @@ input::placeholder {
601
602
  justify-content: center;
602
603
  color: var(--accent);
603
604
  }
605
+
606
+ /* Tiptap & ProseMirror Styles */
607
+ .ProseMirror {
608
+ outline: none !important;
609
+ }
610
+
611
+ .ProseMirror p.is-editor-empty:first-child::before {
612
+ content: attr(data-placeholder);
613
+ float: left;
614
+ color: var(--muted-foreground);
615
+ pointer-events: none;
616
+ height: 0;
617
+ opacity: 0.5;
618
+ font-style: italic;
619
+ }
620
+
621
+ /* Tighten regular lists */
622
+ .prose ul,
623
+ .prose ol,
624
+ .ProseMirror ul,
625
+ .ProseMirror ol {
626
+ margin-top: 0.5rem !important;
627
+ margin-bottom: 0.5rem !important;
628
+ }
629
+
630
+ .prose li,
631
+ .ProseMirror li {
632
+ margin-top: 0.125rem !important;
633
+ margin-bottom: 0.125rem !important;
634
+ }
635
+
636
+ .prose li > p,
637
+ .ProseMirror li > p {
638
+ margin: 0 !important;
639
+ }
640
+
641
+ /* Task List Styling */
642
+ ul[data-type="taskList"] {
643
+ list-style: none;
644
+ padding: 0;
645
+ }
646
+
647
+ ul[data-type="taskList"] li {
648
+ display: flex;
649
+ align-items: center;
650
+ gap: 0.75rem;
651
+ margin-bottom: 0.25rem !important; /* Tightened */
652
+ }
653
+
654
+ ul[data-type="taskList"] li > div p {
655
+ margin: 0 !important;
656
+ line-height: inherit;
657
+ }
658
+
659
+ ul[data-type="taskList"] li > label {
660
+ flex: 0 0 auto;
661
+ user-select: none;
662
+ display: flex;
663
+ align-items: center;
664
+ }
665
+
666
+ ul[data-type="taskList"] li > div {
667
+ flex: 1 1 auto;
668
+ min-height: 1.5rem;
669
+ display: flex;
670
+ align-items: center;
671
+ }
672
+
673
+ ul[data-type="taskList"] input[type="checkbox"] {
674
+ appearance: none;
675
+ background-color: transparent;
676
+ margin: 0;
677
+ font: inherit;
678
+ color: var(--primary);
679
+ width: 1.15em;
680
+ height: 1.15em;
681
+ border: 1.5px solid var(--border);
682
+ border-radius: 4px;
683
+ display: grid;
684
+ place-content: center;
685
+ cursor: pointer;
686
+ transition: all 0.2s ease;
687
+ }
688
+
689
+ /* Heading Overrides for Editor - Forced Hierarchy */
690
+ .prose h1,
691
+ .ProseMirror h1,
692
+ h1.text-3xl {
693
+ font-size: 2rem !important;
694
+ line-height: 1.1 !important;
695
+ font-weight: 900 !important;
696
+ margin-top: 2rem !important;
697
+ margin-bottom: 1.5rem !important;
698
+ display: block !important;
699
+ color: var(--foreground) !important;
700
+ }
701
+
702
+ .prose h2,
703
+ .ProseMirror h2,
704
+ h2.text-xl {
705
+ font-size: 1.5rem !important;
706
+ line-height: 1.2 !important;
707
+ font-weight: 800 !important;
708
+ margin-top: 1.5rem !important;
709
+ margin-bottom: 1.25rem !important;
710
+ display: block !important;
711
+ color: var(--foreground) !important;
712
+ }
713
+
714
+ .prose h3,
715
+ .ProseMirror h3,
716
+ h3.text-base {
717
+ font-size: 1rem !important;
718
+ line-height: 1.3 !important;
719
+ font-weight: 700 !important;
720
+ margin-top: 1.25rem !important;
721
+ margin-bottom: 1rem !important;
722
+ display: block !important;
723
+ color: var(--foreground) !important;
724
+ }
725
+
726
+ ul[data-type="taskList"] input[type="checkbox"]:hover {
727
+ background-color: var(--secondary);
728
+ border-color: var(--primary);
729
+ }
730
+
731
+ ul[data-type="taskList"] input[type="checkbox"]::before {
732
+ content: "";
733
+ width: 0.65em;
734
+ height: 0.65em;
735
+ transform: scale(0);
736
+ transition: 120ms transform ease-in-out;
737
+ box-shadow: inset 1em 1em var(--primary);
738
+ transform-origin: bottom left;
739
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
740
+ }
741
+
742
+ ul[data-type="taskList"] input[type="checkbox"]:checked::before {
743
+ transform: scale(1);
744
+ }
745
+
746
+ ul[data-type="taskList"] li[data-checked="true"] > div {
747
+ text-decoration: line-through;
748
+ opacity: 0.5;
749
+ }
750
+
751
+ /* Code Block & Inline Code Refinement */
752
+ .ProseMirror pre {
753
+ background: #0d1117 !important;
754
+ border: 1px solid var(--border) !important;
755
+ border-radius: 12px !important;
756
+ padding: 1.25rem !important;
757
+ margin: 1.5rem 0 !important;
758
+ font-family:
759
+ "JetBrains Mono", "Fira Code", ui-monospace, monospace !important;
760
+ font-size: 0.875rem !important;
761
+ line-height: 1.6 !important;
762
+ overflow-x: auto !important;
763
+ }
764
+
765
+ .ProseMirror pre code {
766
+ background: transparent !important;
767
+ padding: 0 !important;
768
+ border: none !important;
769
+ color: #e6edf3 !important;
770
+ font-family: inherit !important;
771
+ }
772
+
773
+ .ProseMirror code {
774
+ background: rgba(255, 255, 255, 0.05) !important;
775
+ color: var(--primary) !important;
776
+ padding: 0.2rem 0.4rem !important;
777
+ border-radius: 6px !important;
778
+ font-family: ui-monospace, monospace !important;
779
+ font-size: 0.85em !important;
780
+ border: 1px solid rgba(255, 255, 255, 0.05) !important;
781
+ }
782
+
783
+ /* Syntax Highlighting (lowlight / hljs) */
784
+ .hljs-comment,
785
+ .hljs-quote {
786
+ color: #8b949e;
787
+ font-style: italic;
788
+ }
789
+
790
+ .hljs-keyword,
791
+ .hljs-selector-tag,
792
+ .hljs-section,
793
+ .hljs-type {
794
+ color: #ff7b72;
795
+ }
796
+
797
+ .hljs-attribute,
798
+ .hljs-name,
799
+ .hljs-tag {
800
+ color: #7ee787;
801
+ }
802
+
803
+ .hljs-variable,
804
+ .hljs-template-variable,
805
+ .hljs-selector-id,
806
+ .hljs-selector-class {
807
+ color: #ffa657;
808
+ }
809
+
810
+ .hljs-string,
811
+ .hljs-regexp,
812
+ .hljs-addition {
813
+ color: #a5d6ff;
814
+ }
815
+
816
+ .hljs-symbol,
817
+ .hljs-bullet {
818
+ color: #79c0ff;
819
+ }
820
+
821
+ .hljs-number,
822
+ .hljs-built_in,
823
+ .hljs-builtin-name,
824
+ .hljs-literal,
825
+ .hljs-type,
826
+ .hljs-params {
827
+ color: #ff9bce;
828
+ }
829
+
830
+ .hljs-function,
831
+ .hljs-title {
832
+ color: #d2a8ff;
833
+ }
834
+
835
+ .hljs-keyword,
836
+ .hljs-selector-tag,
837
+ .hljs-section,
838
+ .hljs-type {
839
+ color: #ff7b72;
840
+ }
841
+
842
+ /* Custom Scrollbar for Editor Area */
843
+ .custom-scrollbar::-webkit-scrollbar {
844
+ width: 8px;
845
+ }
846
+
847
+ .custom-scrollbar::-webkit-scrollbar-track {
848
+ background: transparent;
849
+ }
850
+
851
+ .custom-scrollbar::-webkit-scrollbar-thumb {
852
+ background: var(--border);
853
+ border-radius: 20px;
854
+ border: 2px solid transparent;
855
+ background-clip: content-box;
856
+ }
857
+
858
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover {
859
+ background: var(--muted-foreground);
860
+ border: 2px solid transparent;
861
+ background-clip: content-box;
862
+ }
@@ -1,8 +1,6 @@
1
1
  import type { Metadata } from "next";
2
2
  import { Roboto } from "next/font/google";
3
3
  import "./globals.css";
4
- import { Header } from "@/components/Header";
5
- import { Sidebar } from "@/components/Sidebar";
6
4
  import { Providers } from "./providers";
7
5
 
8
6
  const roboto = Roboto({
@@ -20,26 +18,18 @@ export const metadata: Metadata = {
20
18
  },
21
19
  };
22
20
 
23
- export default function RootLayout({
24
- children,
25
- }: Readonly<{
21
+ type Props = {
26
22
  children: React.ReactNode;
27
- }>) {
28
- return (
29
- <html lang="en" className="dark">
30
- <body className={`${roboto.className} antialiased`}>
31
- <Providers>
32
- <div className="flex h-screen overflow-hidden bg-background">
33
- <Sidebar />
23
+ };
34
24
 
35
- <main className="flex-1 overflow-auto bg-background p-8">
36
- <div className="max-w-[1440px] mx-auto">
37
- <Header />
38
- {children}
39
- </div>
40
- </main>
41
- </div>
42
- </Providers>
25
+ export default function RootLayout({ children }: Props) {
26
+ return (
27
+ <html suppressHydrationWarning lang="en" className="dark">
28
+ <body
29
+ suppressHydrationWarning
30
+ className={`${roboto.className} antialiased`}
31
+ >
32
+ <Providers>{children}</Providers>
43
33
  </body>
44
34
  </html>
45
35
  );
@@ -3,14 +3,37 @@
3
3
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
4
  import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
5
5
  import { useState } from "react";
6
+ import { Toaster } from "@/components/ui/Toast";
7
+ import { AuthProvider } from "@/context";
8
+ import { QUERY_CONFIG } from "@/lib/constants";
6
9
 
7
10
  export function Providers({ children }: { children: React.ReactNode }) {
8
- const [queryClient] = useState(() => new QueryClient({}));
11
+ const [queryClient] = useState(
12
+ () =>
13
+ new QueryClient({
14
+ defaultOptions: {
15
+ queries: {
16
+ staleTime: QUERY_CONFIG.DEFAULT_STALE_TIME,
17
+ gcTime: QUERY_CONFIG.DEFAULT_GC_TIME,
18
+ retry: QUERY_CONFIG.DEFAULT_RETRY,
19
+ refetchOnWindowFocus: QUERY_CONFIG.REFETCH_ON_WINDOW_FOCUS,
20
+ },
21
+ mutations: {
22
+ retry: QUERY_CONFIG.MUTATION_RETRY,
23
+ },
24
+ },
25
+ })
26
+ );
27
+
28
+ const isProduction = process.env.NODE_ENV === "production";
9
29
 
10
30
  return (
11
31
  <QueryClientProvider client={queryClient}>
12
- {children}
13
- <ReactQueryDevtools initialIsOpen={false} />
32
+ <AuthProvider>
33
+ {children}
34
+ <Toaster />
35
+ {!isProduction && <ReactQueryDevtools initialIsOpen={false} />}
36
+ </AuthProvider>
14
37
  </QueryClientProvider>
15
38
  );
16
39
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Auth Layout UI Component
3
+ *
4
+ * Provides centered card layout for authentication pages.
5
+ * Includes branding, logo, and centered content area.
6
+ * Used by login, register, and other auth flows.
7
+ *
8
+ * Features:
9
+ * - Centered layout with max-width constraint
10
+ * - Branding section with logo
11
+ * - Responsive padding and spacing
12
+ * - Consistent styling across auth pages
13
+ *
14
+ * @example
15
+ * <AuthLayoutUI>
16
+ * <LoginForm />
17
+ * </AuthLayoutUI>
18
+ */
19
+
20
+ import Image from "next/image";
21
+ import { SecondaryText } from "./typography";
22
+
23
+ interface AuthLayoutUIProps {
24
+ /** Content to display in the centered card */
25
+ children: React.ReactNode;
26
+ }
27
+
28
+ export function AuthLayoutUI({ children }: AuthLayoutUIProps) {
29
+ return (
30
+ <div className="flex min-h-screen flex-col items-center justify-center bg-background p-6">
31
+ <div className="w-full max-w-[400px]">
32
+ {/* Branding Section */}
33
+ <div className="flex flex-col items-center mb-8">
34
+ <div className="relative h-8 w-[98px] mb-2">
35
+ <Image
36
+ src="/logo.png"
37
+ alt="Locus AI Logo"
38
+ fill
39
+ className="object-contain"
40
+ priority
41
+ />
42
+ </div>
43
+ <SecondaryText size="xs">Intelligent Task Management</SecondaryText>
44
+ </div>
45
+
46
+ {/* Content Card */}
47
+ <div className="bg-card border border-border/60 rounded-2xl p-8 shadow-sm">
48
+ {children}
49
+ </div>
50
+ </div>
51
+ </div>
52
+ );
53
+ }
@@ -1,98 +1,99 @@
1
+ /**
2
+ * Board Filter Component
3
+ *
4
+ * Provides filtering controls for board view.
5
+ * Supports search, priority filtering, and role filtering.
6
+ * Helps users find and organize tasks efficiently.
7
+ *
8
+ * Features:
9
+ * - Task search by title/content
10
+ * - Priority-based filtering
11
+ * - Role-based filtering
12
+ * - Clear filters button
13
+ * - Real-time filtering
14
+ *
15
+ * @example
16
+ * <BoardFilter
17
+ * searchQuery={search}
18
+ * onSearchChange={handleSearch}
19
+ * priorityFilter={priority}
20
+ * onPriorityChange={handlePriority}
21
+ * roleFilter={role}
22
+ * onRoleChange={handleRole}
23
+ * />
24
+ */
25
+
1
26
  "use client";
2
27
 
3
- import { AssigneeRole, TaskPriority } from "@locusai/shared";
4
- import { Search, X } from "lucide-react";
5
- import { Button, Dropdown, Input } from "@/components/ui";
28
+ import { AssigneeRole } from "@locusai/shared";
29
+ import { Filter } from "lucide-react";
6
30
 
7
31
  interface BoardFilterProps {
32
+ /** Current search query */
8
33
  searchQuery: string;
34
+ /** Called when search changes */
9
35
  onSearchChange: (query: string) => void;
10
- priorityFilter: TaskPriority | "ALL";
11
- onPriorityChange: (priority: TaskPriority | "ALL") => void;
12
- assigneeFilter: AssigneeRole | "ALL";
13
- onAssigneeChange: (assignee: AssigneeRole | "ALL") => void;
14
- onClearFilters: () => void;
15
- hasActiveFilters: boolean;
36
+ /** Currently selected priority filter */
37
+ priorityFilter: string | null;
38
+ /** Called when priority filter changes */
39
+ onPriorityChange: (priority: string | null) => void;
40
+ /** Currently selected role filter */
41
+ roleFilter: string | null;
42
+ /** Called when role filter changes */
43
+ onRoleChange: (role: string | null) => void;
16
44
  }
17
45
 
18
- const PRIORITY_FILTER_OPTIONS = [
19
- { value: "ALL" as const, label: "All Priorities" },
20
- { value: TaskPriority.LOW, label: "Low" },
21
- { value: TaskPriority.MEDIUM, label: "Medium" },
22
- { value: TaskPriority.HIGH, label: "High" },
23
- { value: TaskPriority.CRITICAL, label: "Critical" },
24
- ];
25
-
26
- const ASSIGNEE_FILTER_OPTIONS = [
27
- { value: "ALL" as const, label: "All Assignees" },
28
- ...Object.values(AssigneeRole).map((role) => ({
29
- value: role,
30
- label: role.charAt(0) + role.slice(1).toLowerCase(),
31
- })),
32
- ];
33
-
34
46
  export function BoardFilter({
35
47
  searchQuery,
36
48
  onSearchChange,
37
49
  priorityFilter,
38
50
  onPriorityChange,
39
- assigneeFilter,
40
- onAssigneeChange,
41
- onClearFilters,
42
- hasActiveFilters,
51
+ roleFilter,
52
+ onRoleChange,
43
53
  }: BoardFilterProps) {
44
54
  return (
45
- <div className="flex flex-wrap items-end gap-4 mb-8 bg-card p-4 rounded-xl border shadow-sm">
46
- <div className="flex-1 min-w-[300px]">
47
- <Input
55
+ <div className="flex items-center flex-wrap gap-3 p-2 bg-secondary/20 rounded-xl border border-border/40">
56
+ {/* Search */}
57
+ <div className="flex-1 min-w-[180px] relative">
58
+ <input
59
+ type="text"
60
+ placeholder="Filter tasks..."
48
61
  value={searchQuery}
49
62
  onChange={(e) => onSearchChange(e.target.value)}
50
- placeholder="Filter by title or ID..."
51
- className="search-input h-10"
52
- icon={<Search size={16} />}
53
- rightElement={
54
- searchQuery ? (
55
- <button
56
- className="hover:text-destructive transition-colors"
57
- onClick={() => onSearchChange("")}
58
- >
59
- <X size={14} />
60
- </button>
61
- ) : undefined
62
- }
63
+ className="w-full bg-background border border-border/50 rounded-lg pl-9 pr-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-primary/20"
64
+ />
65
+ <Filter
66
+ size={14}
67
+ className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground/50"
63
68
  />
64
69
  </div>
65
70
 
66
- <div className="flex gap-4">
67
- <div className="w-[180px]">
68
- <Dropdown
69
- label="Priority Filter"
70
- value={priorityFilter}
71
- onChange={onPriorityChange}
72
- options={PRIORITY_FILTER_OPTIONS}
73
- />
74
- </div>
75
- <div className="w-[180px]">
76
- <Dropdown
77
- label="Assignee Filter"
78
- value={assigneeFilter}
79
- onChange={onAssigneeChange}
80
- options={ASSIGNEE_FILTER_OPTIONS}
81
- />
82
- </div>
83
- </div>
71
+ {/* Priority Filter */}
72
+ <select
73
+ value={priorityFilter || ""}
74
+ onChange={(e) => onPriorityChange(e.target.value || null)}
75
+ className="bg-background border border-border/50 rounded-lg px-2 py-1.5 text-xs font-medium focus:outline-none h-8"
76
+ >
77
+ <option value="">All Priorities</option>
78
+ <option value="LOW">Low</option>
79
+ <option value="MEDIUM">Medium</option>
80
+ <option value="HIGH">High</option>
81
+ <option value="CRITICAL">Critical</option>
82
+ </select>
84
83
 
85
- {hasActiveFilters && (
86
- <Button
87
- variant="ghost"
88
- size="sm"
89
- className="text-muted-foreground hover:text-destructive h-10 px-4"
90
- onClick={onClearFilters}
91
- >
92
- <X size={14} className="mr-2" />
93
- Clear All
94
- </Button>
95
- )}
84
+ {/* Role Filter */}
85
+ <select
86
+ value={roleFilter || ""}
87
+ onChange={(e) => onRoleChange(e.target.value || null)}
88
+ className="bg-background border border-border/50 rounded-lg px-2 py-1.5 text-xs font-medium focus:outline-none h-8"
89
+ >
90
+ <option value="">All Roles</option>
91
+ <option value={AssigneeRole.BACKEND}>Backend</option>
92
+ <option value={AssigneeRole.FRONTEND}>Frontend</option>
93
+ <option value={AssigneeRole.QA}>QA</option>
94
+ <option value={AssigneeRole.PM}>PM</option>
95
+ <option value={AssigneeRole.DESIGN}>Design</option>
96
+ </select>
96
97
  </div>
97
98
  );
98
99
  }