@tulip-systems/create-app 0.12.4 → 0.13.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 (143) hide show
  1. package/dist/index.mjs +2866 -2949
  2. package/dist/index.mjs.map +1 -1
  3. package/dist/templates/basic/package.json +37 -38
  4. package/dist/templates/basic/src/app/layout.tsx +20 -10
  5. package/dist/templates/code/package.json +80 -72
  6. package/dist/templates/code/public/sw.js +35 -0
  7. package/dist/templates/code/src/app/admin/contacts/_components/grid.tsx +1 -1
  8. package/dist/templates/code/src/app/admin/customers/_config/columns-data.tsx +1 -1
  9. package/dist/templates/code/src/app/admin/employees/_config/columns-data.tsx +1 -1
  10. package/dist/templates/code/src/app/admin/history/[id]/layout.tsx +33 -0
  11. package/dist/templates/code/src/app/admin/history/[id]/loading.tsx +11 -0
  12. package/dist/templates/code/src/app/admin/history/[id]/page.tsx +30 -0
  13. package/dist/templates/code/src/app/admin/history/_components/diff.client.tsx +377 -0
  14. package/dist/templates/code/src/app/admin/history/_components/field-comparison.tsx +153 -0
  15. package/dist/templates/code/src/app/admin/history/_components/tables.tsx +47 -0
  16. package/dist/templates/code/src/app/admin/history/_components/toolbars.tsx +54 -0
  17. package/dist/templates/code/src/app/admin/history/_config/columns-data.tsx +61 -0
  18. package/dist/templates/code/src/app/admin/history/_config/filters.ts +46 -0
  19. package/dist/templates/code/src/app/admin/history/_config/sorting.ts +30 -0
  20. package/dist/templates/code/src/app/admin/history/_lib/helpers.ts +98 -0
  21. package/dist/templates/code/src/app/admin/history/_lib/router.ts +100 -0
  22. package/dist/templates/code/src/app/admin/history/_lib/schema.ts +45 -0
  23. package/dist/templates/code/src/app/admin/history/_lib/service.server.ts +30 -0
  24. package/dist/templates/code/src/app/admin/history/_lib/validators.ts +118 -0
  25. package/dist/templates/code/src/app/admin/initiatives/_config/columns-data.tsx +1 -1
  26. package/dist/templates/code/src/app/admin/notifications/_components/command-toggle-push.tsx +115 -0
  27. package/dist/templates/code/src/app/admin/notifications/_components/tables.tsx +37 -0
  28. package/dist/templates/code/src/app/admin/notifications/_components/toolbars.tsx +21 -0
  29. package/dist/templates/code/src/app/admin/notifications/_config/columns-data.tsx +64 -0
  30. package/dist/templates/code/src/app/admin/notifications/_config/commands.tsx +40 -0
  31. package/dist/templates/code/src/app/admin/notifications/_lib/listeners.server.ts +69 -0
  32. package/dist/templates/code/src/app/admin/notifications/_lib/push.server.ts +80 -0
  33. package/dist/templates/code/src/app/admin/notifications/_lib/router.ts +82 -0
  34. package/dist/templates/code/src/app/admin/notifications/_lib/schema.ts +49 -0
  35. package/dist/templates/code/src/app/admin/notifications/_lib/validators.ts +19 -0
  36. package/dist/templates/code/src/app/admin/notifications/layout.tsx +17 -0
  37. package/dist/templates/code/src/app/admin/notifications/loading.tsx +9 -0
  38. package/dist/templates/code/src/app/admin/notifications/page.tsx +28 -0
  39. package/dist/templates/code/src/app/admin/projects/[id]/(default)/page.tsx +1 -1
  40. package/dist/templates/code/src/app/admin/projects/[id]/timeline/page.tsx +1 -1
  41. package/dist/templates/code/src/app/admin/projects/_config/columns-data.tsx +1 -1
  42. package/dist/templates/code/src/app/admin/projects/_lib/events.ts +64 -0
  43. package/dist/templates/code/src/app/admin/projects/_lib/listeners.server.ts +82 -0
  44. package/dist/templates/code/src/app/admin/projects/_lib/router.ts +145 -20
  45. package/dist/templates/code/src/app/admin/projects/timeline/page.tsx +1 -1
  46. package/dist/templates/code/src/app/admin/prospects/_config/columns-data.tsx +1 -1
  47. package/dist/templates/code/src/app/admin/queue/_components/create-command.tsx +97 -0
  48. package/dist/templates/code/src/app/admin/queue/_components/tables.tsx +37 -0
  49. package/dist/templates/code/src/app/admin/queue/_components/toolbars.tsx +16 -0
  50. package/dist/templates/code/src/app/admin/queue/_config/columns-data.tsx +44 -0
  51. package/dist/templates/code/src/app/admin/queue/_config/commands.tsx +39 -0
  52. package/dist/templates/code/src/app/admin/queue/_lib/queue.ts +27 -0
  53. package/dist/templates/code/src/app/admin/queue/_lib/router.ts +33 -0
  54. package/dist/templates/code/src/app/admin/queue/_lib/schema.ts +12 -0
  55. package/dist/templates/code/src/app/admin/queue/_lib/validators.ts +15 -0
  56. package/dist/templates/code/src/app/admin/quotations/_config/columns-data.tsx +1 -1
  57. package/dist/templates/code/src/app/admin/quotations/_config/commands.tsx +1 -1
  58. package/dist/templates/code/src/app/admin/settings/history/layout.tsx +6 -0
  59. package/dist/templates/code/src/app/admin/settings/history/loading.tsx +5 -0
  60. package/dist/templates/code/src/app/admin/settings/history/page.tsx +13 -0
  61. package/dist/templates/code/src/app/admin/settings/layout.tsx +11 -0
  62. package/dist/templates/code/src/app/admin/settings/queue/loading.tsx +9 -0
  63. package/dist/templates/code/src/app/admin/settings/queue/page.tsx +21 -0
  64. package/dist/templates/code/src/app/admin/tasks/_components/domains-tabs-grid.tsx +1 -1
  65. package/dist/templates/code/src/app/admin/tasks/_config/columns-data.tsx +1 -1
  66. package/dist/templates/code/src/app/admin/tasks/_config/columns-inline.tsx +1 -1
  67. package/dist/templates/code/src/app/admin/tasks/_lib/events.ts +40 -0
  68. package/dist/templates/code/src/app/admin/tasks/_lib/listeners.server.ts +46 -0
  69. package/dist/templates/code/src/app/admin/tasks/_lib/router.ts +222 -90
  70. package/dist/templates/code/src/app/admin/time/_config/columns-data.tsx +1 -1
  71. package/dist/templates/code/src/app/admin/time/_config/columns-inline.tsx +1 -1
  72. package/dist/templates/code/src/app/api/[transport]/route.ts +31 -21
  73. package/dist/templates/code/src/app/api/queue/dispatch/route.ts +4 -0
  74. package/dist/templates/code/src/app/auth/forget-password/page.tsx +1 -1
  75. package/dist/templates/code/src/app/auth/layout.tsx +1 -1
  76. package/dist/templates/code/src/app/auth/reset-password/page.tsx +1 -1
  77. package/dist/templates/code/src/app/layout.tsx +25 -13
  78. package/dist/templates/code/src/env.ts +12 -0
  79. package/dist/templates/code/src/lib/config/paths.tsx +8 -0
  80. package/dist/templates/code/src/server/auth/constants.ts +1 -1
  81. package/dist/templates/code/src/server/auth/init.ts +12 -5
  82. package/dist/templates/code/src/server/auth/permissions.ts +3 -0
  83. package/dist/templates/code/src/server/auth/schema.ts +100 -1
  84. package/dist/templates/code/src/server/db/schema.ts +3 -0
  85. package/dist/templates/code/src/server/events/handlers.ts +17 -0
  86. package/dist/templates/code/src/server/events/init.ts +18 -0
  87. package/dist/templates/code/src/server/events/listeners.ts +17 -0
  88. package/dist/templates/code/src/server/queue/handlers.ts +5 -0
  89. package/dist/templates/code/src/server/queue/init.ts +16 -0
  90. package/dist/templates/code/src/server/router/router.ts +13 -0
  91. package/dist/templates/spark/package.json +64 -65
  92. package/dist/templates/spark/src/app/admin/assignments/[id]/(default)/@dashboard/page.tsx +1 -1
  93. package/dist/templates/spark/src/app/admin/assignments/_config/columns-data.tsx +1 -1
  94. package/dist/templates/spark/src/app/admin/companies/_config/columns-data.tsx +1 -1
  95. package/dist/templates/spark/src/app/admin/contacts/_components/grid.tsx +1 -1
  96. package/dist/templates/spark/src/app/admin/customers/_config/columns-data.tsx +1 -1
  97. package/dist/templates/spark/src/app/admin/drive/_config/columns-data.tsx +1 -1
  98. package/dist/templates/spark/src/app/admin/emails/_components/send-email.tsx +1 -1
  99. package/dist/templates/spark/src/app/admin/emails/_config/columns-data.tsx +1 -1
  100. package/dist/templates/spark/src/app/admin/employees/_config/columns-data.tsx +1 -1
  101. package/dist/templates/spark/src/app/admin/executions/[id]/@dashboard/page.tsx +1 -1
  102. package/dist/templates/spark/src/app/admin/executions/_config/columns-data.tsx +1 -1
  103. package/dist/templates/spark/src/app/admin/products/[id]/(preview)/page.tsx +1 -1
  104. package/dist/templates/spark/src/app/admin/products/_config/columns-data.tsx +1 -1
  105. package/dist/templates/spark/src/app/admin/projects/[id]/(dashboard)/page.tsx +1 -1
  106. package/dist/templates/spark/src/app/admin/projects/[id]/messages/page.tsx +1 -1
  107. package/dist/templates/spark/src/app/admin/projects/[id]/statistics/page.tsx +1 -1
  108. package/dist/templates/spark/src/app/admin/projects/_config/columns-data.tsx +1 -1
  109. package/dist/templates/spark/src/app/admin/purchase-order-items/_config/columns-data.tsx +1 -1
  110. package/dist/templates/spark/src/app/admin/purchase-order-items/_config/columns-inline.tsx +1 -1
  111. package/dist/templates/spark/src/app/admin/purchase-order-items/_config/commands.tsx +1 -1
  112. package/dist/templates/spark/src/app/admin/purchase-orders/[id]/(default)/@dashboard/page.tsx +1 -1
  113. package/dist/templates/spark/src/app/admin/purchase-orders/_config/columns-data.tsx +1 -1
  114. package/dist/templates/spark/src/app/admin/quotation-items/_config/commands.tsx +1 -1
  115. package/dist/templates/spark/src/app/admin/quotations/[id]/(default)/@dashboard/page.tsx +1 -1
  116. package/dist/templates/spark/src/app/admin/quotations/_config/columns-data.tsx +1 -1
  117. package/dist/templates/spark/src/app/admin/run-tasks/_config/columns-data.tsx +1 -1
  118. package/dist/templates/spark/src/app/admin/runs/[id]/@dashboard/page.tsx +1 -1
  119. package/dist/templates/spark/src/app/admin/runs/_config/columns-data.tsx +1 -1
  120. package/dist/templates/spark/src/app/admin/sales-invoices/[id]/@dashboard/page.tsx +1 -1
  121. package/dist/templates/spark/src/app/admin/sales-invoices/_config/columns-data.tsx +1 -1
  122. package/dist/templates/spark/src/app/admin/sales-order-executions/_config/columns-data.tsx +1 -1
  123. package/dist/templates/spark/src/app/admin/sales-order-executions/_config/columns-inline.tsx +1 -1
  124. package/dist/templates/spark/src/app/admin/sales-order-executions/_config/commands.tsx +1 -1
  125. package/dist/templates/spark/src/app/admin/sales-order-items/_config/commands.tsx +1 -1
  126. package/dist/templates/spark/src/app/admin/sales-orders/[id]/(default)/@dashboard/page.tsx +1 -1
  127. package/dist/templates/spark/src/app/admin/sales-orders/[id]/(default)/layout.tsx +1 -1
  128. package/dist/templates/spark/src/app/admin/sales-orders/_config/columns-data.tsx +1 -1
  129. package/dist/templates/spark/src/app/admin/schedule/_components/schedule-card.tsx +1 -1
  130. package/dist/templates/spark/src/app/admin/schedule/_components/schedule-month-view.tsx +1 -1
  131. package/dist/templates/spark/src/app/admin/suppliers/_config/columns-data.tsx +1 -1
  132. package/dist/templates/spark/src/app/admin/tasks/_components/subproject-selector.tsx +1 -1
  133. package/dist/templates/spark/src/app/admin/tasks/_config/columns-data.tsx +1 -1
  134. package/dist/templates/spark/src/app/admin/tasks/_config/columns-inline.tsx +1 -1
  135. package/dist/templates/spark/src/app/admin/tasks/_config/commands.tsx +1 -1
  136. package/dist/templates/spark/src/app/admin/technical-sheets/[id]/page.tsx +1 -1
  137. package/dist/templates/spark/src/app/admin/technical-sheets/_config/columns-data.tsx +1 -1
  138. package/dist/templates/spark/src/app/admin/technical-sheets/_config/commands.tsx +1 -1
  139. package/dist/templates/spark/src/app/admin/templates/_config/columns-data.tsx +1 -1
  140. package/dist/templates/spark/src/app/auth/layout.tsx +1 -1
  141. package/dist/templates/spark/src/app/layout.tsx +25 -10
  142. package/dist/templates/spark/src/server/auth/init.ts +1 -0
  143. package/package.json +6 -6
