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.
- package/README.md +42 -0
- package/apps/api/.prettierrc +4 -0
- package/apps/api/README.md +98 -0
- package/apps/api/drizzle/0000_right_drax.sql +87 -0
- package/apps/api/drizzle/meta/0000_snapshot.json +588 -0
- package/apps/api/drizzle/meta/_journal.json +13 -0
- package/apps/api/drizzle.config.ts +12 -0
- package/apps/api/eslint.config.mjs +35 -0
- package/apps/api/nest-cli.json +8 -0
- package/apps/api/package.json +99 -0
- package/apps/api/src/app.controller.spec.ts +25 -0
- package/apps/api/src/app.controller.ts +9 -0
- package/apps/api/src/app.module.ts +37 -0
- package/apps/api/src/app.service.ts +8 -0
- package/apps/api/src/auth/auth.controller.ts +113 -0
- package/apps/api/src/auth/auth.module.ts +15 -0
- package/apps/api/src/auth/auth.service.ts +309 -0
- package/apps/api/src/auth/decorators/current-user-decorator.ts +10 -0
- package/apps/api/src/auth/decorators/require-org-role-decorator.ts +7 -0
- package/apps/api/src/auth/dto/login.dto.ts +10 -0
- package/apps/api/src/auth/dto/register.dto.ts +14 -0
- package/apps/api/src/auth/guards/jwt-auth-guard.ts +40 -0
- package/apps/api/src/auth/guards/org-role.guards.ts +60 -0
- package/apps/api/src/db/db.module.ts +9 -0
- package/apps/api/src/db/drizzle.service.ts +16 -0
- package/apps/api/src/db/schema/index.ts +6 -0
- package/apps/api/src/db/schema/organizations.ts +30 -0
- package/apps/api/src/db/schema/projects.ts +26 -0
- package/apps/api/src/db/schema/query-history.ts +16 -0
- package/apps/api/src/db/schema/storage-buckets.ts +17 -0
- package/apps/api/src/db/schema/storage-objects.ts +18 -0
- package/apps/api/src/db/schema/users.ts +14 -0
- package/apps/api/src/main.ts +51 -0
- package/apps/api/src/members/dto/invite-member-dto.ts +6 -0
- package/apps/api/src/members/dto/update-role.dto.ts +8 -0
- package/apps/api/src/members/invite.service.ts +147 -0
- package/apps/api/src/members/members.controller.ts +56 -0
- package/apps/api/src/members/members.module.ts +13 -0
- package/apps/api/src/members/members.service.ts +85 -0
- package/apps/api/src/orgs/dto/create-org.dto.ts +8 -0
- package/apps/api/src/orgs/orgs.controller.ts +27 -0
- package/apps/api/src/orgs/orgs.module.ts +12 -0
- package/apps/api/src/orgs/orgs.service.ts +86 -0
- package/apps/api/src/project-api/project-api.controller.ts +95 -0
- package/apps/api/src/project-api/project-api.module.ts +12 -0
- package/apps/api/src/project-api/project-api.service.ts +196 -0
- package/apps/api/src/project-api/project-key.guard.ts +45 -0
- package/apps/api/src/project-api/query-parser.ts +129 -0
- package/apps/api/src/project-auth/dto/magic-link.dto.ts +7 -0
- package/apps/api/src/project-auth/dto/signin.dto.ts +10 -0
- package/apps/api/src/project-auth/dto/signup.dto.ts +11 -0
- package/apps/api/src/project-auth/project-auth-dashboard.controller.ts +35 -0
- package/apps/api/src/project-auth/project-auth.controller.ts +111 -0
- package/apps/api/src/project-auth/project-auth.module.ts +13 -0
- package/apps/api/src/project-auth/project-auth.service.ts +440 -0
- package/apps/api/src/projects/dto/create-project.dto.ts +9 -0
- package/apps/api/src/projects/projects.controller.ts +34 -0
- package/apps/api/src/projects/projects.module.ts +12 -0
- package/apps/api/src/projects/projects.service.ts +136 -0
- package/apps/api/src/realtime/realtime-socket.type.ts +14 -0
- package/apps/api/src/realtime/realtime.controller.ts +63 -0
- package/apps/api/src/realtime/realtime.gateway.ts +150 -0
- package/apps/api/src/realtime/realtime.module.ts +14 -0
- package/apps/api/src/realtime/realtime.service.ts +101 -0
- package/apps/api/src/realtime/trigger.service.ts +95 -0
- package/apps/api/src/sql-editor/dto/execute-query.dto.ts +7 -0
- package/apps/api/src/sql-editor/sql-editor.controller.ts +28 -0
- package/apps/api/src/sql-editor/sql-editor.module.ts +12 -0
- package/apps/api/src/sql-editor/sql-editor.service.ts +154 -0
- package/apps/api/src/storage/project-storage.controller.ts +140 -0
- package/apps/api/src/storage/storage.controller.ts +118 -0
- package/apps/api/src/storage/storage.module.ts +15 -0
- package/apps/api/src/storage/storage.service.ts +191 -0
- package/apps/api/src/storage/uploadthing.ts +23 -0
- package/apps/api/src/table-editor/dto/alter-table.dto.ts +15 -0
- package/apps/api/src/table-editor/dto/create-table.dto.ts +54 -0
- package/apps/api/src/table-editor/table-editor.controller.ts +117 -0
- package/apps/api/src/table-editor/table-editor.module.ts +12 -0
- package/apps/api/src/table-editor/table-editor.service.ts +366 -0
- package/apps/api/test/app.e2e-spec.ts +29 -0
- package/apps/api/test/jest-e2e.json +9 -0
- package/apps/api/tsconfig.build.json +4 -0
- package/apps/api/tsconfig.json +25 -0
- package/apps/web/.env.example +12 -0
- package/apps/web/AGENTS.md +9 -0
- package/apps/web/CLAUDE.md +1 -0
- package/apps/web/README.md +36 -0
- package/apps/web/components.json +25 -0
- package/apps/web/eslint.config.mjs +18 -0
- package/apps/web/next.config.ts +11 -0
- package/apps/web/package.json +48 -0
- package/apps/web/postcss.config.mjs +7 -0
- package/apps/web/public/file.svg +1 -0
- package/apps/web/public/globe.svg +1 -0
- package/apps/web/public/logo.svg +4 -0
- package/apps/web/public/next.svg +1 -0
- package/apps/web/public/vercel.svg +1 -0
- package/apps/web/public/window.svg +1 -0
- package/apps/web/src/app/(dashboard)/layout.tsx +33 -0
- package/apps/web/src/app/(dashboard)/organizations/(list)/layout.tsx +7 -0
- package/apps/web/src/app/(dashboard)/organizations/(list)/new/page.tsx +26 -0
- package/apps/web/src/app/(dashboard)/organizations/(list)/page.tsx +44 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/api/page.tsx +13 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/layout.tsx +19 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/page.tsx +10 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/providers/page.tsx +19 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/url-configuration/page.tsx +24 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/users/page.tsx +13 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/database/page.tsx +29 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/realtime/page.tsx +28 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/sql/page.tsx +21 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/storage/page.tsx +28 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/layout.tsx +20 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/projects/page.tsx +62 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/settings/members/page.tsx +28 -0
- package/apps/web/src/app/(dashboard)/organizations/[slug]/settings/page.tsx +10 -0
- package/apps/web/src/app/(dashboard)/settings/page.tsx +12 -0
- package/apps/web/src/app/dashboard/page.tsx +14 -0
- package/apps/web/src/app/favicon.ico +0 -0
- package/apps/web/src/app/globals.css +115 -0
- package/apps/web/src/app/layout.tsx +36 -0
- package/apps/web/src/app/login/page.tsx +199 -0
- package/apps/web/src/app/page.tsx +100 -0
- package/apps/web/src/app/register/page.tsx +218 -0
- package/apps/web/src/components/app-sidebar.tsx +301 -0
- package/apps/web/src/components/navbar.tsx +63 -0
- package/apps/web/src/components/topNav.tsx +68 -0
- package/apps/web/src/components/ui/avatar.tsx +112 -0
- package/apps/web/src/components/ui/badge.tsx +48 -0
- package/apps/web/src/components/ui/button.tsx +66 -0
- package/apps/web/src/components/ui/card.tsx +102 -0
- package/apps/web/src/components/ui/checkbox.tsx +32 -0
- package/apps/web/src/components/ui/dialog.tsx +168 -0
- package/apps/web/src/components/ui/dropdown-menu.tsx +269 -0
- package/apps/web/src/components/ui/field.tsx +238 -0
- package/apps/web/src/components/ui/input.tsx +19 -0
- package/apps/web/src/components/ui/label.tsx +24 -0
- package/apps/web/src/components/ui/resizable.tsx +50 -0
- package/apps/web/src/components/ui/scroll-area.tsx +55 -0
- package/apps/web/src/components/ui/select.tsx +192 -0
- package/apps/web/src/components/ui/separator.tsx +28 -0
- package/apps/web/src/components/ui/sheet.tsx +147 -0
- package/apps/web/src/components/ui/sidebar.tsx +703 -0
- package/apps/web/src/components/ui/skeleton.tsx +13 -0
- package/apps/web/src/components/ui/switch.tsx +33 -0
- package/apps/web/src/components/ui/table.tsx +116 -0
- package/apps/web/src/components/ui/tooltip.tsx +57 -0
- package/apps/web/src/features/api-docs/api-docs-client.tsx +227 -0
- package/apps/web/src/features/api-docs/api-docs-helpers.server.ts +86 -0
- package/apps/web/src/features/auth/action.ts +67 -0
- package/apps/web/src/features/auth/client.schema.ts +13 -0
- package/apps/web/src/features/auth/constants.ts +6 -0
- package/apps/web/src/features/auth/cookies.ts +86 -0
- package/apps/web/src/features/auth/server.schema.ts +11 -0
- package/apps/web/src/features/auth/sign-out.ts +17 -0
- package/apps/web/src/features/members/action.ts +66 -0
- package/apps/web/src/features/members/client.schema.ts +11 -0
- package/apps/web/src/features/members/constants.ts +8 -0
- package/apps/web/src/features/members/members-client.tsx +198 -0
- package/apps/web/src/features/members/members-helpers.server.ts +21 -0
- package/apps/web/src/features/members/server.schema.ts +19 -0
- package/apps/web/src/features/organization/action.ts +45 -0
- package/apps/web/src/features/organization/client.schema.ts +5 -0
- package/apps/web/src/features/organization/constants.tsx +3 -0
- package/apps/web/src/features/organization/create-org-form.tsx +66 -0
- package/apps/web/src/features/organization/organization-helpers.server.ts +35 -0
- package/apps/web/src/features/organization/server.schema.ts +10 -0
- package/apps/web/src/features/project-auth/project-auth-action.ts +78 -0
- package/apps/web/src/features/project-auth/project-auth-client.schema.ts +18 -0
- package/apps/web/src/features/project-auth/project-auth-constants.ts +8 -0
- package/apps/web/src/features/project-auth/project-auth-helpers.server.ts +39 -0
- package/apps/web/src/features/project-auth/project-auth-providers.tsx +222 -0
- package/apps/web/src/features/project-auth/project-auth-server.schema.ts +22 -0
- package/apps/web/src/features/project-auth/project-auth-shell.tsx +106 -0
- package/apps/web/src/features/project-auth/project-auth-url-config.tsx +151 -0
- package/apps/web/src/features/project-auth/project-auth-users.tsx +138 -0
- package/apps/web/src/features/projects/action.ts +46 -0
- package/apps/web/src/features/projects/client.schema.ts +9 -0
- package/apps/web/src/features/projects/constants.ts +6 -0
- package/apps/web/src/features/projects/create-project-modal.tsx +117 -0
- package/apps/web/src/features/projects/project-helpers.server.ts +38 -0
- package/apps/web/src/features/projects/server.schema.ts +10 -0
- package/apps/web/src/features/realtime/realtime-client.tsx +294 -0
- package/apps/web/src/features/realtime/realtime-helpers.server.ts +40 -0
- package/apps/web/src/features/sql-editor/sql-editor-client.tsx +324 -0
- package/apps/web/src/features/sql-editor/sql-editor-helpers.server.ts +22 -0
- package/apps/web/src/features/storage/storage-client.tsx +500 -0
- package/apps/web/src/features/storage/storage-helpers.server.ts +36 -0
- package/apps/web/src/features/table-editor/action.ts +97 -0
- package/apps/web/src/features/table-editor/add-column-dialog.tsx +184 -0
- package/apps/web/src/features/table-editor/client.schema.ts +36 -0
- package/apps/web/src/features/table-editor/create-table-drawer.tsx +542 -0
- package/apps/web/src/features/table-editor/server.schema.ts +41 -0
- package/apps/web/src/features/table-editor/table-editor-client.tsx +737 -0
- package/apps/web/src/features/table-editor/table-editor-helpers.server.ts +39 -0
- package/apps/web/src/hooks/use-mobile.ts +19 -0
- package/apps/web/src/lib/axios.ts +8 -0
- package/apps/web/src/lib/utils.ts +6 -0
- package/apps/web/src/proxy.ts +72 -0
- package/apps/web/src/server-utils/utils.ts +10 -0
- package/apps/web/tsconfig.json +34 -0
- package/package.json +22 -0
- package/packages/apiDatabase-js/package.json +39 -0
- package/packages/apiDatabase-js/src/auth/index.ts +121 -0
- package/packages/apiDatabase-js/src/client.ts +25 -0
- package/packages/apiDatabase-js/src/db/index.ts +15 -0
- package/packages/apiDatabase-js/src/db/query-builder.ts +194 -0
- package/packages/apiDatabase-js/src/index.ts +16 -0
- package/packages/apiDatabase-js/src/realtime/index.ts +84 -0
- package/packages/apiDatabase-js/src/storage/index.ts +130 -0
- package/packages/apiDatabase-js/tsconfig.json +13 -0
- package/packages/apiDatabase-js/tsdown.config.ts +20 -0
- package/packages/constants/package.json +6 -0
- package/packages/constants/src/index.ts +76 -0
- package/packages/tsconfig.json +13 -0
- package/packages/tsdown.config.ts +20 -0
- package/packages/types/package.json +6 -0
- package/packages/types/src/index.ts +254 -0
- 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 @@
|
|
|
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,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
|
+
}
|
package/apps/web/src/app/(dashboard)/organizations/[slug]/[projectSlug]/auth/providers/page.tsx
ADDED
|
@@ -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,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
|