@pylonsync/create-pylon 0.19.1 → 0.21.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 (696) hide show
  1. package/bin/create-pylon.js +30 -7
  2. package/package.json +1 -1
  3. package/templates/_root/AGENTS.md +1 -1
  4. package/templates/agency/.env.example +7 -0
  5. package/templates/agency/AGENTS.md +1 -1
  6. package/templates/agency/README.md +28 -3
  7. package/templates/agency/app/(marketing)/contact-form.tsx +20 -18
  8. package/templates/agency/app/(marketing)/page.tsx +3 -3
  9. package/templates/agency/app/(marketing)/work/page.tsx +3 -3
  10. package/templates/agency/app/auth-form.tsx +4 -4
  11. package/templates/agency/app/dashboard/dashboard-client.tsx +110 -64
  12. package/templates/agency/app/dashboard/page.tsx +14 -16
  13. package/templates/agency/app/icon.svg +3 -0
  14. package/templates/agency/app/login/page.tsx +12 -14
  15. package/templates/agency/components/marketing.tsx +12 -5
  16. package/templates/agency/functions/seedStudioBackoffice.ts +42 -11
  17. package/templates/agency/lib/agency.ts +22 -0
  18. package/templates/agency/lib/demo.ts +118 -0
  19. package/templates/agency/lib/site.config.ts +19 -13
  20. package/templates/agency/public/favicon.ico +0 -0
  21. package/templates/agency/tests/agency.test.ts +57 -0
  22. package/templates/ai-chat/.env.example +13 -27
  23. package/templates/ai-chat/AGENTS.md +1 -1
  24. package/templates/ai-chat/README.md +53 -60
  25. package/templates/ai-chat/app/(chat)/c/[id]/page.tsx +19 -0
  26. package/templates/ai-chat/app/(chat)/chat-client.tsx +657 -622
  27. package/templates/ai-chat/app/(chat)/layout.tsx +6 -43
  28. package/templates/ai-chat/app/(chat)/not-found.tsx +6 -10
  29. package/templates/ai-chat/app/(chat)/page.tsx +7 -11
  30. package/templates/ai-chat/app/auth-form.tsx +45 -38
  31. package/templates/ai-chat/app/error.tsx +9 -12
  32. package/templates/ai-chat/app/globals.css +464 -102
  33. package/templates/ai-chat/app/layout.tsx +11 -19
  34. package/templates/ai-chat/app/login/page.tsx +39 -24
  35. package/templates/ai-chat/app.ts +118 -43
  36. package/templates/ai-chat/components/chat/composer.tsx +193 -0
  37. package/templates/ai-chat/components/chat/empty-state.tsx +65 -0
  38. package/templates/ai-chat/components/chat/icons.tsx +198 -0
  39. package/templates/ai-chat/components/chat/markdown.tsx +164 -0
  40. package/templates/ai-chat/components/chat/message.tsx +183 -0
  41. package/templates/ai-chat/components/chat/setup.tsx +71 -0
  42. package/templates/ai-chat/components/chat/sidebar.tsx +288 -0
  43. package/templates/ai-chat/functions/_beginTurn.ts +145 -0
  44. package/templates/ai-chat/functions/_finishTurn.ts +55 -0
  45. package/templates/ai-chat/functions/assistantStatus.ts +13 -0
  46. package/templates/ai-chat/functions/claimGuestHistory.ts +39 -0
  47. package/templates/ai-chat/functions/createConversation.ts +28 -0
  48. package/templates/ai-chat/functions/deleteConversation.ts +15 -20
  49. package/templates/ai-chat/functions/prepareGuestClaim.ts +32 -0
  50. package/templates/ai-chat/functions/renameConversation.ts +19 -0
  51. package/templates/ai-chat/functions/respond.ts +88 -0
  52. package/templates/ai-chat/functions/seedExamples.ts +46 -0
  53. package/templates/ai-chat/functions/stopResponse.ts +30 -0
  54. package/templates/ai-chat/lib/brand-icon.ts +7 -0
  55. package/templates/ai-chat/lib/chat.ts +277 -0
  56. package/templates/ai-chat/lib/claim.ts +15 -0
  57. package/templates/ai-chat/lib/examples.ts +179 -0
  58. package/templates/ai-chat/lib/highlight.ts +107 -0
  59. package/templates/ai-chat/lib/markdown.ts +317 -0
  60. package/templates/ai-chat/lib/provider.ts +38 -0
  61. package/templates/ai-chat/lib/site.config.ts +55 -39
  62. package/templates/ai-chat/tests/chat.test.ts +174 -0
  63. package/templates/ai-chat/tests/components.test.tsx +57 -0
  64. package/templates/ai-chat/tests/markdown.test.ts +88 -0
  65. package/templates/ai-chat/tests/provider.test.ts +32 -0
  66. package/templates/ai-studio/AGENTS.md +1 -1
  67. package/templates/backend/consumer/apps/api/app/layout.tsx +33 -0
  68. package/templates/backend/consumer/apps/api/app/page.tsx +54 -0
  69. package/templates/backend/consumer/apps/api/app.ts +166 -0
  70. package/templates/backend/consumer/apps/api/functions/addComment.ts +24 -0
  71. package/templates/backend/consumer/apps/api/functions/createPost.ts +19 -36
  72. package/templates/backend/consumer/apps/api/functions/deletePost.ts +15 -13
  73. package/templates/backend/consumer/apps/api/functions/myProfile.ts +5 -8
  74. package/templates/backend/consumer/apps/api/functions/seedDemo.ts +95 -0
  75. package/templates/backend/consumer/apps/api/functions/setFollow.ts +36 -0
  76. package/templates/backend/consumer/apps/api/functions/setLike.ts +36 -0
  77. package/templates/backend/consumer/apps/api/functions/upsertProfile.ts +43 -37
  78. package/templates/backend/consumer/apps/api/lib/seed.ts +89 -0
  79. package/templates/backend/consumer/apps/api/lib/social.ts +50 -0
  80. package/templates/backend/consumer/apps/api/package.json +8 -2
  81. package/templates/backend/consumer/apps/api/public/images/posts/arch.jpg +0 -0
  82. package/templates/backend/consumer/apps/api/public/images/posts/coffee.jpg +0 -0
  83. package/templates/backend/consumer/apps/api/public/images/posts/dog.jpg +0 -0
  84. package/templates/backend/consumer/apps/api/public/images/posts/lisbon.jpg +0 -0
  85. package/templates/backend/consumer/apps/api/public/images/posts/ramen.jpg +0 -0
  86. package/templates/backend/consumer/apps/api/public/images/posts/run.jpg +0 -0
  87. package/templates/backend/consumer/apps/api/public/images/posts/sunset.jpg +0 -0
  88. package/templates/backend/consumer/apps/api/tsconfig.json +12 -2
  89. package/templates/barebones/AGENTS.md +1 -1
  90. package/templates/chat/AGENTS.md +1 -1
  91. package/templates/chat/README.md +43 -21
  92. package/templates/chat/app/chat-client.tsx +495 -85
  93. package/templates/chat/app/error.tsx +1 -1
  94. package/templates/chat/app/globals.css +170 -54
  95. package/templates/chat/app/layout.tsx +12 -9
  96. package/templates/chat/app/not-found.tsx +4 -2
  97. package/templates/chat/app/page.tsx +9 -19
  98. package/templates/chat/app.ts +96 -17
  99. package/templates/chat/components/chat/avatar.tsx +45 -0
  100. package/templates/chat/components/chat/composer.tsx +110 -0
  101. package/templates/chat/components/chat/message-list.tsx +285 -0
  102. package/templates/chat/components/chat/sidebar.tsx +190 -0
  103. package/templates/chat/functions/joinChat.ts +83 -0
  104. package/templates/chat/functions/renameMember.ts +25 -0
  105. package/templates/chat/lib/chat.ts +188 -0
  106. package/templates/chat/lib/seed.ts +78 -0
  107. package/templates/chat/tests/chat.test.ts +159 -0
  108. package/templates/chat/tests/composer.test.tsx +54 -0
  109. package/templates/consumer/AGENTS.md +1 -1
  110. package/templates/consumer/README.md +3 -3
  111. package/templates/consumer/app/globals.css +10 -3
  112. package/templates/consumer/app/icon.svg +1 -0
  113. package/templates/consumer/components/social/avatar.tsx +25 -11
  114. package/templates/consumer/functions/seedFeed.ts +3 -3
  115. package/templates/consumer/lib/seed.ts +43 -85
  116. package/templates/consumer/public/favicon.ico +0 -0
  117. package/templates/consumer/public/images/posts/arch.jpg +0 -0
  118. package/templates/consumer/public/images/posts/coffee.jpg +0 -0
  119. package/templates/consumer/public/images/posts/dog.jpg +0 -0
  120. package/templates/consumer/public/images/posts/lisbon.jpg +0 -0
  121. package/templates/consumer/public/images/posts/ramen.jpg +0 -0
  122. package/templates/consumer/public/images/posts/run.jpg +0 -0
  123. package/templates/consumer/public/images/posts/sunset.jpg +0 -0
  124. package/templates/consumer/tests/seed.test.ts +39 -0
  125. package/templates/creator/.env.example +7 -0
  126. package/templates/creator/AGENTS.md +1 -1
  127. package/templates/creator/README.md +24 -5
  128. package/templates/creator/app/(marketing)/newsletter-signup.tsx +33 -12
  129. package/templates/creator/app/auth-form.tsx +7 -7
  130. package/templates/creator/app/dashboard/dashboard-client.tsx +137 -100
  131. package/templates/creator/app/dashboard/page.tsx +18 -18
  132. package/templates/creator/app/icon.svg +2 -0
  133. package/templates/creator/app/login/page.tsx +14 -14
  134. package/templates/creator/app.ts +4 -4
  135. package/templates/creator/functions/seedDemo.ts +32 -0
  136. package/templates/creator/functions/subscribe.ts +4 -15
  137. package/templates/creator/lib/demo.ts +94 -0
  138. package/templates/creator/lib/site.config.ts +15 -10
  139. package/templates/creator/lib/stats.ts +35 -0
  140. package/templates/creator/public/favicon.ico +0 -0
  141. package/templates/creator/tests/counter.test.ts +92 -0
  142. package/templates/creator/tests/live-count.test.tsx +45 -0
  143. package/templates/crm/AGENTS.md +1 -1
  144. package/templates/crm/README.md +22 -1
  145. package/templates/crm/app/apple-icon.png +0 -0
  146. package/templates/crm/app/companies/companies-view.tsx +32 -14
  147. package/templates/crm/app/companies/page.tsx +2 -1
  148. package/templates/crm/app/contacts/contacts-view.tsx +34 -10
  149. package/templates/crm/app/contacts/page.tsx +2 -1
  150. package/templates/crm/app/deals/[id]/deal-view.tsx +137 -98
  151. package/templates/crm/app/deals/[id]/page.tsx +2 -1
  152. package/templates/crm/app/globals.css +29 -14
  153. package/templates/crm/app/icon.svg +1 -0
  154. package/templates/crm/app/layout.tsx +7 -5
  155. package/templates/crm/app/page.tsx +2 -1
  156. package/templates/crm/app/pipeline-view.tsx +5 -5
  157. package/templates/crm/app/workspace.tsx +29 -17
  158. package/templates/crm/app.ts +5 -5
  159. package/templates/crm/components/activity-timeline.tsx +14 -4
  160. package/templates/crm/components/app-shell.tsx +94 -0
  161. package/templates/crm/components/auth-form.tsx +35 -5
  162. package/templates/crm/components/avatar.tsx +5 -1
  163. package/templates/crm/components/board-skeleton.tsx +5 -5
  164. package/templates/crm/components/brand-mark.tsx +25 -0
  165. package/templates/crm/components/command-palette.tsx +17 -17
  166. package/templates/crm/components/data-table.tsx +97 -36
  167. package/templates/crm/components/deal-card.tsx +23 -27
  168. package/templates/crm/components/filter-tabs.tsx +101 -0
  169. package/templates/crm/components/metrics-bar.tsx +6 -6
  170. package/templates/crm/components/nav.tsx +15 -0
  171. package/templates/crm/components/page-header.tsx +43 -7
  172. package/templates/crm/components/pipeline-board.tsx +16 -10
  173. package/templates/crm/components/require-auth.tsx +24 -26
  174. package/templates/crm/components/sidebar.tsx +54 -49
  175. package/templates/crm/components/stage-badge.tsx +4 -2
  176. package/templates/crm/components/ui/button.tsx +5 -4
  177. package/templates/crm/components/ui/dialog.tsx +1 -1
  178. package/templates/crm/components/ui/input.tsx +1 -1
  179. package/templates/crm/components/ui/select.tsx +1 -1
  180. package/templates/crm/components/ui/textarea.tsx +1 -1
  181. package/templates/crm/functions/seedWorkspace.ts +32 -17
  182. package/templates/crm/lib/brand.ts +9 -0
  183. package/templates/crm/lib/demo-team.ts +51 -0
  184. package/templates/crm/lib/pipeline.ts +37 -0
  185. package/templates/crm/lib/search.ts +4 -3
  186. package/templates/crm/lib/seed.ts +53 -8
  187. package/templates/crm/public/favicon.ico +0 -0
  188. package/templates/crm/tests/components.test.tsx +5 -5
  189. package/templates/crm/tests/demo-team.test.ts +18 -0
  190. package/templates/crm/tests/pipeline.test.ts +59 -3
  191. package/templates/directory/.env.example +7 -0
  192. package/templates/directory/AGENTS.md +1 -1
  193. package/templates/directory/README.md +22 -3
  194. package/templates/directory/app/(marketing)/directory-browse.tsx +30 -12
  195. package/templates/directory/app/(marketing)/page.tsx +6 -4
  196. package/templates/directory/app/auth-form.tsx +4 -4
  197. package/templates/directory/app/dashboard/dashboard-client.tsx +177 -90
  198. package/templates/directory/app/dashboard/page.tsx +16 -14
  199. package/templates/directory/app/icon.svg +4 -0
  200. package/templates/directory/app/login/page.tsx +16 -15
  201. package/templates/directory/functions/seedDemo.ts +43 -0
  202. package/templates/directory/lib/demo.ts +145 -0
  203. package/templates/directory/lib/directory.ts +27 -0
  204. package/templates/directory/lib/site.config.ts +21 -16
  205. package/templates/directory/public/favicon.ico +0 -0
  206. package/templates/directory/tests/directory.test.ts +46 -0
  207. package/templates/expo/consumer/apps/expo/App.tsx +360 -288
  208. package/templates/expo/consumer/apps/expo/app.json +9 -1
  209. package/templates/expo/consumer/apps/expo/package.json +2 -1
  210. package/templates/helpdesk/AGENTS.md +1 -1
  211. package/templates/helpdesk/README.md +21 -0
  212. package/templates/helpdesk/app/apple-icon.png +0 -0
  213. package/templates/helpdesk/app/customers/customers-view.tsx +23 -7
  214. package/templates/helpdesk/app/customers/page.tsx +2 -1
  215. package/templates/helpdesk/app/globals.css +29 -14
  216. package/templates/helpdesk/app/icon.svg +1 -0
  217. package/templates/helpdesk/app/inbox-view.tsx +66 -47
  218. package/templates/helpdesk/app/layout.tsx +7 -5
  219. package/templates/helpdesk/app/page.tsx +4 -7
  220. package/templates/helpdesk/app/tickets/[id]/page.tsx +2 -1
  221. package/templates/helpdesk/app/tickets/[id]/ticket-view.tsx +134 -97
  222. package/templates/helpdesk/app/workspace.tsx +33 -22
  223. package/templates/helpdesk/app.ts +2 -2
  224. package/templates/helpdesk/components/app-shell.tsx +94 -0
  225. package/templates/helpdesk/components/auth-form.tsx +35 -5
  226. package/templates/helpdesk/components/avatar.tsx +5 -1
  227. package/templates/helpdesk/components/brand-mark.tsx +28 -0
  228. package/templates/helpdesk/components/command-palette.tsx +17 -17
  229. package/templates/helpdesk/components/data-table.tsx +97 -36
  230. package/templates/helpdesk/components/filter-tabs.tsx +101 -0
  231. package/templates/helpdesk/components/nav.tsx +14 -0
  232. package/templates/helpdesk/components/page-header.tsx +43 -7
  233. package/templates/helpdesk/components/priority-badge.tsx +49 -6
  234. package/templates/helpdesk/components/require-auth.tsx +24 -26
  235. package/templates/helpdesk/components/sidebar.tsx +54 -48
  236. package/templates/helpdesk/components/sla-indicator.tsx +5 -8
  237. package/templates/helpdesk/components/thread.tsx +7 -7
  238. package/templates/helpdesk/components/ticket-list.tsx +79 -19
  239. package/templates/helpdesk/components/ui/button.tsx +5 -4
  240. package/templates/helpdesk/components/ui/dialog.tsx +1 -1
  241. package/templates/helpdesk/components/ui/input.tsx +1 -1
  242. package/templates/helpdesk/components/ui/select.tsx +1 -1
  243. package/templates/helpdesk/components/ui/textarea.tsx +1 -1
  244. package/templates/helpdesk/functions/seedWorkspace.ts +25 -15
  245. package/templates/helpdesk/lib/brand.ts +9 -0
  246. package/templates/helpdesk/lib/demo-team.ts +51 -0
  247. package/templates/helpdesk/lib/search.ts +4 -3
  248. package/templates/helpdesk/lib/seed.ts +43 -2
  249. package/templates/helpdesk/lib/tickets.ts +68 -20
  250. package/templates/helpdesk/public/favicon.ico +0 -0
  251. package/templates/helpdesk/tests/components.test.tsx +10 -0
  252. package/templates/helpdesk/tests/demo-team.test.ts +18 -0
  253. package/templates/helpdesk/tests/tickets.test.ts +70 -0
  254. package/templates/imessage/.env.example +49 -0
  255. package/templates/imessage/AGENTS.md +153 -0
  256. package/templates/imessage/CLAUDE.md +7 -0
  257. package/templates/imessage/README.md +187 -0
  258. package/templates/imessage/app/console.tsx +382 -0
  259. package/templates/imessage/app/contacts/page.tsx +13 -0
  260. package/templates/imessage/app/error.tsx +16 -0
  261. package/templates/imessage/app/gate.tsx +31 -0
  262. package/templates/imessage/app/globals.css +183 -0
  263. package/templates/imessage/app/layout.tsx +17 -0
  264. package/templates/imessage/app/login/login-form.tsx +115 -0
  265. package/templates/imessage/app/login/page.tsx +30 -0
  266. package/templates/imessage/app/not-found.tsx +13 -0
  267. package/templates/imessage/app/page.tsx +14 -0
  268. package/templates/imessage/app/robots.ts +6 -0
  269. package/templates/imessage/app/setup/page.tsx +13 -0
  270. package/templates/imessage/app/sign-out.tsx +20 -0
  271. package/templates/imessage/app.ts +299 -0
  272. package/templates/imessage/bunfig +4 -0
  273. package/templates/imessage/components/avatar.tsx +46 -0
  274. package/templates/imessage/components/contact-panel.tsx +263 -0
  275. package/templates/imessage/components/contacts-view.tsx +172 -0
  276. package/templates/imessage/components/conversation-list.tsx +129 -0
  277. package/templates/imessage/components/nav-rail.tsx +67 -0
  278. package/templates/imessage/components/setup-view.tsx +408 -0
  279. package/templates/imessage/components/thread.tsx +229 -0
  280. package/templates/imessage/components/ui/badge.tsx +37 -0
  281. package/templates/imessage/components/ui/button.tsx +56 -0
  282. package/templates/imessage/components/ui/card.tsx +90 -0
  283. package/templates/imessage/components/ui/dialog.tsx +110 -0
  284. package/templates/imessage/components/ui/input.tsx +30 -0
  285. package/templates/imessage/components/ui/label.tsx +21 -0
  286. package/templates/imessage/components/ui/select.tsx +39 -0
  287. package/templates/imessage/components/ui/table.tsx +124 -0
  288. package/templates/imessage/components/ui/textarea.tsx +24 -0
  289. package/templates/imessage/components.json +20 -0
  290. package/templates/imessage/functions/answerNow.ts +34 -0
  291. package/templates/imessage/functions/assistant.ts +96 -0
  292. package/templates/imessage/functions/beginTurn.ts +101 -0
  293. package/templates/imessage/functions/cancelReminder.ts +13 -0
  294. package/templates/imessage/functions/claimOutbound.ts +44 -0
  295. package/templates/imessage/functions/clearDemo.ts +18 -0
  296. package/templates/imessage/functions/deleteNote.ts +11 -0
  297. package/templates/imessage/functions/deliverOutbound.ts +55 -0
  298. package/templates/imessage/functions/finishTurn.ts +84 -0
  299. package/templates/imessage/functions/fireReminder.ts +42 -0
  300. package/templates/imessage/functions/ingestInbound.ts +22 -0
  301. package/templates/imessage/functions/ownerAccount.ts +13 -0
  302. package/templates/imessage/functions/processTurn.ts +74 -0
  303. package/templates/imessage/functions/relayApply.ts +102 -0
  304. package/templates/imessage/functions/relaySync.ts +63 -0
  305. package/templates/imessage/functions/releaseOutbound.ts +18 -0
  306. package/templates/imessage/functions/resolveTurn.ts +25 -0
  307. package/templates/imessage/functions/saveContact.ts +27 -0
  308. package/templates/imessage/functions/seedDemo.ts +70 -0
  309. package/templates/imessage/functions/sendOwnerMessage.ts +28 -0
  310. package/templates/imessage/functions/sendblueWebhook.ts +49 -0
  311. package/templates/imessage/functions/setContactStatus.ts +17 -0
  312. package/templates/imessage/functions/settleOutbound.ts +35 -0
  313. package/templates/imessage/functions/setupStatus.ts +33 -0
  314. package/templates/imessage/functions/sweep.ts +58 -0
  315. package/templates/imessage/functions/toolCancelReminder.ts +17 -0
  316. package/templates/imessage/functions/toolForgetNote.ts +15 -0
  317. package/templates/imessage/functions/toolListNotes.ts +16 -0
  318. package/templates/imessage/functions/toolListReminders.ts +17 -0
  319. package/templates/imessage/functions/toolSaveNote.ts +22 -0
  320. package/templates/imessage/functions/toolSetReminder.ts +55 -0
  321. package/templates/imessage/functions/updateSettings.ts +48 -0
  322. package/templates/imessage/gitignore +11 -0
  323. package/templates/imessage/lib/agent-call.ts +251 -0
  324. package/templates/imessage/lib/assistant.ts +74 -0
  325. package/templates/imessage/lib/chunk.ts +135 -0
  326. package/templates/imessage/lib/demo.ts +68 -0
  327. package/templates/imessage/lib/format.ts +170 -0
  328. package/templates/imessage/lib/gate.ts +104 -0
  329. package/templates/imessage/lib/handles.ts +67 -0
  330. package/templates/imessage/lib/provider.ts +38 -0
  331. package/templates/imessage/lib/relay-protocol.ts +95 -0
  332. package/templates/imessage/lib/reminders.ts +41 -0
  333. package/templates/imessage/lib/secrets.ts +59 -0
  334. package/templates/imessage/lib/sendblue.ts +173 -0
  335. package/templates/imessage/lib/store.ts +407 -0
  336. package/templates/imessage/lib/transport.ts +135 -0
  337. package/templates/imessage/lib/utils.ts +10 -0
  338. package/templates/imessage/package.json +40 -0
  339. package/templates/imessage/relay/.env.example +14 -0
  340. package/templates/imessage/relay/applescript.ts +70 -0
  341. package/templates/imessage/relay/chatdb.ts +165 -0
  342. package/templates/imessage/relay/client.ts +41 -0
  343. package/templates/imessage/relay/main.ts +137 -0
  344. package/templates/imessage/relay/state.ts +35 -0
  345. package/templates/imessage/tests/agent-call.test.ts +112 -0
  346. package/templates/imessage/tests/applescript.test.ts +88 -0
  347. package/templates/imessage/tests/chatdb.test.ts +139 -0
  348. package/templates/imessage/tests/chunk.test.ts +61 -0
  349. package/templates/imessage/tests/fake-ctx.ts +88 -0
  350. package/templates/imessage/tests/ingest.test.ts +141 -0
  351. package/templates/imessage/tests/lib.test.ts +99 -0
  352. package/templates/imessage/tests/review-fixes.test.ts +138 -0
  353. package/templates/imessage/tests/secrets.test.ts +36 -0
  354. package/templates/imessage/tests/sendblue.test.ts +143 -0
  355. package/templates/imessage/tests/setup.ts +5 -0
  356. package/templates/imessage/tsconfig.json +18 -0
  357. package/templates/inventory/AGENTS.md +1 -1
  358. package/templates/inventory/README.md +21 -0
  359. package/templates/inventory/app/apple-icon.png +0 -0
  360. package/templates/inventory/app/globals.css +29 -14
  361. package/templates/inventory/app/icon.svg +1 -0
  362. package/templates/inventory/app/layout.tsx +7 -5
  363. package/templates/inventory/app/movements/movements-view.tsx +32 -10
  364. package/templates/inventory/app/movements/page.tsx +2 -1
  365. package/templates/inventory/app/page.tsx +4 -6
  366. package/templates/inventory/app/products/[id]/page.tsx +2 -1
  367. package/templates/inventory/app/products/[id]/product-view.tsx +55 -25
  368. package/templates/inventory/app/products-view.tsx +74 -33
  369. package/templates/inventory/app/workspace.tsx +34 -16
  370. package/templates/inventory/app.ts +10 -2
  371. package/templates/inventory/components/app-shell.tsx +94 -0
  372. package/templates/inventory/components/auth-form.tsx +35 -5
  373. package/templates/inventory/components/avatar.tsx +5 -1
  374. package/templates/inventory/components/brand-mark.tsx +25 -0
  375. package/templates/inventory/components/category-tile.tsx +49 -0
  376. package/templates/inventory/components/command-palette.tsx +17 -17
  377. package/templates/inventory/components/data-table.tsx +97 -36
  378. package/templates/inventory/components/filter-tabs.tsx +101 -0
  379. package/templates/inventory/components/nav.tsx +14 -0
  380. package/templates/inventory/components/page-header.tsx +43 -7
  381. package/templates/inventory/components/require-auth.tsx +24 -26
  382. package/templates/inventory/components/sidebar.tsx +54 -48
  383. package/templates/inventory/components/stock-level.tsx +30 -14
  384. package/templates/inventory/components/summary-bar.tsx +8 -15
  385. package/templates/inventory/components/ui/button.tsx +5 -4
  386. package/templates/inventory/components/ui/dialog.tsx +1 -1
  387. package/templates/inventory/components/ui/input.tsx +1 -1
  388. package/templates/inventory/components/ui/select.tsx +1 -1
  389. package/templates/inventory/components/ui/textarea.tsx +1 -1
  390. package/templates/inventory/functions/seedWorkspace.ts +18 -8
  391. package/templates/inventory/lib/brand.ts +9 -0
  392. package/templates/inventory/lib/demo-team.ts +51 -0
  393. package/templates/inventory/lib/search.ts +4 -3
  394. package/templates/inventory/lib/seed.ts +29 -2
  395. package/templates/inventory/lib/stock.ts +32 -0
  396. package/templates/inventory/public/favicon.ico +0 -0
  397. package/templates/inventory/tests/demo-team.test.ts +18 -0
  398. package/templates/inventory/tests/stock.test.ts +29 -0
  399. package/templates/invoices/AGENTS.md +1 -1
  400. package/templates/invoices/README.md +16 -0
  401. package/templates/invoices/app/apple-icon.png +0 -0
  402. package/templates/invoices/app/clients/clients-view.tsx +18 -6
  403. package/templates/invoices/app/clients/page.tsx +2 -1
  404. package/templates/invoices/app/globals.css +29 -14
  405. package/templates/invoices/app/icon.svg +1 -0
  406. package/templates/invoices/app/invoices/[id]/invoice-view.tsx +72 -48
  407. package/templates/invoices/app/invoices/[id]/page.tsx +2 -1
  408. package/templates/invoices/app/invoices-view.tsx +81 -32
  409. package/templates/invoices/app/layout.tsx +7 -5
  410. package/templates/invoices/app/page.tsx +4 -6
  411. package/templates/invoices/app/workspace.tsx +26 -16
  412. package/templates/invoices/app.ts +2 -2
  413. package/templates/invoices/components/app-shell.tsx +94 -0
  414. package/templates/invoices/components/auth-form.tsx +35 -5
  415. package/templates/invoices/components/avatar.tsx +5 -1
  416. package/templates/invoices/components/brand-mark.tsx +26 -0
  417. package/templates/invoices/components/command-palette.tsx +17 -17
  418. package/templates/invoices/components/data-table.tsx +97 -36
  419. package/templates/invoices/components/filter-tabs.tsx +101 -0
  420. package/templates/invoices/components/line-items.tsx +19 -14
  421. package/templates/invoices/components/nav.tsx +14 -0
  422. package/templates/invoices/components/page-header.tsx +43 -7
  423. package/templates/invoices/components/require-auth.tsx +24 -26
  424. package/templates/invoices/components/sidebar.tsx +54 -48
  425. package/templates/invoices/components/status-badge.tsx +7 -7
  426. package/templates/invoices/components/summary-bar.tsx +5 -5
  427. package/templates/invoices/components/ui/button.tsx +5 -4
  428. package/templates/invoices/components/ui/dialog.tsx +1 -1
  429. package/templates/invoices/components/ui/input.tsx +1 -1
  430. package/templates/invoices/components/ui/select.tsx +1 -1
  431. package/templates/invoices/components/ui/textarea.tsx +1 -1
  432. package/templates/invoices/functions/recordPayment.ts +3 -0
  433. package/templates/invoices/lib/billing.ts +40 -0
  434. package/templates/invoices/lib/brand.ts +9 -0
  435. package/templates/invoices/lib/search.ts +4 -3
  436. package/templates/invoices/public/favicon.ico +0 -0
  437. package/templates/invoices/tests/billing.test.ts +27 -0
  438. package/templates/ios/consumer/apps/ios/Package.swift +4 -3
  439. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/ActivityView.swift +107 -0
  440. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/AppModel.swift +171 -0
  441. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/AuthView.swift +182 -0
  442. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/CommentsView.swift +136 -0
  443. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/ComposeView.swift +152 -0
  444. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/ExploreView.swift +117 -0
  445. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/FeedView.swift +175 -159
  446. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/MainTabView.swift +54 -0
  447. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/Media.swift +271 -0
  448. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/Models.swift +101 -4
  449. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/PostCard.swift +245 -0
  450. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/ProfileEditorView.swift +208 -0
  451. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/ProfileView.swift +183 -0
  452. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/RootView.swift +25 -31
  453. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/SocialStore.swift +285 -0
  454. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/StoryViewer.swift +155 -0
  455. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/Theme.swift +82 -0
  456. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/__APP_NAME_PASCAL__App.swift +4 -47
  457. package/templates/ios/consumer/apps/ios/project.yml +13 -9
  458. package/templates/local-service/.env.example +7 -0
  459. package/templates/local-service/AGENTS.md +1 -1
  460. package/templates/local-service/README.md +26 -2
  461. package/templates/local-service/app/(marketing)/booking-widget.tsx +48 -9
  462. package/templates/local-service/app/(marketing)/page.tsx +66 -42
  463. package/templates/local-service/app/auth-form.tsx +8 -8
  464. package/templates/local-service/app/dashboard/dashboard-client.tsx +119 -92
  465. package/templates/local-service/app/dashboard/page.tsx +14 -14
  466. package/templates/local-service/app/icon.svg +2 -0
  467. package/templates/local-service/app/login/page.tsx +15 -15
  468. package/templates/local-service/functions/seedDemo.ts +49 -0
  469. package/templates/local-service/lib/demo.ts +135 -0
  470. package/templates/local-service/lib/hours.ts +44 -0
  471. package/templates/local-service/lib/site.config.ts +8 -3
  472. package/templates/local-service/lib/slots.ts +3 -0
  473. package/templates/local-service/public/favicon.ico +0 -0
  474. package/templates/local-service/tests/booking.test.ts +104 -0
  475. package/templates/marketplace/AGENTS.md +1 -1
  476. package/templates/marketplace/README.md +23 -15
  477. package/templates/marketplace/app/globals.css +172 -114
  478. package/templates/marketplace/app/layout.tsx +75 -30
  479. package/templates/marketplace/app/listing/[id]/page.tsx +210 -123
  480. package/templates/marketplace/app/me/page.tsx +4 -4
  481. package/templates/marketplace/app/page.tsx +221 -298
  482. package/templates/marketplace/app/sell/page.tsx +8 -11
  483. package/templates/marketplace/app.ts +32 -7
  484. package/templates/marketplace/client/ActivityFeed.tsx +311 -0
  485. package/templates/marketplace/client/AuthNav.tsx +24 -16
  486. package/templates/marketplace/client/ListingCard.tsx +118 -0
  487. package/templates/marketplace/client/LiveGrid.tsx +92 -0
  488. package/templates/marketplace/client/LiveListingStatus.tsx +32 -24
  489. package/templates/marketplace/client/LoginCard.tsx +114 -136
  490. package/templates/marketplace/client/MarketProvider.tsx +3 -5
  491. package/templates/marketplace/client/MyMarket.tsx +371 -185
  492. package/templates/marketplace/client/OfferPanel.tsx +421 -287
  493. package/templates/marketplace/client/SellForm.tsx +271 -192
  494. package/templates/marketplace/client/ThemeToggle.tsx +1 -0
  495. package/templates/marketplace/client/WatchButton.tsx +16 -16
  496. package/templates/marketplace/client/market.ts +61 -14
  497. package/templates/marketplace/functions/seedMarket.ts +143 -36
  498. package/templates/marketplace/functions/seedOffers.ts +101 -0
  499. package/templates/marketplace/lib/catalog.ts +72 -1
  500. package/templates/marketplace/public/images/listings/ceramic-lamp-640.webp +0 -0
  501. package/templates/marketplace/public/images/listings/ceramic-lamp.webp +0 -0
  502. package/templates/marketplace/public/images/listings/duffel-640.webp +0 -0
  503. package/templates/marketplace/public/images/listings/duffel.webp +0 -0
  504. package/templates/marketplace/public/images/listings/film-camera-640.webp +0 -0
  505. package/templates/marketplace/public/images/listings/film-camera.webp +0 -0
  506. package/templates/marketplace/public/images/listings/lounge-chair-640.webp +0 -0
  507. package/templates/marketplace/public/images/listings/lounge-chair.webp +0 -0
  508. package/templates/marketplace/public/images/listings/road-bike-640.webp +0 -0
  509. package/templates/marketplace/public/images/listings/road-bike.webp +0 -0
  510. package/templates/marketplace/public/images/listings/slipper-chair-640.webp +0 -0
  511. package/templates/marketplace/public/images/listings/slipper-chair.webp +0 -0
  512. package/templates/marketplace/public/images/listings/turntable-640.webp +0 -0
  513. package/templates/marketplace/public/images/listings/turntable.webp +0 -0
  514. package/templates/marketplace/public/images/listings/wardrobe-640.webp +0 -0
  515. package/templates/marketplace/public/images/listings/wardrobe.webp +0 -0
  516. package/templates/marketplace/public/images/listings/watch-640.webp +0 -0
  517. package/templates/marketplace/public/images/listings/watch.webp +0 -0
  518. package/templates/marketplace/public/images/listings/weekender-bag-640.webp +0 -0
  519. package/templates/marketplace/public/images/listings/weekender-bag.webp +0 -0
  520. package/templates/marketplace/tests/example.test.ts +64 -2
  521. package/templates/marketplace/tests/listing-card.test.tsx +61 -0
  522. package/templates/projects/AGENTS.md +1 -1
  523. package/templates/projects/README.md +24 -3
  524. package/templates/projects/app/apple-icon.png +0 -0
  525. package/templates/projects/app/clients/clients-view.tsx +20 -6
  526. package/templates/projects/app/clients/page.tsx +2 -1
  527. package/templates/projects/app/globals.css +29 -14
  528. package/templates/projects/app/icon.svg +1 -0
  529. package/templates/projects/app/layout.tsx +7 -5
  530. package/templates/projects/app/page.tsx +3 -5
  531. package/templates/projects/app/projects/[id]/page.tsx +2 -1
  532. package/templates/projects/app/projects/[id]/project-view.tsx +45 -30
  533. package/templates/projects/app/projects-view.tsx +105 -52
  534. package/templates/projects/app/workspace.tsx +41 -20
  535. package/templates/projects/app.ts +2 -2
  536. package/templates/projects/components/app-shell.tsx +94 -0
  537. package/templates/projects/components/auth-form.tsx +35 -5
  538. package/templates/projects/components/avatar.tsx +5 -1
  539. package/templates/projects/components/board-skeleton.tsx +3 -3
  540. package/templates/projects/components/brand-mark.tsx +25 -0
  541. package/templates/projects/components/command-palette.tsx +17 -17
  542. package/templates/projects/components/data-table.tsx +97 -36
  543. package/templates/projects/components/filter-tabs.tsx +101 -0
  544. package/templates/projects/components/meter.tsx +48 -0
  545. package/templates/projects/components/nav.tsx +14 -0
  546. package/templates/projects/components/page-header.tsx +43 -7
  547. package/templates/projects/components/require-auth.tsx +24 -26
  548. package/templates/projects/components/sidebar.tsx +54 -48
  549. package/templates/projects/components/summary-bar.tsx +49 -0
  550. package/templates/projects/components/task-board.tsx +10 -9
  551. package/templates/projects/components/time-dialog.tsx +29 -5
  552. package/templates/projects/components/ui/button.tsx +5 -4
  553. package/templates/projects/components/ui/dialog.tsx +1 -1
  554. package/templates/projects/components/ui/input.tsx +1 -1
  555. package/templates/projects/components/ui/select.tsx +1 -1
  556. package/templates/projects/components/ui/textarea.tsx +1 -1
  557. package/templates/projects/functions/seedWorkspace.ts +26 -12
  558. package/templates/projects/lib/brand.ts +9 -0
  559. package/templates/projects/lib/demo-team.ts +51 -0
  560. package/templates/projects/lib/search.ts +4 -3
  561. package/templates/projects/lib/seed.ts +35 -1
  562. package/templates/projects/lib/work.ts +63 -0
  563. package/templates/projects/public/favicon.ico +0 -0
  564. package/templates/projects/tests/demo-team.test.ts +18 -0
  565. package/templates/projects/tests/work.test.ts +65 -0
  566. package/templates/restaurant/.env.example +7 -0
  567. package/templates/restaurant/AGENTS.md +1 -1
  568. package/templates/restaurant/README.md +29 -3
  569. package/templates/restaurant/app/(marketing)/layout.tsx +4 -2
  570. package/templates/restaurant/app/(marketing)/page.tsx +47 -23
  571. package/templates/restaurant/app/(marketing)/reservation-widget.tsx +37 -7
  572. package/templates/restaurant/app/auth-form.tsx +8 -8
  573. package/templates/restaurant/app/dashboard/dashboard-client.tsx +241 -109
  574. package/templates/restaurant/app/dashboard/page.tsx +14 -14
  575. package/templates/restaurant/app/icon.svg +4 -0
  576. package/templates/restaurant/app/login/page.tsx +15 -15
  577. package/templates/restaurant/functions/seedDemo.ts +44 -0
  578. package/templates/restaurant/lib/demo.ts +144 -0
  579. package/templates/restaurant/lib/hours.ts +45 -0
  580. package/templates/restaurant/lib/site.config.ts +3 -3
  581. package/templates/restaurant/public/favicon.ico +0 -0
  582. package/templates/restaurant/tests/reservations.test.ts +67 -0
  583. package/templates/saas/AGENTS.md +1 -1
  584. package/templates/saas/README.md +54 -35
  585. package/templates/saas/app/(auth)/auth-form.tsx +25 -23
  586. package/templates/saas/app/(auth)/forgot-password/page.tsx +1 -1
  587. package/templates/saas/app/(auth)/layout.tsx +27 -33
  588. package/templates/saas/app/(auth)/login/page.tsx +1 -1
  589. package/templates/saas/app/(auth)/reset-password/page.tsx +1 -1
  590. package/templates/saas/app/(auth)/signup/page.tsx +1 -1
  591. package/templates/saas/app/(marketing)/layout.tsx +127 -253
  592. package/templates/saas/app/(marketing)/page.tsx +133 -372
  593. package/templates/saas/app/(marketing)/pricing/page.tsx +21 -19
  594. package/templates/saas/app/(marketing)/products/[slug]/page.tsx +40 -95
  595. package/templates/saas/app/dashboard/board-client.tsx +416 -0
  596. package/templates/saas/app/dashboard/dashboard-client.tsx +30 -615
  597. package/templates/saas/app/dashboard/layout.tsx +27 -13
  598. package/templates/saas/app/dashboard/overview-client.tsx +332 -0
  599. package/templates/saas/app/dashboard/page.tsx +29 -35
  600. package/templates/saas/app/dashboard/projects/[id]/page.tsx +29 -0
  601. package/templates/saas/app/dashboard/projects/page.tsx +11 -7
  602. package/templates/saas/app/dashboard/projects-client.tsx +398 -0
  603. package/templates/saas/app/globals.css +5 -4
  604. package/templates/saas/app/icon.svg +1 -0
  605. package/templates/saas/app/onboarding/onboarding-client.tsx +93 -26
  606. package/templates/saas/app/onboarding/page.tsx +6 -2
  607. package/templates/saas/app.ts +68 -13
  608. package/templates/saas/components/dashboard-shell.tsx +212 -132
  609. package/templates/saas/components/marketing.tsx +137 -274
  610. package/templates/saas/components/pricing-table.tsx +12 -11
  611. package/templates/saas/components/setup-checklist.tsx +31 -29
  612. package/templates/saas/components/task-ui.tsx +199 -0
  613. package/templates/saas/functions/createProject.ts +7 -13
  614. package/templates/saas/functions/createTask.ts +67 -0
  615. package/templates/saas/functions/deleteProject.ts +17 -0
  616. package/templates/saas/functions/deleteTask.ts +14 -0
  617. package/templates/saas/functions/seedWorkspace.ts +46 -0
  618. package/templates/saas/functions/setProjectStatus.ts +41 -0
  619. package/templates/saas/functions/updateProfile.ts +13 -0
  620. package/templates/saas/functions/updateProject.ts +4 -5
  621. package/templates/saas/functions/updateTask.ts +88 -0
  622. package/templates/saas/lib/members.ts +53 -0
  623. package/templates/saas/lib/names.ts +53 -0
  624. package/templates/saas/lib/plans.ts +11 -0
  625. package/templates/saas/lib/sample-workspace.ts +117 -0
  626. package/templates/saas/lib/site.config.ts +200 -463
  627. package/templates/saas/lib/tasks.ts +101 -0
  628. package/templates/saas/lib/use-live.ts +25 -0
  629. package/templates/saas/public/favicon.ico +0 -0
  630. package/templates/saas/public/screenshots/board.png +0 -0
  631. package/templates/saas/public/screenshots/members.png +0 -0
  632. package/templates/saas/public/screenshots/overview.png +0 -0
  633. package/templates/saas/public/screenshots/projects.png +0 -0
  634. package/templates/saas/scripts/capture-screenshots.mjs +156 -0
  635. package/templates/saas/tests/names.test.ts +35 -0
  636. package/templates/saas/tests/plans.test.ts +12 -0
  637. package/templates/saas/tests/sample-workspace.test.ts +46 -0
  638. package/templates/saas/tests/tasks.test.ts +81 -0
  639. package/templates/shop/AGENTS.md +1 -1
  640. package/templates/shop/README.md +25 -13
  641. package/templates/shop/app/(marketing)/layout.tsx +94 -67
  642. package/templates/shop/app/(marketing)/not-found.tsx +13 -12
  643. package/templates/shop/app/(marketing)/page.tsx +120 -59
  644. package/templates/shop/app/(marketing)/shop-client.tsx +364 -237
  645. package/templates/shop/app/(marketing)/success/page.tsx +75 -22
  646. package/templates/shop/app/globals.css +94 -1
  647. package/templates/shop/app/layout.tsx +4 -4
  648. package/templates/shop/app/login/page.tsx +4 -4
  649. package/templates/shop/app.ts +18 -6
  650. package/templates/shop/components/cart-button.tsx +33 -0
  651. package/templates/shop/components/marketing.tsx +17 -87
  652. package/templates/shop/components/shelf-count.tsx +36 -0
  653. package/templates/shop/functions/checkout.ts +17 -1
  654. package/templates/shop/lib/cart-store.ts +57 -0
  655. package/templates/shop/lib/shelf-store.ts +35 -0
  656. package/templates/shop/lib/shop.ts +27 -0
  657. package/templates/shop/lib/site.config.ts +108 -98
  658. package/templates/shop/public/images/hero.jpg +0 -0
  659. package/templates/shop/public/images/products/cedar-smoke.jpg +0 -0
  660. package/templates/shop/public/images/products/fig-leaf.jpg +0 -0
  661. package/templates/shop/public/images/products/linen.jpg +0 -0
  662. package/templates/shop/public/images/products/sea-salt.jpg +0 -0
  663. package/templates/shop/public/images/products/tobacco-oak.jpg +0 -0
  664. package/templates/shop/tests/shop.test.ts +64 -0
  665. package/templates/todo/AGENTS.md +1 -1
  666. package/templates/waitlist/.env.example +7 -0
  667. package/templates/waitlist/AGENTS.md +1 -1
  668. package/templates/waitlist/README.md +29 -13
  669. package/templates/waitlist/app/(marketing)/page.tsx +9 -7
  670. package/templates/waitlist/app/(marketing)/waitlist-hero.tsx +64 -31
  671. package/templates/waitlist/app/auth-form.tsx +8 -8
  672. package/templates/waitlist/app/dashboard/dashboard-client.tsx +132 -95
  673. package/templates/waitlist/app/dashboard/page.tsx +17 -16
  674. package/templates/waitlist/app/icon.svg +2 -0
  675. package/templates/waitlist/app/login/page.tsx +14 -14
  676. package/templates/waitlist/app.ts +6 -6
  677. package/templates/waitlist/functions/joinWaitlist.ts +6 -18
  678. package/templates/waitlist/functions/seedDemo.ts +32 -0
  679. package/templates/waitlist/lib/demo.ts +94 -0
  680. package/templates/waitlist/lib/launch.ts +19 -0
  681. package/templates/waitlist/lib/site.config.ts +14 -9
  682. package/templates/waitlist/lib/stats.ts +35 -0
  683. package/templates/waitlist/public/favicon.ico +0 -0
  684. package/templates/waitlist/tests/counter.test.ts +107 -0
  685. package/templates/waitlist/tests/live-count.test.tsx +48 -0
  686. package/templates/ai-chat/tests/example.test.ts +0 -12
  687. package/templates/backend/consumer/apps/api/functions/feed.ts +0 -57
  688. package/templates/backend/consumer/apps/api/functions/profilePosts.ts +0 -17
  689. package/templates/backend/consumer/apps/api/functions/toggleLike.ts +0 -48
  690. package/templates/backend/consumer/apps/api/schema.ts +0 -143
  691. package/templates/chat/functions/_keep.ts +0 -13
  692. package/templates/chat/tests/example.test.ts +0 -12
  693. package/templates/ios/consumer/apps/ios/Sources/__APP_NAME_PASCAL__/ProfileSetupView.swift +0 -68
  694. package/templates/marketplace/client/LiveTicker.tsx +0 -116
  695. package/templates/marketplace/client/ScrollToListingsLink.tsx +0 -29
  696. package/templates/marketplace/public/images/marketplace-hero.webp +0 -0