@@ -18,52 +18,51 @@
18
18
  "db:studio": "dotenv drizzle-kit studio"
19
19
  },
20
20
  "dependencies": {
21
- "@better-auth/passkey": "^1.6.26",
22
- "@hookform/resolvers": "^5.7.1",
23
- "@orpc/client": "^1.14.15",
24
- "@orpc/server": "^1.14.15",
25
- "@orpc/tanstack-query": "^1.14.15",
26
- "@tailwindcss/typography": "^0.5.20",
27
- "@tanstack/react-query": "^5.101.4",
28
- "@tulip-systems/app": "0.12.4",
29
- "@tulip-systems/auth": "0.12.4",
30
- "@tulip-systems/commands": "0.12.4",
31
- "@tulip-systems/core": "0.12.4",
32
- "@tulip-systems/ui": "0.12.4",
21
+ "@better-auth/passkey": "catalog:",
22
+ "@hookform/resolvers": "catalog:",
23
+ "@orpc/client": "catalog:",
24
+ "@orpc/server": "catalog:",
25
+ "@orpc/tanstack-query": "catalog:",
26
+ "@tailwindcss/typography": "catalog:",
27
+ "@tanstack/react-query": "catalog:",
28
+ "@tulip-systems/app": "0.13.0",
29
+ "@tulip-systems/auth": "0.13.0",
30
+ "@tulip-systems/commands": "0.13.0",
31
+ "@tulip-systems/core": "0.13.0",
32
+ "@tulip-systems/ui": "0.13.0",
33
33
  "@vercel/functions": "^3.9.0",
34
- "better-auth": "^1.6.26",
35
- "class-variance-authority": "^0.7.1",
36
- "date-fns": "^4.4.0",
37
- "drizzle-orm": "^0.45.2",
38
- "drizzle-zod": "^0.8.3",
39
- "lucide-react": "^1.30.0",
40
- "motion": "^13.0.0",
41
- "next": "16.3.0",
42
- "nuqs": "2.9.5",
43
- "pg": "8.22.0",
44
- "postgres": "^3.4.9",
45
- "react": "19.2.8",
46
- "react-dom": "19.2.8",
47
- "react-hook-form": "^7.84.0",
34
+ "better-auth": "catalog:",
35
+ "class-variance-authority": "catalog:",
36
+ "date-fns": "catalog:",
37
+ "drizzle-orm": "catalog:",
38
+ "drizzle-zod": "catalog:",
39
+ "lucide-react": "catalog:",
40
+ "motion": "catalog:",
41
+ "next": "catalog:",
42
+ "nuqs": "catalog:",
43
+ "pg": "catalog:",
44
+ "react": "catalog:",
45
+ "react-dom": "catalog:",
46
+ "react-hook-form": "catalog:",
48
47
  "resend": "^6.18.1",
49
48
  "sharp": "^0.35.3",
50
49
  "server-only": "^0.0.1",
51
50
  "uuid": "^14.0.1",
52
- "zod": "^4.4.3",
51
+ "zod": "catalog:",
53
52
  "zustand": "^5.0.14"
54
53
  },
