ta_data_mas 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/README.md +42 -0
  2. package/apps/api/.prettierrc +4 -0
  3. package/apps/api/README.md +98 -0
  4. package/apps/api/drizzle/0000_right_drax.sql +87 -0
  5. package/apps/api/drizzle/meta/0000_snapshot.json +588 -0
  6. package/apps/api/drizzle/meta/_journal.json +13 -0
  7. package/apps/api/drizzle.config.ts +12 -0
  8. package/apps/api/eslint.config.mjs +35 -0
  9. package/apps/api/nest-cli.json +8 -0
  10. package/apps/api/package.json +99 -0
  11. package/apps/api/src/app.controller.spec.ts +25 -0
  12. package/apps/api/src/app.controller.ts +9 -0
  13. package/apps/api/src/app.module.ts +37 -0
  14. package/apps/api/src/app.service.ts +8 -0
  15. package/apps/api/src/auth/auth.controller.ts +113 -0
  16. package/apps/api/src/auth/auth.module.ts +15 -0
  17. package/apps/api/src/auth/auth.service.ts +309 -0
  18. package/apps/api/src/auth/decorators/current-user-decorator.ts +10 -0
  19. package/apps/api/src/auth/decorators/require-org-role-decorator.ts +7 -0
  20. package/apps/api/src/auth/dto/login.dto.ts +10 -0
  21. package/apps/api/src/auth/dto/register.dto.ts +14 -0
  22. package/apps/api/src/auth/guards/jwt-auth-guard.ts +40 -0
  23. package/apps/api/src/auth/guards/org-role.guards.ts +60 -0
  24. package/apps/api/src/db/db.module.ts +9 -0
  25. package/apps/api/src/db/drizzle.service.ts +16 -0
  26. package/apps/api/src/db/schema/index.ts +6 -0
  27. package/apps/api/src/db/schema/organizations.ts +30 -0
  28. package/apps/api/src/db/schema/projects.ts +26 -0
  29. package/apps/api/src/db/schema/query-history.ts +16 -0
  30. package/apps/api/src/db/schema/storage-buckets.ts +17 -0
  31. package/apps/api/src/db/schema/storage-objects.ts +18 -0
  32. package/apps/api/src/db/schema/users.ts +14 -0
  33. package/apps/api/src/main.ts +51 -0
  34. package/apps/api/src/members/dto/invite-member-dto.ts +6 -0
  35. package/apps/api/src/members/dto/update-role.dto.ts +8 -0
  36. package/apps/api/src/members/invite.service.ts +147 -0
  37. package/apps/api/src/members/members.controller.ts +56 -0
  38. package/apps/api/src/members/members.module.ts +13 -0
  39. package/apps/api/src/members/members.service.ts +85 -0
  40. package/apps/api/src/orgs/dto/create-org.dto.ts +8 -0
  41. package/apps/api/src/orgs/orgs.controller.ts +27 -0
  42. package/apps/api/src/orgs/orgs.module.ts +12 -0
  43. package/apps/api/src/orgs/orgs.service.ts +86 -0
  44. package/apps/api/src/project-api/project-api.controller.ts +95 -0
  45. package/apps/api/src/project-api/project-api.module.ts +12 -0
  46. package/apps/api/src/project-api/project-api.service.ts +196 -0
  47. package/apps/api/src/project-api/project-key.guard.ts +45 -0
  48. package/apps/api/src/project-api/query-parser.ts +129 -0
  49. package/apps/api/src/project-auth/dto/magic-link.dto.ts +7 -0
  50. package/apps/api/src/project-auth/dto/signin.dto.ts +10 -0
  51. package/apps/api/src/project-auth/dto/signup.dto.ts +11 -0
  52. package/apps/api/src/project-auth/project-auth-dashboard.controller.ts +35 -0
  53. package/apps/api/src/project-auth/project-auth.controller.ts +111 -0
  54. package/apps/api/src/project-auth/project-auth.module.ts +13 -0
  55. package/apps/api/src/project-auth/project-auth.service.ts +440 -0
  56. package/apps/api/src/projects/dto/create-project.dto.ts +9 -0
  57. package/apps/api/src/projects/projects.controller.ts +34 -0
  58. package/apps/api/src/projects/projects.module.ts +12 -0
  59. package/apps/api/src/projects/projects.service.ts +136 -0
  60. package/apps/api/src/realtime/realtime-socket.type.ts +14 -0
  61. package/apps/api/src/realtime/realtime.controller.ts +63 -0
  62. package/apps/api/src/realtime/realtime.gateway.ts +150 -0
  63. package/apps/api/src/realtime/realtime.module.ts +14 -0
  64. package/apps/api/src/realtime/realtime.service.ts +101 -0
  65. package/apps/api/src/realtime/trigger.service.ts +95 -0
  66. package/apps/api/src/sql-editor/dto/execute-query.dto.ts +7 -0
  67. package/apps/api/src/sql-editor/sql-editor.controller.ts +28 -0
  68. package/apps/api/src/sql-editor/sql-editor.module.ts +12 -0
  69. package/apps/api/src/sql-editor/sql-editor.service.ts +154 -0
  70. package/apps/api/src/storage/project-storage.controller.ts +140 -0
  71. package/apps/api/src/storage/storage.controller.ts +118 -0
  72. package/apps/api/src/storage/storage.module.ts +15 -0
  73. package/apps/api/src/storage/storage.service.ts +191 -0
  74. package/apps/api/src/storage/uploadthing.ts +23 -0
  75. package/apps/api/src/table-editor/dto/alter-table.dto.ts +15 -0
  76. package/apps/api/src/table-editor/dto/create-table.dto.ts +54 -0
  77. package/apps/api/src/table-editor/table-editor.controller.ts +117 -0
  78. package/apps/api/src/table-editor/table-editor.module.ts +12 -0
  79. package/apps/api/src/table-editor/table-editor.service.ts +366 -0
  80. package/apps/api/test/app.e2e-spec.ts +29 -0
  81. package/apps/api/test/jest-e2e.json +9 -0
  82. package/apps/api/tsconfig.build.json +4 -0
  83. package/apps/api/tsconfig.json +25 -0
  84. package/apps/web/.env.example +12 -0
  85. package/apps/web/AGENTS.md +9 -0
  86. package/apps/web/CLAUDE.md +1 -0
  87. package/apps/web/README.md +36 -0
  88. package/apps/web/components.json +25 -0
  89. package/apps/web/eslint.config.mjs +18 -0
  90. package/apps/web/next.config.ts +11 -0
  91. package/apps/web/package.json +48 -0
  92. package/apps/web/postcss.config.mjs +7 -0
  93. package/apps/web/public/file.svg +1 -0
  94. package/apps/web/public/globe.svg +1 -0
  95. package/apps/web/public/logo.svg +4 -0
  96. package/apps/web/public/next.svg +1 -0
  97. package/apps/web/public/vercel.svg +1 -0
  98. package/apps/web/public/window.svg +1 -0
  99. package/apps/web/src/app/(dashboard)/layout.tsx +33 -0
  100. package/apps/web/src/app/(dashboard)/organizations/(list)/layout.tsx +7 -0
  101. package/apps/web/src/app/(dashboard)/organizations/(list)/new/page.tsx +26 -0
  102. package/apps/web/src/app/(dashboard)/organizations/(list)/page.tsx +44 -0
  103. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/api/page.tsx +13 -0
  104. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/layout.tsx +19 -0
  105. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/page.tsx +10 -0
  106. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/providers/page.tsx +19 -0
  107. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/url-configuration/page.tsx +24 -0
  108. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/users/page.tsx +13 -0
  109. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/database/page.tsx +29 -0
  110. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/realtime/page.tsx +28 -0
  111. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/sql/page.tsx +21 -0
  112. package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/storage/page.tsx +28 -0
  113. package/apps/web/src/app/(dashboard)/organizations/[slug]/layout.tsx +20 -0
  114. package/apps/web/src/app/(dashboard)/organizations/[slug]/projects/page.tsx +62 -0
  115. package/apps/web/src/app/(dashboard)/organizations/[slug]/settings/members/page.tsx +28 -0
  116. package/apps/web/src/app/(dashboard)/organizations/[slug]/settings/page.tsx +10 -0
  117. package/apps/web/src/app/(dashboard)/settings/page.tsx +12 -0
  118. package/apps/web/src/app/dashboard/page.tsx +14 -0
  119. package/apps/web/src/app/favicon.ico +0 -0
  120. package/apps/web/src/app/globals.css +115 -0
  121. package/apps/web/src/app/layout.tsx +36 -0
  122. package/apps/web/src/app/login/page.tsx +199 -0
  123. package/apps/web/src/app/page.tsx +100 -0
  124. package/apps/web/src/app/register/page.tsx +218 -0
  125. package/apps/web/src/components/app-sidebar.tsx +301 -0
  126. package/apps/web/src/components/navbar.tsx +63 -0
  127. package/apps/web/src/components/topNav.tsx +68 -0
  128. package/apps/web/src/components/ui/avatar.tsx +112 -0
  129. package/apps/web/src/components/ui/badge.tsx +48 -0
  130. package/apps/web/src/components/ui/button.tsx +66 -0
  131. package/apps/web/src/components/ui/card.tsx +102 -0
  132. package/apps/web/src/components/ui/checkbox.tsx +32 -0
  133. package/apps/web/src/components/ui/dialog.tsx +168 -0
  134. package/apps/web/src/components/ui/dropdown-menu.tsx +269 -0
  135. package/apps/web/src/components/ui/field.tsx +238 -0
  136. package/apps/web/src/components/ui/input.tsx +19 -0
  137. package/apps/web/src/components/ui/label.tsx +24 -0
  138. package/apps/web/src/components/ui/resizable.tsx +50 -0
  139. package/apps/web/src/components/ui/scroll-area.tsx +55 -0
  140. package/apps/web/src/components/ui/select.tsx +192 -0
  141. package/apps/web/src/components/ui/separator.tsx +28 -0
  142. package/apps/web/src/components/ui/sheet.tsx +147 -0
  143. package/apps/web/src/components/ui/sidebar.tsx +703 -0
  144. package/apps/web/src/components/ui/skeleton.tsx +13 -0
  145. package/apps/web/src/components/ui/switch.tsx +33 -0
  146. package/apps/web/src/components/ui/table.tsx +116 -0
  147. package/apps/web/src/components/ui/tooltip.tsx +57 -0
  148. package/apps/web/src/features/api-docs/api-docs-client.tsx +227 -0
  149. package/apps/web/src/features/api-docs/api-docs-helpers.server.ts +86 -0
  150. package/apps/web/src/features/auth/action.ts +67 -0
  151. package/apps/web/src/features/auth/client.schema.ts +13 -0
  152. package/apps/web/src/features/auth/constants.ts +6 -0
  153. package/apps/web/src/features/auth/cookies.ts +86 -0
  154. package/apps/web/src/features/auth/server.schema.ts +11 -0
  155. package/apps/web/src/features/auth/sign-out.ts +17 -0
  156. package/apps/web/src/features/members/action.ts +66 -0
  157. package/apps/web/src/features/members/client.schema.ts +11 -0
  158. package/apps/web/src/features/members/constants.ts +8 -0
  159. package/apps/web/src/features/members/members-client.tsx +198 -0
  160. package/apps/web/src/features/members/members-helpers.server.ts +21 -0
  161. package/apps/web/src/features/members/server.schema.ts +19 -0
  162. package/apps/web/src/features/organization/action.ts +45 -0
  163. package/apps/web/src/features/organization/client.schema.ts +5 -0
  164. package/apps/web/src/features/organization/constants.tsx +3 -0
  165. package/apps/web/src/features/organization/create-org-form.tsx +66 -0
  166. package/apps/web/src/features/organization/organization-helpers.server.ts +35 -0
  167. package/apps/web/src/features/organization/server.schema.ts +10 -0
  168. package/apps/web/src/features/project-auth/project-auth-action.ts +78 -0
  169. package/apps/web/src/features/project-auth/project-auth-client.schema.ts +18 -0
  170. package/apps/web/src/features/project-auth/project-auth-constants.ts +8 -0
  171. package/apps/web/src/features/project-auth/project-auth-helpers.server.ts +39 -0
  172. package/apps/web/src/features/project-auth/project-auth-providers.tsx +222 -0
  173. package/apps/web/src/features/project-auth/project-auth-server.schema.ts +22 -0
  174. package/apps/web/src/features/project-auth/project-auth-shell.tsx +106 -0
  175. package/apps/web/src/features/project-auth/project-auth-url-config.tsx +151 -0
  176. package/apps/web/src/features/project-auth/project-auth-users.tsx +138 -0
  177. package/apps/web/src/features/projects/action.ts +46 -0
  178. package/apps/web/src/features/projects/client.schema.ts +9 -0
  179. package/apps/web/src/features/projects/constants.ts +6 -0
  180. package/apps/web/src/features/projects/create-project-modal.tsx +117 -0
  181. package/apps/web/src/features/projects/project-helpers.server.ts +38 -0
  182. package/apps/web/src/features/projects/server.schema.ts +10 -0
  183. package/apps/web/src/features/realtime/realtime-client.tsx +294 -0
  184. package/apps/web/src/features/realtime/realtime-helpers.server.ts +40 -0
  185. package/apps/web/src/features/sql-editor/sql-editor-client.tsx +324 -0
  186. package/apps/web/src/features/sql-editor/sql-editor-helpers.server.ts +22 -0
  187. package/apps/web/src/features/storage/storage-client.tsx +500 -0
  188. package/apps/web/src/features/storage/storage-helpers.server.ts +36 -0
  189. package/apps/web/src/features/table-editor/action.ts +97 -0
  190. package/apps/web/src/features/table-editor/add-column-dialog.tsx +184 -0
  191. package/apps/web/src/features/table-editor/client.schema.ts +36 -0
  192. package/apps/web/src/features/table-editor/create-table-drawer.tsx +542 -0
  193. package/apps/web/src/features/table-editor/server.schema.ts +41 -0
  194. package/apps/web/src/features/table-editor/table-editor-client.tsx +737 -0
  195. package/apps/web/src/features/table-editor/table-editor-helpers.server.ts +39 -0
  196. package/apps/web/src/hooks/use-mobile.ts +19 -0
  197. package/apps/web/src/lib/axios.ts +8 -0
  198. package/apps/web/src/lib/utils.ts +6 -0
  199. package/apps/web/src/proxy.ts +72 -0
  200. package/apps/web/src/server-utils/utils.ts +10 -0
  201. package/apps/web/tsconfig.json +34 -0
  202. package/package.json +22 -0
  203. package/packages/apiDatabase-js/package.json +39 -0
  204. package/packages/apiDatabase-js/src/auth/index.ts +121 -0
  205. package/packages/apiDatabase-js/src/client.ts +25 -0
  206. package/packages/apiDatabase-js/src/db/index.ts +15 -0
  207. package/packages/apiDatabase-js/src/db/query-builder.ts +194 -0
  208. package/packages/apiDatabase-js/src/index.ts +16 -0
  209. package/packages/apiDatabase-js/src/realtime/index.ts +84 -0
  210. package/packages/apiDatabase-js/src/storage/index.ts +130 -0
  211. package/packages/apiDatabase-js/tsconfig.json +13 -0
  212. package/packages/apiDatabase-js/tsdown.config.ts +20 -0
  213. package/packages/constants/package.json +6 -0
  214. package/packages/constants/src/index.ts +76 -0
  215. package/packages/tsconfig.json +13 -0
  216. package/packages/tsdown.config.ts +20 -0
  217. package/packages/types/package.json +6 -0
  218. package/packages/types/src/index.ts +254 -0
  219. package/pnpm-workspace.yaml +10 -0
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "web",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --port 3001",
7
+ "build": "next build",
8
+ "start": "next start --port 3001",
9
+ "lint": "eslint"
10
+ },
11
+ "dependencies": {
12
+ "@apiDatabase/constants": "workspace:*",
13
+ "@apiDatabase/types": "workspace:*",
14
+ "@hookform/resolvers": "^5.4.0",
15
+ "@monaco-editor/react": "^4.7.0",
16
+ "@radix-ui/react-scroll-area": "^1.2.13",
17
+ "@tanstack/react-table": "^8.21.3",
18
+ "@uploadthing/react": "^7.3.3",
19
+ "axios": "^1.18.1",
20
+ "class-variance-authority": "^0.7.1",
21
+ "clsx": "^2.1.1",
22
+ "cn": "^0.2.5",
23
+ "jose": "^6.2.3",
24
+ "lucide-react": "^1.17.0",
25
+ "next": "16.3.4",
26
+ "radix-ui": "^1.5.0",
27
+ "react": "19.2.8",
28
+ "react-dom": "19.2.8",
29
+ "react-hook-form": "^7.78.0",
30
+ "react-resizable-panels": "^4.12.1",
31
+ "socket.io-client": "^4.8.3",
32
+ "tailwind-merge": "^3.6.0",
33
+ "tw-animate-css": "^1.4.0",
34
+ "uploadthing": "^7.7.4",
35
+ "zod": "^4.4.3"
36
+ },
37
+ "devDependencies": {
38
+ "@tailwindcss/postcss": "^4",
39
+ "@types/node": "^20",
40
+ "@types/react": "^19",
41
+ "@types/react-dom": "^19",
42
+ "babel-plugin-react-compiler": "1.0.0",
43
+ "eslint": "^9",
44
+ "eslint-config-next": "16.3.4",
45
+ "tailwindcss": "^4",
46
+ "typescript": "^5"
47
+ }
48
+ }
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1,4 @@
1
+ <svg width="44" height="31" viewBox="0 0 44 31" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M29.825 11.829 18.797.805a2.75 2.75 0 0 0-3.89 0L.806 14.9a2.75 2.75 0 0 0 0 3.89l11.028 11.023a2.75 2.75 0 0 0 3.89 0l14.1-14.094a2.75 2.75 0 0 0 0-3.889" fill="#d4d4d8"/>
3
+ <path d="M42.892 11.829 31.863.805a2.75 2.75 0 0 0-3.89 0L13.873 14.9a2.75 2.75 0 0 0 0 3.89L24.9 29.811a2.75 2.75 0 0 0 3.89 0l14.1-14.094a2.75 2.75 0 0 0 0-3.889" fill="#27272a"/>
4
+ </svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -0,0 +1,33 @@
1
+ import { SidebarProvider, SidebarInset } from "@/components/ui/sidebar";
2
+ import { AppSidebar } from "@/components/app-sidebar";
3
+
4
+ import { retrieveTokenFromCookie } from "@/server-utils/utils";
5
+ import { retrieveMyOrganizationsFromApi } from "@/features/organization/organization-helpers.server";
6
+
7
+ async function getCurrentUser() {
8
+ const token = await retrieveTokenFromCookie();
9
+
10
+ const payload = JSON.parse(
11
+ Buffer.from(token.split(".")[1], "base64").toString(),
12
+ );
13
+
14
+ return { email: payload.email as string, name: null };
15
+ }
16
+
17
+ export default async function DashboardLayout({
18
+ children,
19
+ }: {
20
+ children: React.ReactNode;
21
+ }) {
22
+ const [orgs, user] = await Promise.all([
23
+ retrieveMyOrganizationsFromApi(),
24
+ getCurrentUser(),
25
+ ]);
26
+
27
+ return (
28
+ <SidebarProvider>
29
+ <AppSidebar orgs={orgs} user={user} />
30
+ <SidebarInset className="bg-background">{children}</SidebarInset>
31
+ </SidebarProvider>
32
+ );
33
+ }
@@ -0,0 +1,7 @@
1
+ export default function OrganizationsListLayout({
2
+ children,
3
+ }: {
4
+ children: React.ReactNode;
5
+ }) {
6
+ return <main className="flex-1 overflow-y-auto p-6 md:p-8">{children}</main>;
7
+ }
@@ -0,0 +1,26 @@
1
+ import Link from "next/link";
2
+ import { ChevronLeft } from "lucide-react";
3
+ import { CreateOrgForm } from "@/features/organization/create-org-form";
4
+
5
+ export default function NewOrganizationPage() {
6
+ return (
7
+ <div>
8
+ <Link
9
+ href="/organizations"
10
+ className="mb-6 inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
11
+ >
12
+ <ChevronLeft className="size-4" />
13
+ Back to organizations
14
+ </Link>
15
+
16
+ <div className="mb-6">
17
+ <h1 className="text-2xl font-medium">New organization</h1>
18
+ <p className="mt-1 text-sm text-muted-foreground">
19
+ Organizations group projects and team members.
20
+ </p>
21
+ </div>
22
+
23
+ <CreateOrgForm />
24
+ </div>
25
+ );
26
+ }
@@ -0,0 +1,44 @@
1
+ import Link from "next/link";
2
+ import { Plus, Building2 } from "lucide-react";
3
+ import { Button } from "@/components/ui/button";
4
+ import { retrieveMyOrganizationsFromApi } from "@/features/organization/organization-helpers.server";
5
+
6
+ export default async function OrganizationsPage() {
7
+ const orgs = await retrieveMyOrganizationsFromApi();
8
+
9
+ return (
10
+ <div>
11
+ <div className="flex items-center justify-between mb-6">
12
+ <h1 className="text-2xl font-medium">Your Organizations</h1>
13
+ <Button asChild size="sm">
14
+ <Link href="/organizations/new">
15
+ <Plus size={14} className="mr-1.5" />
16
+ New organization
17
+ </Link>
18
+ </Button>
19
+ </div>
20
+
21
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
22
+ {orgs.map((org) => (
23
+ <Link
24
+ key={org.id}
25
+ href={`/organizations/${org.slug}/projects`}
26
+ className="flex items-center gap-4 p-5 rounded-xl border border-border bg-background hover:bg-accent transition-colors"
27
+ >
28
+ <div className="w-10 h-10 rounded-lg bg-muted flex items-center justify-center shrink-0">
29
+ <Building2 size={18} className="text-muted-foreground" />
30
+ </div>
31
+ <div className="min-w-0">
32
+ <p className="font-medium text-sm truncate">{org.name}</p>
33
+ <p className="text-xs text-muted-foreground mt-0.5">
34
+ {org.projectCount}{" "}
35
+ {org.projectCount === 1 ? "project" : "projects"} -{" "}
36
+ {org.memberCount} {org.memberCount === 1 ? "member" : "members"}
37
+ </p>
38
+ </div>
39
+ </Link>
40
+ ))}
41
+ </div>
42
+ </div>
43
+ );
44
+ }
@@ -0,0 +1,13 @@
1
+ import { retrieveApiDocsFromApi } from "@/features/api-docs/api-docs-helpers.server";
2
+ import { ApiDocsClient } from "@/features/api-docs/api-docs-client";
3
+
4
+ export default async function ApiDocsPage({
5
+ params,
6
+ }: {
7
+ params: Promise<{ slug: string; projectSlug: string }>;
8
+ }) {
9
+ const { slug, projectSlug } = await params;
10
+ const docs = await retrieveApiDocsFromApi(slug, projectSlug);
11
+
12
+ return <ApiDocsClient docs={docs} />;
13
+ }
@@ -0,0 +1,19 @@
1
+ import { ProjectAuthShell } from "@/features/project-auth/project-auth-shell";
2
+
3
+ export default async function AuthLayout({
4
+ children,
5
+ params,
6
+ }: {
7
+ children: React.ReactNode;
8
+ params: Promise<{ slug: string; projectSlug: string }>;
9
+ }) {
10
+ const { slug, projectSlug } = await params;
11
+
12
+ return (
13
+ <div className="-mx-6 -mt-6 -mb-6 flex h-[calc(100svh-3rem)] min-h-0 flex-col overflow-hidden">
14
+ <ProjectAuthShell orgSlug={slug} projectSlug={projectSlug}>
15
+ {children}
16
+ </ProjectAuthShell>
17
+ </div>
18
+ );
19
+ }
@@ -0,0 +1,10 @@
1
+ import { redirect } from "next/navigation";
2
+
3
+ export default async function AuthIndexPage({
4
+ params,
5
+ }: {
6
+ params: Promise<{ slug: string; projectSlug: string }>;
7
+ }) {
8
+ const { slug, projectSlug } = await params;
9
+ redirect(`/organizations/${slug}/${projectSlug}/auth/users`);
10
+ }
@@ -0,0 +1,19 @@
1
+ import { retrieveOAuthSettingsFromApi } from "@/features/project-auth/project-auth-helpers.server";
2
+ import { ProjectAuthProviders } from "@/features/project-auth/project-auth-providers";
3
+
4
+ export default async function AuthProvidersPage({
5
+ params,
6
+ }: {
7
+ params: Promise<{ slug: string; projectSlug: string }>;
8
+ }) {
9
+ const { slug, projectSlug } = await params;
10
+ const settings = await retrieveOAuthSettingsFromApi(slug, projectSlug);
11
+
12
+ return (
13
+ <ProjectAuthProviders
14
+ orgSlug={slug}
15
+ projectSlug={projectSlug}
16
+ initialSettings={settings}
17
+ />
18
+ );
19
+ }
@@ -0,0 +1,24 @@
1
+ import { retrieveOAuthSettingsFromApi } from "@/features/project-auth/project-auth-helpers.server";
2
+ import { ProjectAuthUrlConfig } from "@/features/project-auth/project-auth-url-config";
3
+
4
+ export default async function AuthUrlConfigurationPage({
5
+ params,
6
+ }: {
7
+ params: Promise<{ slug: string; projectSlug: string }>;
8
+ }) {
9
+ const { slug, projectSlug } = await params;
10
+ const apiBaseUrl =
11
+ process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000/api";
12
+ const settings = await retrieveOAuthSettingsFromApi(slug, projectSlug);
13
+ const fallbackSiteUrl =
14
+ process.env.NEXT_PUBLIC_WEB_URL ?? "http://localhost:3001";
15
+
16
+ return (
17
+ <ProjectAuthUrlConfig
18
+ orgSlug={slug}
19
+ projectSlug={projectSlug}
20
+ initialSiteUrl={settings.siteUrl ?? fallbackSiteUrl}
21
+ apiBaseUrl={apiBaseUrl}
22
+ />
23
+ );
24
+ }
@@ -0,0 +1,13 @@
1
+ import { retrieveProjectAuthUsersFromApi } from "@/features/project-auth/project-auth-helpers.server";
2
+ import { ProjectAuthUsers } from "@/features/project-auth/project-auth-users";
3
+
4
+ export default async function AuthUsersPage({
5
+ params,
6
+ }: {
7
+ params: Promise<{ slug: string; projectSlug: string }>;
8
+ }) {
9
+ const { slug, projectSlug } = await params;
10
+ const users = await retrieveProjectAuthUsersFromApi(slug, projectSlug);
11
+
12
+ return <ProjectAuthUsers users={users} />;
13
+ }
@@ -0,0 +1,29 @@
1
+ import { TableEditorClient } from "@/features/table-editor/table-editor-client";
2
+ import {
3
+ retrieveTablesFromApi,
4
+ retrieveProjectDbSchema,
5
+ } from "@/features/table-editor/table-editor-helpers.server";
6
+
7
+ export default async function DatabasePage({
8
+ params,
9
+ }: {
10
+ params: Promise<{ slug: string; projectSlug: string }>;
11
+ }) {
12
+ const { slug, projectSlug } = await params;
13
+
14
+ const [tables, dbSchema] = await Promise.all([
15
+ retrieveTablesFromApi(slug, projectSlug),
16
+ retrieveProjectDbSchema(slug, projectSlug),
17
+ ]);
18
+
19
+ return (
20
+ <div className="-mx-6 -mt-6 -mb-6 flex h-[calc(100svh-3rem)] min-h-0 flex-col overflow-hidden">
21
+ <TableEditorClient
22
+ orgSlug={slug}
23
+ projectSlug={projectSlug}
24
+ dbSchema={dbSchema}
25
+ initialTables={tables}
26
+ />
27
+ </div>
28
+ );
29
+ }
@@ -0,0 +1,28 @@
1
+ import {
2
+ retrieveProjectForRealtime,
3
+ retrieveTablesForRealtime,
4
+ } from "@/features/realtime/realtime-helpers.server";
5
+ import { RealtimeClient } from "@/features/realtime/realtime-client";
6
+
7
+ export default async function RealtimePage({
8
+ params,
9
+ }: {
10
+ params: Promise<{ slug: string; projectSlug: string }>;
11
+ }) {
12
+ const { slug, projectSlug } = await params;
13
+
14
+ const [project, tables] = await Promise.all([
15
+ retrieveProjectForRealtime(slug, projectSlug),
16
+ retrieveTablesForRealtime(slug, projectSlug),
17
+ ]);
18
+
19
+ return (
20
+ <RealtimeClient
21
+ orgSlug={slug}
22
+ projectSlug={projectSlug}
23
+ projectId={project.id}
24
+ anonKey={project.anonKey}
25
+ tables={tables}
26
+ />
27
+ );
28
+ }
@@ -0,0 +1,21 @@
1
+ import { retrieveSqlHistoryFromApi } from "@/features/sql-editor/sql-editor-helpers.server";
2
+ import { SqlEditorClient } from "@/features/sql-editor/sql-editor-client";
3
+
4
+ export default async function SqlEditorPage({
5
+ params,
6
+ }: {
7
+ params: Promise<{ slug: string; projectSlug: string }>;
8
+ }) {
9
+ const { slug, projectSlug } = await params;
10
+ const history = await retrieveSqlHistoryFromApi(slug, projectSlug);
11
+
12
+ return (
13
+ <div className="-mx-6 -mt-6 -mb-6 flex h-[calc(100svh-3rem)] min-h-0 flex-col overflow-hidden">
14
+ <SqlEditorClient
15
+ orgSlug={slug}
16
+ projectSlug={projectSlug}
17
+ initialHistory={history}
18
+ />
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,28 @@
1
+ import {
2
+ retrieveBucketsFromApi,
3
+ retrieveObjectsFromApi,
4
+ } from "@/features/storage/storage-helpers.server";
5
+ import { StorageClient } from "@/features/storage/storage-client";
6
+
7
+ export default async function StoragePage({
8
+ params,
9
+ }: {
10
+ params: Promise<{ slug: string; projectSlug: string }>;
11
+ }) {
12
+ const { slug, projectSlug } = await params;
13
+ const buckets = await retrieveBucketsFromApi(slug, projectSlug);
14
+ const initialObjects = buckets[0]
15
+ ? await retrieveObjectsFromApi(slug, projectSlug, buckets[0].id)
16
+ : [];
17
+
18
+ return (
19
+ <div className="-mx-6 -mt-6 -mb-6 flex h-[calc(100svh-3rem)] min-h-0 flex-col overflow-hidden">
20
+ <StorageClient
21
+ orgSlug={slug}
22
+ projectSlug={projectSlug}
23
+ initialBuckets={buckets}
24
+ initialObjects={initialObjects}
25
+ />
26
+ </div>
27
+ );
28
+ }
@@ -0,0 +1,20 @@
1
+ import { TopNav } from "@/components/topNav";
2
+ import { retrieveProjectsFromApi } from "@/features/projects/project-helpers.server";
3
+
4
+ export default async function OrgLayout({
5
+ children,
6
+ params,
7
+ }: {
8
+ children: React.ReactNode;
9
+ params: Promise<{ slug: string }>;
10
+ }) {
11
+ const { slug } = await params;
12
+ const projects = await retrieveProjectsFromApi(slug);
13
+
14
+ return (
15
+ <>
16
+ <TopNav projects={projects} />
17
+ <main className="flex-1 overflow-y-auto p-6">{children}</main>
18
+ </>
19
+ );
20
+ }
@@ -0,0 +1,62 @@
1
+ import Link from "next/link";
2
+ import { Database } from "lucide-react";
3
+ import { retrieveOrganizationBySlugFromApi } from "@/features/organization/organization-helpers.server";
4
+ import { retrieveProjectsFromApi } from "@/features/projects/project-helpers.server";
5
+ import { ORG_ROLES } from "@apiDatabase/constants";
6
+ import { CreateProjectModal } from "@/features/projects/create-project-modal";
7
+
8
+ export default async function ProjectsPage({
9
+ params,
10
+ }: {
11
+ params: Promise<{ slug: string }>;
12
+ }) {
13
+ const { slug } = await params;
14
+
15
+ const [org, projects] = await Promise.all([
16
+ retrieveOrganizationBySlugFromApi(slug),
17
+ retrieveProjectsFromApi(slug),
18
+ ]);
19
+
20
+ const isAdmin = org.role === ORG_ROLES.ADMIN;
21
+
22
+ return (
23
+ <div>
24
+ <div className="flex items-center justify-between mb-6">
25
+ <h1 className="text-2xl font-medium">Projects</h1>
26
+ {isAdmin && <CreateProjectModal slug={slug} />}
27
+ </div>
28
+
29
+ {/* Empty state */}
30
+ {projects.length === 0 ? (
31
+ <div className="flex flex-col items-center justify-center py-24 text-center border border-dashed border-border rounded-xl">
32
+ <p className="text-muted-foreground text-sm">
33
+ No projects yet in {org.name}
34
+ </p>
35
+ <p className="text-muted-foreground text-xs mt-1">
36
+ Create your first project to get started
37
+ </p>
38
+ </div>
39
+ ) : (
40
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
41
+ {projects.map((project) => (
42
+ <Link
43
+ key={project.id}
44
+ href={`/organizations/${slug}/${project.slug}/database`}
45
+ className="flex items-center gap-4 p-5 rounded-xl border border-border bg-background hover:bg-accent transition-colors"
46
+ >
47
+ <div className="w-10 h-10 rounded-lg bg-muted flex items-center justify-center shrink-0">
48
+ <Database size={18} className="text-muted-foreground" />
49
+ </div>
50
+ <div className="min-w-0">
51
+ <p className="font-medium text-sm truncate">{project.name}</p>
52
+ <p className="text-xs text-muted-foreground mt-0.5 truncate">
53
+ {project.projectUrl}
54
+ </p>
55
+ </div>
56
+ </Link>
57
+ ))}
58
+ </div>
59
+ )}
60
+ </div>
61
+ );
62
+ }
@@ -0,0 +1,28 @@
1
+ import { MembersClient } from "@/features/members/members-client";
2
+ import { retrieveMembersFromApi } from "@/features/members/members-helpers.server";
3
+ import { retrieveOrganizationBySlugFromApi } from "@/features/organization/organization-helpers.server";
4
+
5
+ export default async function MembersSettingsPage({
6
+ params,
7
+ }: {
8
+ params: Promise<{ slug: string }>;
9
+ }) {
10
+ const { slug } = await params;
11
+
12
+ const [org, members] = await Promise.all([
13
+ retrieveOrganizationBySlugFromApi(slug),
14
+ retrieveMembersFromApi(slug),
15
+ ]);
16
+
17
+ return (
18
+ <div>
19
+ <div className="mb-6">
20
+ <h1 className="text-2xl font-medium">Members</h1>
21
+ <p className="text-sm text-muted-foreground mt-1">
22
+ Manage who has access to {org.name}
23
+ </p>
24
+ </div>
25
+ <MembersClient slug={slug} members={members} currentUserRole={org.role} />
26
+ </div>
27
+ );
28
+ }
@@ -0,0 +1,10 @@
1
+ import { redirect } from "next/navigation";
2
+
3
+ export default async function OrgSettingsIndexPage({
4
+ params,
5
+ }: {
6
+ params: Promise<{ slug: string }>;
7
+ }) {
8
+ const { slug } = await params;
9
+ redirect(`/organizations/${slug}/settings/members`);
10
+ }
@@ -0,0 +1,12 @@
1
+ import { redirect } from "next/navigation";
2
+ import { retrieveMyOrganizationsFromApi } from "@/features/organization/organization-helpers.server";
3
+
4
+ export default async function SettingsPage() {
5
+ const orgs = await retrieveMyOrganizationsFromApi();
6
+
7
+ if (orgs.length === 0) {
8
+ redirect("/organizations/new");
9
+ }
10
+
11
+ redirect(`/organizations/${orgs[0].slug}/settings/members`);
12
+ }
@@ -0,0 +1,14 @@
1
+ import { redirect } from "next/navigation";
2
+ import { retrieveMyOrganizationsFromApi } from "@/features/organization/organization-helpers.server";
3
+
4
+ export default async function DashboardPage() {
5
+ const orgs = await retrieveMyOrganizationsFromApi();
6
+
7
+ console.log("ORG", orgs);
8
+
9
+ if (orgs.length === 1) {
10
+ redirect(`/organizations/${orgs[0].slug}/projects`);
11
+ }
12
+
13
+ redirect("/organizations");
14
+ }
Binary file