@@ -20,6 +20,14 @@
20
20
  },
21
21
  "web": {
22
22
  "bundler": "metro"
23
- }
23
+ },
24
+ "plugins": [
25
+ [
26
+ "expo-image-picker",
27
+ {
28
+ "photosPermission": "Choose photos from your library to share."
29
+ }
30
+ ]
31
+ ]
24
32
  }
25
33
  }
@@ -11,13 +11,14 @@
11
11
  "web": "expo start --web"
12
12
  },
13
13
  "dependencies": {
14
- "@pylonsync/sdk": "^__PYLON_VERSION__",
15
14
  "@pylonsync/react": "^__PYLON_VERSION__",
16
15
  "@pylonsync/react-native": "^__PYLON_VERSION__",
16
+ "@pylonsync/sdk": "^__PYLON_VERSION__",
17
17
  "@pylonsync/sync": "^__PYLON_VERSION__",
18
18
  "@react-native-async-storage/async-storage": "2.2.0",
19
19
  "@react-native-community/netinfo": "~12.0.0",
20
20
  "expo": "~56.0.0",
21
+ "expo-image-picker": "~56.0.25",
21
22
  "expo-status-bar": "~56.0.0",
22
23
  "react": "19.2.0",
23
24
  "react-dom": "19.2.0",
@@ -62,7 +62,7 @@ this pass before the user has to ask.
62
62
  - **`serverData` (SSR) is READ-ONLY.** No write methods; the runtime rejects write frames (`SSR_WRITE_FORBIDDEN`). Mutations belong in actions/functions, never in a page render.
63
63
  - **`response.*` / `response.redirect()` / `response.notFound()` must fire in the synchronous shell render**, before any `await` / `<Suspense>`. The HTTP head commits when the shell is ready; status/headers/cookies set from a suspended subtree are lost, and `redirect`/`notFound` thrown below a Suspense boundary are swallowed.
64
64
  - **`ctx.llm`, `ctx.rooms`, and `ctx.connections` are on mutation + action only, NOT query** (reactive purity). `action` has no direct `ctx.db`; use `ctx.runQuery` / `ctx.runMutation`.
65
- - **`ctx.llm.stream(request, onEvent)` streams tokens as they generate** and still resolves with the full response, so `stop_reason === "tool_use"` drives an agent tool loop. Events are `text_delta` / `tool_use_start` / `tool_input_delta` / `done`. Same auth + model-allowlist gating as `ctx.llm.complete`. Streaming does NOT extend the call deadline (`PYLON_FN_CALL_TIMEOUT`, 30s default) — set `timeout: <secs>` on the def for a long run.
65
+ - **`ctx.llm.stream(request, onEvent)` streams tokens as they generate** and still resolves with the full response, so `stop_reason === "tool_use"` drives an agent tool loop. Events are `text_delta` / `tool_use_start` / `tool_input_delta` / `done`. Same auth + model-allowlist gating as `ctx.llm.complete`. The call timeout is an idle timeout (`PYLON_FN_CALL_TIMEOUT`, 30s default; Stack0 Cloud 300s): each stream event resets it, and the total run is capped at 10× the timeout. Set `timeout: <secs>` on the def when a step (a slow tool call) can be silent longer than that.
66
66
  - **`ctx.stream.write(text)` streams to the caller — and every fn stream is RESUMABLE**: the server buffers frames under a stream id (`streamFn`'s `onStreamId`), so a dropped connection or closed tab catches up via `resumeStream(id)`, including the final result after the handler finished. `ctx.rooms.broadcast(room, topic, data)` fans out to every CURRENTLY-CONNECTED subscriber (second device, second tab) but does not replay missed messages — use the stream id for anything that must survive a gap. Broadcast resolves `{ delivered: false }` when the room has no members — a no-op, not an error. Clients receive with `useRoomMessages(room, cb)` from `@pylonsync/react`; `useRoom` is the send side.
67
67
  - **It's `db.useQueryOne`, not `useOne`.** Validators and field types have aliases: `v.bool`/`v.boolean`, `v.float`/`v.number`.
68
68
  - **Use the supported file and scheduling APIs.** Files go through `<FileUpload>` and `/api/files/*`; an upload is readable by its uploader only, so pass `visibility: "public"` to `uploadFile` or `<FileUpload>` for files every visitor sees; there is no `ctx.files`. One-shot work uses `ctx.scheduler.runAfter`, `runAt`, or `cancel`; there is no `defineWorkflow` or `defineJob`. Recurring work uses `cron("0 * * * *", "fnName")` in `buildManifest({ crons: [...] })`, imported from `@pylonsync/sdk`. Make the target function `internal: true`. It runs with anonymous auth, but its own `ctx.db.*` calls are server-side and bypass policies. Use `ctx.auth.elevate({ admin: true, reason: "..." })`, with a mandatory reason, only when chaining another internal function through `ctx.scheduler`.
@@ -15,6 +15,11 @@ realistic queue — including one urgent ticket already past its first-response
15
15
  window, so the breach state is visible rather than theoretical. Delete
16
16
  `functions/seedWorkspace.ts` and `lib/seed.ts` once real tickets arrive.
17
17
 
18
+ The tickets are spread across you and four demo teammates. Each is a User
19
+ row with a `@demo.invalid` address and no password, so outside dev mode nobody
20
+ can sign in as one (see `lib/demo-team.ts`). Delete those users along with the
21
+ seed.
22
+
18
23
  ## What's interesting here
19
24
 
20
25
  **The queue answers "what next".** Rows are ordered by `queueOrder` in
@@ -37,6 +42,22 @@ the note stays marked in the thread, and — deliberately — an internal note d
37
42
  **not** stop the SLA clock. A team that could clear its SLA by talking to itself
38
43
  would have an SLA worth nothing.
39
44
 
45
+ ## Brand and layout
46
+
47
+ The product ships as **Frontdesk**. The name lives in `lib/brand.ts`, and the
48
+ sidebar, sign-in screen, page titles, and phone drawer all read it. The mark is
49
+ `components/brand-mark.tsx`; `app/icon.svg`, `app/apple-icon.png`, and
50
+ `public/favicon.ico` draw the same shape for browsers and home screens. The
51
+ accent colour is `--brand` at the top of `app/globals.css`, and the typeface
52
+ (Public Sans) is set in `fonts` in `app.ts`.
53
+
54
+ The frame is `components/app-shell.tsx`. From 768px up the sidebar is a fixed
55
+ rail; below that it opens as a drawer from the menu button in each page header,
56
+ tables drop their lower-priority columns (`hideBelow` in
57
+ `components/data-table.tsx`), and boards scroll one column at a time. The nav
58
+ links are in `components/nav.tsx`. Every nav count comes from `navCounts` in
59
+ `app/workspace.tsx`, and page headers and tabs read the same numbers.
60
+
40
61
  ## Layout
41
62
 
42
63
  ```
@@ -19,7 +19,7 @@ export function CustomersView() {
19
19
  const [open, setOpen] = useState(false);
20
20
 
21
21
  return (
22
- <RequireAuth title="Helpdesk" description="Your team shares one queue. Anyone with an account sees it.">
22
+ <RequireAuth>
23
23
  <Workspace pathname="/customers">
24
24
  {(data) => {
25
25
  // Ticket counts per customer, derived rather than stored — one less
@@ -33,16 +33,23 @@ export function CustomersView() {
33
33
  {
34
34
  key: "name",
35
35
  header: "Customer",
36
+ className: "w-[62%] md:w-[24%]",
36
37
  cell: (row) => (
37
- <span className="flex items-center gap-2">
38
- <Avatar name={row.name} size="sm" />
39
- <span className="truncate font-medium">{row.name}</span>
38
+ <span className="flex min-w-0 items-center gap-2.5">
39
+ <Avatar name={row.name} />
40
+ <span className="min-w-0">
41
+ <span className="block truncate font-medium">{row.name}</span>
42
+ <span className="block truncate text-[12px] text-muted-foreground md:hidden">
43
+ {row.company ?? row.email}
44
+ </span>
45
+ </span>
40
46
  </span>
41
47
  ),
42
48
  },
43
49
  {
44
50
  key: "company",
45
51
  header: "Company",
52
+ hideBelow: "md",
46
53
  cell: (row) => (
47
54
  <span className="text-muted-foreground">{row.company ?? "—"}</span>
48
55
  ),
@@ -50,6 +57,8 @@ export function CustomersView() {
50
57
  {
51
58
  key: "email",
52
59
  header: "Email",
60
+ hideBelow: "lg",
61
+ className: "w-[26%]",
53
62
  cell: (row) => (
54
63
  <a
55
64
  href={`mailto:${row.email}`}
@@ -62,19 +71,24 @@ export function CustomersView() {
62
71
  },
63
72
  {
64
73
  key: "open",
65
- header: "Open",
74
+ header: "Unresolved",
66
75
  numeric: true,
76
+ className: "w-[104px]",
67
77
  cell: (row) => openCount(row.id),
68
78
  },
69
79
  {
70
80
  key: "total",
71
81
  header: "Total",
72
82
  numeric: true,
83
+ hideBelow: "sm",
84
+ className: "w-[80px]",
73
85
  cell: (row) => totalCount(row.id),
74
86
  },
75
87
  {
76
88
  key: "created",
77
89
  header: "Added",
90
+ hideBelow: "xl",
91
+ className: "w-[100px]",
78
92
  cell: (row) => (
79
93
  <span className="text-muted-foreground">
80
94
  {relativeTime(row.createdAt)}
@@ -87,16 +101,18 @@ export function CustomersView() {
87
101
 
88
102
  return (
89
103
  <>
90
- <PageHeader title="Customers" count={rows.length}>
104
+ <PageHeader title="Customers" count={data.navCounts["/customers"]}>
91
105
  <Button size="sm" onClick={() => setOpen(true)}>
92
106
  <Plus />
93
- New customer
107
+ <span className="max-sm:sr-only">New customer</span>
94
108
  </Button>
95
109
  </PageHeader>
96
110
 
97
111
  <DataTable
98
112
  rows={rows}
99
113
  columns={columns}
114
+ loading={data.loading}
115
+ label="Customers"
100
116
  empty={
101
117
  <EmptyState
102
118
  icon={<Users />}
@@ -1,9 +1,10 @@
1
1
  import React from "react";
2
2
  import type { Metadata, PageProps } from "@pylonsync/react";
3
+ import { BRAND } from "@/lib/brand";
3
4
  import { CustomersView } from "./customers-view";
4
5
 
5
6
  export const metadata: Metadata = {
6
- title: "Customers",
7
+ title: `Customers · ${BRAND.name}`,
7
8
  robots: "noindex",
8
9
  };
9
10
 
@@ -9,15 +9,21 @@
9
9
  /* ---------------------------------------------------------------------------
10
10
  Design tokens.
11
11
 
12
- Tuned for a dense internal tool rather than a marketing page: a near-neutral
13
- surface ramp, hairline borders instead of shadows, and one accent used
14
- sparingly so status colour still means something. Dark is the primary theme —
15
- `app/layout.tsx` sets `class="dark"` — and light is a real, tested
16
- alternative, not an afterthought.
12
+ Tuned for a dense internal tool: a near-neutral surface ramp, hairline
13
+ borders instead of shadows, and one accent used sparingly so status colour
14
+ still means something. Light is the default; `.dark` holds a complete dark
15
+ set (add `class="dark"` to <html> in app/layout.tsx to switch).
17
16
 
18
- These are the same variable names shadcn/ui generates against, so
17
+ These are the variable names shadcn/ui generates against, so
19
18
  `npx shadcn@latest add <component>` drops in already themed.
20
19
  --------------------------------------------------------------------------- */
20
+ :root {
21
+ /* The brand accent: primary buttons, the brand mark, focus rings, and the
22
+ active nav icon. Change these two lines to re-colour the product. */
23
+ --brand: oklch(0.53 0.1 195);
24
+ --brand-dark: oklch(0.66 0.1 195);
25
+ }
26
+
21
27
  :root {
22
28
  --radius: 0.5rem;
23
29
 
@@ -28,7 +34,7 @@
28
34
  --popover: oklch(1 0 0);
29
35
  --popover-foreground: var(--foreground);
30
36
 
31
- --primary: oklch(0.55 0.204 274.5);
37
+ --primary: var(--brand);
32
38
  --primary-foreground: oklch(1 0 0);
33
39
  --secondary: oklch(0.968 0.002 286.4);
34
40
  --secondary-foreground: oklch(0.27 0.006 286);
@@ -40,7 +46,7 @@
40
46
 
41
47
  --border: oklch(0.918 0.004 286.3);
42
48
  --input: oklch(0.918 0.004 286.3);
43
- --ring: oklch(0.55 0.204 274.5);
49
+ --ring: var(--brand);
44
50
 
45
51
  /* Surfaces above the page: sidebar, popovers, hover rows. */
46
52
  --surface-1: oklch(0.985 0.001 286.4);
@@ -51,6 +57,7 @@
51
57
  --stage-lead: oklch(0.62 0.03 264);
52
58
  --stage-qualified: oklch(0.6 0.13 240);
53
59
  --stage-proposal: oklch(0.68 0.15 78);
60
+ --stage-negotiation: oklch(0.64 0.16 45);
54
61
  --stage-won: oklch(0.6 0.15 155);
55
62
  --stage-lost: oklch(0.6 0.11 25);
56
63
  }
@@ -63,7 +70,7 @@
63
70
  --popover: oklch(0.216 0.006 285.9);
64
71
  --popover-foreground: var(--foreground);
65
72
 
66
- --primary: oklch(0.62 0.19 274.5);
73
+ --primary: var(--brand-dark);
67
74
  --primary-foreground: oklch(1 0 0);
68
75
  --secondary: oklch(0.25 0.006 286);
69
76
  --secondary-foreground: oklch(0.93 0.002 286.3);
@@ -75,7 +82,7 @@
75
82
 
76
83
  --border: oklch(1 0 0 / 9%);
77
84
  --input: oklch(1 0 0 / 12%);
78
- --ring: oklch(0.62 0.19 274.5);
85
+ --ring: var(--brand-dark);
79
86
 
80
87
  --surface-1: oklch(0.186 0.004 285.9);
81
88
  --surface-2: oklch(0.216 0.006 285.9);
@@ -83,6 +90,7 @@
83
90
  --stage-lead: oklch(0.68 0.03 264);
84
91
  --stage-qualified: oklch(0.68 0.13 240);
85
92
  --stage-proposal: oklch(0.75 0.14 78);
93
+ --stage-negotiation: oklch(0.72 0.15 45);
86
94
  --stage-won: oklch(0.7 0.15 155);
87
95
  --stage-lost: oklch(0.68 0.14 25);
88
96
  }
@@ -118,6 +126,7 @@
118
126
  --color-stage-lead: var(--stage-lead);
119
127
  --color-stage-qualified: var(--stage-qualified);
120
128
  --color-stage-proposal: var(--stage-proposal);
129
+ --color-stage-negotiation: var(--stage-negotiation);
121
130
  --color-stage-won: var(--stage-won);
122
131
  --color-stage-lost: var(--stage-lost);
123
132
  }
@@ -143,15 +152,21 @@
143
152
  height: 100%;
144
153
  background-color: var(--color-background);
145
154
  color: var(--color-foreground);
146
- /* 13px is the density these screens are designed at; the slight negative
147
- tracking is what keeps Inter from looking loose at that size. */
148
- font-size: 13px;
155
+ /* 14px on phones, 13px from the md breakpoint up: the density these
156
+ screens are designed at on a desktop. */
157
+ font-size: 14px;
149
158
  line-height: 1.5;
150
- letter-spacing: -0.006em;
159
+ letter-spacing: -0.003em;
151
160
  -webkit-font-smoothing: antialiased;
152
161
  text-rendering: optimizeLegibility;
153
162
  }
154
163
 
164
+ @media (min-width: 768px) {
165
+ body {
166
+ font-size: 13px;
167
+ }
168
+ }
169
+
155
170
  button {
156
171
  cursor: pointer;
157
172
  }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="8" fill="#007d7e"/><path d="M9 7h14a3.5 3.5 0 0 1 3.5 3.5v7.5a3.5 3.5 0 0 1-3.5 3.5h-6.5L11.5 25v-3.5H9A3.5 3.5 0 0 1 5.5 18v-7.5A3.5 3.5 0 0 1 9 7Z" fill="#fff"/><rect x="10" y="11.3" width="12" height="2.4" rx="1.2" fill="#007d7e"/><rect x="10" y="15.3" width="7.5" height="2.4" rx="1.2" fill="#007d7e"/></svg>
@@ -2,15 +2,21 @@
2
2
 
3
3
  import React, { useEffect, useState } from "react";
4
4
  import { callFn, useRouter } from "@pylonsync/react";
5
- import { Inbox, Plus } from "lucide-react";
5
+ import { Inbox, Plus, UserX } from "lucide-react";
6
6
  import { Button } from "@/components/ui/button";
7
- import { Select } from "@/components/ui/select";
8
7
  import { Kbd } from "@/components/kbd";
9
8
  import { PageHeader } from "@/components/page-header";
10
9
  import { EmptyState } from "@/components/empty-state";
11
- import { TicketList } from "@/components/ticket-list";
10
+ import { TicketList, TicketListSkeleton } from "@/components/ticket-list";
12
11
  import { NewTicketDialog } from "@/components/new-ticket-dialog";
13
- import { STATUSES, applyFilter, counts, type Filter } from "@/lib/tickets";
12
+ import { FilterTabs } from "@/components/filter-tabs";
13
+ import {
14
+ DEFAULT_INBOX_TAB,
15
+ INBOX_TABS,
16
+ applyFilter,
17
+ inboxCount,
18
+ inboxFilter,
19
+ } from "@/lib/tickets";
14
20
  import { RequireAuth } from "@/components/require-auth";
15
21
  import { Workspace } from "./workspace";
16
22
 
@@ -23,9 +29,18 @@ export function InboxView({
23
29
  }) {
24
30
  const router = useRouter();
25
31
  const [dialogOpen, setDialogOpen] = useState(Boolean(openNew));
26
- const [status, setStatus] = useState<string>("open");
32
+ const [tab, setTab] = useState<string>(DEFAULT_INBOX_TAB);
27
33
  const [unassigned, setUnassigned] = useState(initialFilter === "unassigned");
28
34
 
35
+ // ⌘K "Unassigned open tickets" navigates here with ?filter=unassigned while
36
+ // the inbox may already be mounted.
37
+ useEffect(() => {
38
+ if (initialFilter === "unassigned") {
39
+ setTab(DEFAULT_INBOX_TAB);
40
+ setUnassigned(true);
41
+ }
42
+ }, [initialFilter]);
43
+
29
44
  // "c" opens a ticket, the way an issue tracker does. Ignored while typing so
30
45
  // it never swallows a character in the reply box.
31
46
  useEffect(() => {
@@ -46,66 +61,69 @@ export function InboxView({
46
61
  }, []);
47
62
 
48
63
  return (
49
- <RequireAuth title="Helpdesk" description="Your team shares one queue. Anyone with an account sees it.">
64
+ <RequireAuth>
50
65
  <Workspace pathname="/">
51
66
  {(data) => {
52
- const filter: Filter = {
53
- ...(status === "all" ? {} : { status }),
54
- ...(unassigned ? { unassigned: true } : {}),
55
- };
56
- const visible = applyFilter(data.tickets, filter);
57
- const queue = counts(data.tickets);
67
+ const visible = applyFilter(data.tickets, inboxFilter(tab, unassigned));
58
68
 
59
69
  return (
60
70
  <>
61
- <PageHeader title="Inbox" count={visible.length}>
62
- <div className="w-32">
63
- <Select
64
- aria-label="Status"
65
- value={status}
66
- onChange={(event) => setStatus(event.target.value)}
67
- className="h-7 text-[12px]"
68
- >
69
- <option value="all">All statuses</option>
70
- {STATUSES.map((s) => (
71
- <option key={s.id} value={s.id}>
72
- {s.label}
73
- </option>
74
- ))}
75
- </Select>
76
- </div>
77
- <Button
78
- size="sm"
79
- variant={unassigned ? "default" : "secondary"}
80
- onClick={() => setUnassigned((on) => !on)}
81
- title="Show only tickets with no agent"
82
- >
83
- Unassigned
84
- <span className="tabular ml-1 opacity-70">{queue.unassigned}</span>
85
- </Button>
86
- <Button size="sm" onClick={() => setDialogOpen(true)}>
71
+ <PageHeader title="Inbox" count={data.navCounts["/"]}>
72
+ <Button size="sm" onClick={() => setDialogOpen(true)} title="New ticket (c)">
87
73
  <Plus />
88
74
  New ticket
89
- <Kbd className="ml-1 border-primary-foreground/25 bg-primary-foreground/10 text-primary-foreground/70">
90
- c
75
+ <Kbd className="ml-0.5 hidden border-primary-foreground/25 bg-primary-foreground/10 text-primary-foreground/75 md:inline-flex">
76
+ C
91
77
  </Kbd>
92
78
  </Button>
93
79
  </PageHeader>
94
80
 
95
- {visible.length === 0 ? (
81
+ <FilterTabs
82
+ label="Ticket status"
83
+ value={tab}
84
+ onChange={setTab}
85
+ tabs={INBOX_TABS.map((t) => ({
86
+ id: t.id,
87
+ label: t.label,
88
+ count: inboxCount(data.tickets, t.id, unassigned),
89
+ }))}
90
+ trailing={
91
+ <button
92
+ type="button"
93
+ aria-pressed={unassigned}
94
+ onClick={() => setUnassigned((on) => !on)}
95
+ title="Show only tickets with no agent"
96
+ className={
97
+ "flex h-7 items-center gap-1.5 rounded-md border px-2.5 text-[12.5px] transition-colors " +
98
+ (unassigned
99
+ ? "border-primary/40 bg-primary/10 font-medium text-primary"
100
+ : "border-border text-muted-foreground hover:text-foreground")
101
+ }
102
+ >
103
+ <UserX className="size-3.5" />
104
+ <span className="max-sm:sr-only">Unassigned</span>
105
+ </button>
106
+ }
107
+ />
108
+
109
+ {data.loading ? (
110
+ <TicketListSkeleton />
111
+ ) : visible.length === 0 ? (
96
112
  <EmptyState
97
113
  icon={<Inbox />}
98
114
  title={
99
- data.loading
100
- ? "Loading…"
101
- : data.tickets.length === 0
102
- ? "No tickets yet"
103
- : "Nothing matches this filter"
115
+ data.tickets.length === 0
116
+ ? "No tickets yet"
117
+ : unassigned
118
+ ? "Every ticket here has an agent"
119
+ : "No tickets with this status"
104
120
  }
105
121
  description={
106
122
  data.tickets.length === 0
107
123
  ? "When a customer writes in, their ticket lands here. You can also open one yourself after a phone call."
108
- : "Try a different status, or clear the unassigned filter."
124
+ : unassigned
125
+ ? "Turn off the Unassigned filter to see the tickets your team is working."
126
+ : "Pick another tab to see the rest of the queue."
109
127
  }
110
128
  action={
111
129
  data.tickets.length === 0 ? (
@@ -119,6 +137,7 @@ export function InboxView({
119
137
  ) : (
120
138
  <TicketList
121
139
  tickets={visible}
140
+ showStatus={tab === "all"}
122
141
  customerName={data.customerName}
123
142
  assigneeName={data.agentName}
124
143
  onSelect={(id) => router.push(`/tickets/${id}`)}
@@ -18,12 +18,14 @@ export default function RootLayout({ children }: LayoutProps) {
18
18
  <html lang="en">
19
19
  <head>
20
20
  <meta charSet="utf-8" />
21
- <meta name="viewport" content="width=device-width, initial-scale=1" />
22
- <title>__APP_NAME__</title>
21
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
22
+ {/* No <title> here: each page's `metadata` sets "<Page> · <Brand>".
23
+ A title in the layout renders first and wins over the page's. */}
23
24
  {/* Tailwind is compiled by Pylon from app/globals.css and the
24
- stylesheet link is injected here automatically. Inter is declared in
25
- app.ts (fonts: [...]) and self-hosted by the build — @font-face, the
26
- preload link, and a size-adjusted fallback are injected too. */}
25
+ stylesheet link is injected here automatically. The typeface is
26
+ declared in app.ts (fonts: [...]) and self-hosted by the build;
27
+ @font-face, the preload link, and a size-adjusted fallback are
28
+ injected too. */}
27
29
  </head>
28
30
  <body className="h-full">{children}</body>
29
31
  </html>
@@ -1,21 +1,18 @@
1
1
  import React from "react";
2
2
  import type { Metadata, PageProps } from "@pylonsync/react";
3
+ import { BRAND } from "@/lib/brand";
3
4
  import { InboxView } from "./inbox-view";
4
5
 
5
6
  export const metadata: Metadata = {
6
- title: "Inbox",
7
+ title: `Inbox · ${BRAND.name}`,
7
8
  robots: "noindex",
8
9
  };
9
10
 
10
- /**
11
- * `/` — the support queue.
12
- *
13
- */
11
+ /** `/` — the support queue. */
14
12
  export default function InboxPage({ searchParams }: PageProps) {
15
-
16
13
  return (
17
14
  <InboxView
18
- openNew={searchParams?.new === "ticket"}
15
+ openNew={searchParams?.new === "ticket"}
19
16
  initialFilter={searchParams?.filter}
20
17
  />
21
18
  );
@@ -1,9 +1,10 @@
1
1
  import React from "react";
2
2
  import type { Metadata, PageProps } from "@pylonsync/react";
3
+ import { BRAND } from "@/lib/brand";
3
4
  import { TicketView } from "./ticket-view";
4
5
 
5
6
  export const metadata: Metadata = {
6
- title: "Ticket",
7
+ title: `Ticket · ${BRAND.name}`,
7
8
  robots: "noindex",
8
9
  };
9
10