55
54
  "devDependencies": {
56
- "@tailwindcss/postcss": "^4.3.3",
57
- "@types/node": "^26.2.0",
58
- "@types/pg": "^8.21.0",
59
- "@types/react": "19.2.17",
60
- "@types/react-dom": "19.2.4",
61
- "dotenv-cli": "^11.0.0",
62
- "drizzle-kit": "^0.31.10",
63
- "postcss": "^8.5.26",
55
+ "@tailwindcss/postcss": "catalog:",
56
+ "@types/node": "catalog:",
57
+ "@types/pg": "catalog:",
58
+ "@types/react": "catalog:",
59
+ "@types/react-dom": "catalog:",
60
+ "dotenv-cli": "catalog:",
61
+ "drizzle-kit": "catalog:",
62
+ "postcss": "catalog:",
64
63
  "server-cli-only": "^0.3.2",
65
- "tailwindcss": "^4.3.3",
66
- "tw-animate-css": "^1.4.0",
67
- "typescript": "5.9.3"
64
+ "tailwindcss": "catalog:",
65
+ "tw-animate-css": "catalog:",
66
+ "typescript": "catalog:"
68
67
  }
69
68
  }
@@ -2,21 +2,31 @@ import "./globals.css";
2
2
  import "../server/router/register";
3
3
 
4
4
  import { Providers } from "@tulip-systems/app/components/client";
5
- import {
6
- ColorThemeScript,
7
- generateRootLayoutMetadata,
8
- RootLayout,
9
- } from "@tulip-systems/app/components/server";
5
+ import { registerFonts, rootLayoutViewport } from "@tulip-systems/app/components/server";
6
+ import { cn } from "@tulip-systems/ui/cn";
7
+ import type { Metadata } from "next";
10
8
  import type { PropsWithChildren } from "react";
11
9
  import { config } from "@/lib/config/base";
12
10
 
13
- export const { metadata, viewport } = generateRootLayoutMetadata(config);
11
+ export const viewport = rootLayoutViewport;
12
+
13
+ export const metadata: Metadata = {
14
+ description: "Developed by NewCode",
15
+ appleWebApp: {
16
+ capable: true,
17
+ statusBarStyle: "black-translucent",
18
+ title: config.general.name,
19
+ },
20
+ };
14
21
 
15
22
  export default function Layout({ children }: PropsWithChildren) {
16
23
  return (
17
- <RootLayout>
18
- <ColorThemeScript />
19
- <Providers>{children}</Providers>
20
- </RootLayout>
24
+ <html lang="nl" suppressHydrationWarning>
25
+ <title>{config.general.name}</title>
26
+
27
+ <body className={cn("bg-background font-sans antialiased", registerFonts())}>
28
+ <Providers>{children}</Providers>
29
+ </body>
30
+ </html>
21
31
  );
22
32
  }
@@ -23,118 +23,126 @@
23
23
  "@ai-sdk/react": "^4.0.60",
24
24
  "@aws-sdk/client-s3": "^3.1106.0",
25
25
  "@aws-sdk/s3-request-presigner": "^3.1106.0",
26
- "@better-auth/oauth-provider": "^1.6.26",
27
- "@better-auth/passkey": "^1.6.26",
26
+ "@better-auth/cimd": "catalog:",
27
+ "@better-auth/mcp": "catalog:",
28
+ "@better-auth/oauth-provider": "catalog:",
29
+ "@better-auth/passkey": "catalog:",
28
30
  "@dnd-kit/collision": "^0.5.0",
29
31
  "@dnd-kit/core": "^6.3.1",
30
32
  "@dnd-kit/helpers": "^0.5.0",
31
33
  "@dnd-kit/modifiers": "^9.0.0",
32
34
  "@dnd-kit/react": "^0.5.0",
33
35
  "@dnd-kit/sortable": "^10.0.0",
34
- "@hookform/resolvers": "^5.7.1",
36
+ "@hookform/resolvers": "catalog:",
35
37
  "@js-temporal/polyfill": "^0.5.1",
36
38
  "@modelcontextprotocol/server": "^2.0.0",
37
39
  "@openrouter/ai-sdk-provider": "^3.0.0",
38
40
  "@opentelemetry/api": "^1.9.1",
39
- "@opentelemetry/instrumentation-pg": "^0.73.0",
41
+ "@opentelemetry/instrumentation-pg": "^0.74.0",
40
42
  "@orpc/ai-sdk": "^1.14.15",
41
- "@orpc/client": "^1.14.15",
43
+ "@orpc/client": "catalog:",
42
44
  "@orpc/otel": "^1.14.15",
43
- "@orpc/server": "^1.14.15",
44
- "@orpc/tanstack-query": "^1.14.15",
45
+ "@orpc/server": "catalog:",
46
+ "@orpc/tanstack-query": "catalog:",
45
47
  "@react-pdf/renderer": "^4.5.1",
46
48
  "@t3-oss/env-nextjs": "^0.13.11",
47
- "@tailwindcss/typography": "^0.5.20",
48
- "@tanstack/db": "^0.6.17",
49
+ "@tailwindcss/typography": "catalog:",
50
+ "@tanstack/db": "^0.9.2",
49
51
  "@tanstack/query-db-collection": "^1.2.1",
50
- "@tanstack/react-query": "^5.101.4",
52
+ "@tanstack/react-query": "catalog:",
51
53
  "@tanstack/react-table": "^8.21.3",
52
54
  "@tanstack/react-virtual": "^3.14.9",
53
- "@tiptap/core": "^3.29.2",
54
- "@tiptap/extension-blockquote": "^3.29.2",
55
- "@tiptap/extension-bold": "^3.29.2",
56
- "@tiptap/extension-document": "^3.29.2",
57
- "@tiptap/extension-hard-break": "^3.29.2",
58
- "@tiptap/extension-heading": "^3.29.2",
59
- "@tiptap/extension-highlight": "^3.29.2",
60
- "@tiptap/extension-horizontal-rule": "^3.29.2",
61
- "@tiptap/extension-italic": "^3.29.2",
62
- "@tiptap/extension-link": "^3.29.2",
63
- "@tiptap/extension-list": "^3.29.2",
64
- "@tiptap/extension-paragraph": "^3.29.2",
65
- "@tiptap/extension-strike": "^3.29.2",
66
- "@tiptap/extension-text": "^3.29.2",
67
- "@tiptap/extension-text-style": "^3.29.2",
68
- "@tiptap/extension-underline": "^3.29.2",
69
- "@tiptap/extensions": "^3.29.2",
70
- "@tulip-systems/ai": "0.12.4",
71
- "@tulip-systems/app": "0.12.4",
72
- "@tulip-systems/auth": "0.12.4",
73
- "@tulip-systems/blocks": "0.12.4",
74
- "@tulip-systems/commands": "0.12.4",
75
- "@tulip-systems/core": "0.12.4",
76
- "@tulip-systems/data-tables": "0.12.4",
77
- "@tulip-systems/drive": "0.12.4",
78
- "@tulip-systems/drive-google": "0.12.4",
79
- "@tulip-systems/editor": "0.12.4",
80
- "@tulip-systems/editor-storage": "0.12.4",
81
- "@tulip-systems/inline": "0.12.4",
82
- "@tulip-systems/query": "0.12.4",
83
- "@tulip-systems/storage": "0.12.4",
84
- "@tulip-systems/ui": "0.12.4",
55
+ "@tiptap/core": "catalog:",
56
+ "@tiptap/extension-blockquote": "catalog:",
57
+ "@tiptap/extension-bold": "catalog:",
58
+ "@tiptap/extension-document": "catalog:",
59
+ "@tiptap/extension-hard-break": "catalog:",
60
+ "@tiptap/extension-heading": "catalog:",
61
+ "@tiptap/extension-highlight": "catalog:",
62
+ "@tiptap/extension-horizontal-rule": "catalog:",
63
+ "@tiptap/extension-italic": "catalog:",
64
+ "@tiptap/extension-link": "catalog:",
65
+ "@tiptap/extension-list": "catalog:",
66
+ "@tiptap/extension-paragraph": "catalog:",
67
+ "@tiptap/extension-strike": "catalog:",
68
+ "@tiptap/extension-text": "catalog:",
69
+ "@tiptap/extension-text-style": "catalog:",
70
+ "@tiptap/extension-underline": "catalog:",
71
+ "@tiptap/extensions": "catalog:",
72
+ "@tulip-systems/ai": "0.13.0",
73
+ "@tulip-systems/app": "0.13.0",
74
+ "@tulip-systems/auth": "0.13.0",
75
+ "@tulip-systems/blocks": "0.13.0",
76
+ "@tulip-systems/commands": "0.13.0",
77
+ "@tulip-systems/core": "0.13.0",
78
+ "@tulip-systems/data-tables": "0.13.0",
79
+ "@tulip-systems/drive": "0.13.0",
80
+ "@tulip-systems/drive-google": "0.13.0",
81
+ "@tulip-systems/editor": "0.13.0",
82
+ "@tulip-systems/editor-storage": "0.13.0",
83
+ "@tulip-systems/events": "0.13.0",
84
+ "@tulip-systems/inline": "0.13.0",
85
+ "@tulip-systems/query": "0.13.0",
86
+ "@tulip-systems/queue": "0.13.0",
87
+ "@tulip-systems/storage": "0.13.0",
88
+ "@tulip-systems/ui": "0.13.0",
85
89
  "@uidotdev/usehooks": "^2.4.1",
90
+ "@upstash/qstash": "^2.11.3",
86
91
  "@vercel/functions": "^3.9.0",
87
92
  "@vercel/otel": "^2.1.3",
88
93
  "ai": "^7.0.57",
89
- "better-auth": "^1.6.26",
90
- "class-variance-authority": "^0.7.1",
94
+ "better-auth": "catalog:",
95
+ "class-variance-authority": "catalog:",
91
96
  "client-only": "^0.0.1",
92
- "date-fns": "^4.4.0",
93
- "drizzle-orm": "^0.45.2",
97
+ "date-fns": "catalog:",
98
+ "diff": "^9.0.0",
99
+ "drizzle-orm": "catalog:",
94
100
  "drizzle-seed": "^0.3.1",
95
- "drizzle-zod": "^0.8.3",
101
+ "drizzle-zod": "catalog:",
96
102
  "fast-deep-equal": "^3.1.3",
97
- "googleapis": "^174.0.1",
98
- "jotai": "^2.20.2",
103
+ "googleapis": "^181.0.0",
104
+ "jotai": "^3.0.0",
99
105
  "lodash.throttle": "^4.1.1",
100
- "lucide-react": "^1.30.0",
106
+ "lucide-react": "catalog:",
101
107
  "mcp-handler": "^2.1.0",
102
- "motion": "^13.0.0",
103
- "next": "16.3.0",
104
- "nuqs": "2.9.5",
105
- "pg": "8.22.0",
106
- "postgres": "^3.4.9",
107
- "react": "19.2.8",
108
- "react-dom": "19.2.8",
109
- "react-hook-form": "^7.84.0",
108
+ "motion": "catalog:",
109
+ "next": "catalog:",
110
+ "nuqs": "catalog:",
111
+ "pg": "catalog:",
112
+ "react": "catalog:",
113
+ "react-dom": "catalog:",
114
+ "react-hook-form": "catalog:",
110
115
  "react-markdown": "^10.1.0",
111
116
  "react-pdf-tailwind": "^3.0.0",
112
- "recharts": "3.10.1",
117
+ "recharts": "catalog:",
113
118
  "resend": "^6.18.1",
119
+ "rfc6902": "^5.3.0",
114
120
  "server-only": "^0.0.1",
115
121
  "sharp": "^0.35.3",
116
122
  "usehooks-ts": "^3.1.1",
117
123
  "uuid": "^14.0.1",
124
+ "web-push": "^3.6.7",
118
125
  "xlsx": "^0.18.5",
119
- "zod": "^4.4.3",
126
+ "zod": "catalog:",
120
127
  "zustand": "^5.0.14"
121
128
  },
122
129
  "devDependencies": {
123
130
  "@faker-js/faker": "^10.5.0",
124
- "@tailwindcss/postcss": "^4.3.3",
131
+ "@tailwindcss/postcss": "catalog:",
125
132
  "@types/lodash.throttle": "^4.1.9",
126
- "@types/node": "^26.2.0",
127
- "@types/pg": "^8.21.0",
128
- "@types/react": "19.2.17",
129
- "@types/react-dom": "19.2.4",
133
+ "@types/node": "catalog:",
134
+ "@types/pg": "catalog:",
135
+ "@types/react": "catalog:",
136
+ "@types/react-dom": "catalog:",
137
+ "@types/web-push": "^3.6.4",
130
138
  "babel-plugin-react-compiler": "^1.0.0",
131
- "dotenv-cli": "^11.0.0",
132
- "drizzle-kit": "^0.31.10",
133
- "postcss": "^8.5.26",
139
+ "dotenv-cli": "catalog:",
140
+ "drizzle-kit": "catalog:",
141
+ "postcss": "catalog:",
134
142
  "server-cli-only": "^0.3.2",
135
- "tailwindcss": "^4.3.3",
136
- "tsx": "^4.23.11",
137
- "tw-animate-css": "^1.4.0",
138
- "typescript": "5.9.3"
143
+ "tailwindcss": "catalog:",
144
+ "tsx": "catalog:",
145
+ "tw-animate-css": "catalog:",
146
+ "typescript": "catalog:"
139
147
  }
140
148
  }
@@ -0,0 +1,35 @@
1
+ self.addEventListener("push", (event) => {
2
+ const data = event.data?.json() ?? {};
3
+ const title = data.title ?? "Notification";
4
+ const options = {
5
+ body: data.body,
6
+ icon: "/icons/icon-x192.png",
7
+ badge: "/icons/icon-x192.png",
8
+ data: {
9
+ url: data.url ?? "/admin/notifications",
10
+ notificationId: data.notificationId,
11
+ },
12
+ };
13
+
14
+ event.waitUntil(self.registration.showNotification(title, options));
15
+ });
16
+
17
+ self.addEventListener("notificationclick", (event) => {
18
+ event.notification.close();
19
+
20
+ const url = new URL(event.notification.data?.url ?? "/admin/notifications", self.location.origin);
21
+
22
+ event.waitUntil(
23
+ self.clients.matchAll({ type: "window", includeUncontrolled: true }).then((clients) => {
24
+ for (const client of clients) {
25
+ if (new URL(client.url).href === url.href && "focus" in client) {
26
+ return client.focus();
27
+ }
28
+ }
29
+
30
+ if (self.clients.openWindow) {
31
+ return self.clients.openWindow(url.href);
32
+ }
33
+ }),
34
+ );
35
+ });
@@ -6,11 +6,11 @@ import {
6
6
  DropdownCommandMenu,
7
7
  } from "@tulip-systems/commands/client";
8
8
  import { formatPhone } from "@tulip-systems/core";
9
+ import { Link } from "@tulip-systems/core/navigation";
9
10
  import { Card, CardContent, CardHeader, CardTitle } from "@tulip-systems/ui/card";
10
11
  import { cn } from "@tulip-systems/ui/cn";
11
12
  import { EmptyPage, EmptyPageTitle } from "@tulip-systems/ui/empty";
12
13
  import { Briefcase, Mail, Phone } from "lucide-react";
13
- import Link from "next/link";
14
14
  import type { ComponentProps } from "react";
15
15
  import type { Contact } from "../_lib/validators";
16
16
 
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
 
3
3
  import { formatPhone } from "@tulip-systems/core";
4
+ import { Link } from "@tulip-systems/core/navigation";
4
5
  import { TableCell, type TableColumnDef, TableColumnHeader } from "@tulip-systems/data-tables";
5
6
  import { createTableSelectCell } from "@tulip-systems/data-tables/client";
6
- import Link from "next/link";
7
7
  import type { Customer } from "../_lib/validators";
8
8
 
9
9
  export type CustomerColumn = Customer;
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
 
3
+ import { Link } from "@tulip-systems/core/navigation";
3
4
  import { TableCell, type TableColumnDef, TableColumnHeader } from "@tulip-systems/data-tables";
4
5
  import { createTableSelectCell } from "@tulip-systems/data-tables/client";
5
- import Link from "next/link";
6
6
  import type { EmployeeTableData } from "../_components/tables";
7
7
 
8
8
  export const employeeColumns: TableColumnDef<EmployeeTableData>[] = [
@@ -0,0 +1,33 @@
1
+ "use client";
2
+
3
+ import { useSuspenseQuery } from "@tanstack/react-query";
4
+ import { Header, Topbar, TopbarTitle } from "@tulip-systems/app/components/client";
5
+ import { notFound } from "next/navigation";
6
+ import { type PropsWithChildren, use } from "react";
7
+ import { orpc } from "@/server/router/client";
8
+
9
+ export default function Layout(props: PropsWithChildren<{ params: Promise<{ id: string }> }>) {
10
+ const { id } = use(props.params);
11
+ const { data } = useSuspenseQuery(orpc.history.getById.queryOptions({ input: { id } }));
12
+ if (!data) notFound();
13
+
14
+ return (
15
+ <>
16
+ <Header>
17
+ <Topbar>
18
+ <TopbarTitle
19
+ breadcrumbs={[
20
+ { label: "History", href: "/admin/settings/history" },
21
+ {
22
+ label: [data.entry.resourceType, data.entry.resourceLabel, data.entry.action]
23
+ .filter(Boolean)
24
+ .join(" · "),
25
+ },
26
+ ]}
27
+ />
28
+ </Topbar>
29
+ </Header>
30
+ <div className="min-h-0 overflow-auto p-content">{props.children}</div>
31
+ </>
32
+ );
33
+ }
@@ -0,0 +1,11 @@
1
+ import { Skeleton } from "@tulip-systems/ui/skeleton";
2
+
3
+ export default function Loading() {
4
+ return (
5
+ <div className="space-y-6">
6
+ <Skeleton className="h-8 w-80" />
7
+ <Skeleton className="h-5 w-56" />
8
+ <Skeleton className="h-64 w-full" />
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,30 @@
1
+ "use client";
2
+
3
+ import { useSuspenseQuery } from "@tanstack/react-query";
4
+ import { formatDateTime } from "@tulip-systems/core";
5
+ import { notFound } from "next/navigation";
6
+ import { use } from "react";
7
+ import { orpc } from "@/server/router/client";
8
+ import { HistoryDiffComparison } from "../_components/diff.client";
9
+
10
+ export default function Page(props: { params: Promise<{ id: string }> }) {
11
+ const { id } = use(props.params);
12
+ const { data } = useSuspenseQuery(orpc.history.getById.queryOptions({ input: { id } }));
13
+ if (!data) notFound();
14
+
15
+ return (
16
+ <div className="space-y-8">
17
+ <div className="space-y-3">
18
+ <p className="text-muted-foreground text-sm">
19
+ {data.entry.actorName} · {formatDateTime(data.entry.occurredAt)}
20
+ </p>
21
+ {data.entry.context.length > 0 && (
22
+ <p className="text-muted-foreground text-sm">
23
+ {data.entry.context.map((item) => `${item.type}: ${item.label}`).join(" › ")}
24
+ </p>
25
+ )}
26
+ </div>
27
+ <HistoryDiffComparison diff={data.diff} />
28
+ </div>
29
+ );
30
+ }