insforge 0.3.1

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 (395) hide show
  1. package/.dockerignore +58 -0
  2. package/.env.example +49 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.yml +79 -0
  6. package/.github/copilot-instructions.md +147 -0
  7. package/.github/workflows/build-image.yml +65 -0
  8. package/.github/workflows/ci-premerge-check.yml +24 -0
  9. package/.github/workflows/deploy-aws.yml +130 -0
  10. package/.github/workflows/lint-and-format.yml +33 -0
  11. package/.prettierignore +65 -0
  12. package/.prettierrc +9 -0
  13. package/CHANGELOG.md +3 -0
  14. package/CONTRIBUTING.md +126 -0
  15. package/Dockerfile +27 -0
  16. package/GITHUB_OAUTH_SETUP.md +49 -0
  17. package/GOOGLE_OAUTH_SETUP.md +148 -0
  18. package/LICENSE +201 -0
  19. package/README.md +134 -0
  20. package/assets/Dark.svg +23 -0
  21. package/assets/archDiagram.png +0 -0
  22. package/assets/banner.png +0 -0
  23. package/assets/mcpInstallv2.png +0 -0
  24. package/assets/sampleResponse.png +0 -0
  25. package/assets/signin.png +0 -0
  26. package/assets/userflow.png +0 -0
  27. package/backend/migrations/000_create-base-tables.sql +142 -0
  28. package/backend/migrations/001_create-helper-functions.sql +41 -0
  29. package/backend/migrations/002_rename-auth-tables.sql +30 -0
  30. package/backend/migrations/003_create-users-table.sql +56 -0
  31. package/backend/migrations/004_add-reload-postgrest-func.sql +24 -0
  32. package/backend/migrations/005_enable-project-admin-modify-users.sql +30 -0
  33. package/backend/migrations/006_modify-ai-usage-table.sql +25 -0
  34. package/backend/migrations/007_drop-metadata-table.sql +2 -0
  35. package/backend/migrations/008_add-system-tables.sql +77 -0
  36. package/backend/migrations/009_add-function-secrets.sql +24 -0
  37. package/backend/migrations/010_modify-ai-config-modalities.sql +93 -0
  38. package/backend/migrations/011_refactor-secrets-table.sql +15 -0
  39. package/backend/migrations/012_add-storage-uploaded-by.sql +8 -0
  40. package/backend/package.json +75 -0
  41. package/backend/src/api/middleware/auth.ts +240 -0
  42. package/backend/src/api/middleware/error.ts +231 -0
  43. package/backend/src/api/middleware/upload.ts +59 -0
  44. package/backend/src/api/routes/agent.ts +29 -0
  45. package/backend/src/api/routes/ai.ts +472 -0
  46. package/backend/src/api/routes/auth.oauth.ts +482 -0
  47. package/backend/src/api/routes/auth.ts +386 -0
  48. package/backend/src/api/routes/database.advance.ts +275 -0
  49. package/backend/src/api/routes/database.records.ts +246 -0
  50. package/backend/src/api/routes/database.tables.ts +161 -0
  51. package/backend/src/api/routes/docs.ts +66 -0
  52. package/backend/src/api/routes/functions.ts +183 -0
  53. package/backend/src/api/routes/logs.ts +150 -0
  54. package/backend/src/api/routes/metadata.ts +160 -0
  55. package/backend/src/api/routes/openapi.ts +82 -0
  56. package/backend/src/api/routes/secrets.ts +199 -0
  57. package/backend/src/api/routes/storage.ts +547 -0
  58. package/backend/src/api/routes/usage.ts +96 -0
  59. package/backend/src/core/ai/chat.ts +207 -0
  60. package/backend/src/core/ai/client.ts +242 -0
  61. package/backend/src/core/ai/config.ts +187 -0
  62. package/backend/src/core/ai/image.ts +156 -0
  63. package/backend/src/core/ai/model.ts +117 -0
  64. package/backend/src/core/ai/usage.ts +290 -0
  65. package/backend/src/core/auth/auth.ts +781 -0
  66. package/backend/src/core/auth/oauth.ts +398 -0
  67. package/backend/src/core/database/advance.ts +1074 -0
  68. package/backend/src/core/database/manager.ts +178 -0
  69. package/backend/src/core/database/table.ts +772 -0
  70. package/backend/src/core/documentation/agent.ts +689 -0
  71. package/backend/src/core/documentation/openapi.ts +856 -0
  72. package/backend/src/core/functions/functions.ts +310 -0
  73. package/backend/src/core/logs/analytics.ts +76 -0
  74. package/backend/src/core/logs/audit.ts +255 -0
  75. package/backend/src/core/logs/providers/base.provider.ts +83 -0
  76. package/backend/src/core/logs/providers/cloudwatch.provider.ts +510 -0
  77. package/backend/src/core/logs/providers/localdb.provider.ts +246 -0
  78. package/backend/src/core/secrets/encryption.ts +58 -0
  79. package/backend/src/core/secrets/secrets.ts +410 -0
  80. package/backend/src/core/socket/socket.ts +388 -0
  81. package/backend/src/core/socket/types.ts +79 -0
  82. package/backend/src/core/storage/storage.ts +923 -0
  83. package/backend/src/server.ts +288 -0
  84. package/backend/src/types/ai.ts +46 -0
  85. package/backend/src/types/auth.ts +90 -0
  86. package/backend/src/types/database.ts +136 -0
  87. package/backend/src/types/error-constants.ts +86 -0
  88. package/backend/src/types/logs.ts +47 -0
  89. package/backend/src/types/profile.ts +55 -0
  90. package/backend/src/types/storage.ts +23 -0
  91. package/backend/src/utils/cloud-token.ts +39 -0
  92. package/backend/src/utils/constants.ts +1 -0
  93. package/backend/src/utils/environment.ts +35 -0
  94. package/backend/src/utils/helpers.ts +49 -0
  95. package/backend/src/utils/logger.ts +13 -0
  96. package/backend/src/utils/response.ts +62 -0
  97. package/backend/src/utils/seed.ts +205 -0
  98. package/backend/src/utils/sql-parser.ts +63 -0
  99. package/backend/src/utils/uuid.ts +9 -0
  100. package/backend/src/utils/validations.ts +129 -0
  101. package/backend/tests/README.md +134 -0
  102. package/backend/tests/cleanup-all-test-data.sh +231 -0
  103. package/backend/tests/cloud/test-s3-multitenant.sh +132 -0
  104. package/backend/tests/local/comprehensive-curl-tests.sh +156 -0
  105. package/backend/tests/local/test-auth-router.sh +144 -0
  106. package/backend/tests/local/test-database-router.sh +222 -0
  107. package/backend/tests/local/test-e2e.sh +241 -0
  108. package/backend/tests/local/test-fk-errors.sh +97 -0
  109. package/backend/tests/local/test-id-field.sh +201 -0
  110. package/backend/tests/local/test-public-bucket.sh +265 -0
  111. package/backend/tests/local/test-secrets.sh +248 -0
  112. package/backend/tests/local/test-serverless-functions.sh.disabled +325 -0
  113. package/backend/tests/local/test-traditional-rest.sh +209 -0
  114. package/backend/tests/manual/README.md +51 -0
  115. package/backend/tests/manual/create-large-table-simple.sql +11 -0
  116. package/backend/tests/manual/seed-large-table.sql +101 -0
  117. package/backend/tests/manual/setup-large-table-extras.sql +34 -0
  118. package/backend/tests/manual/test-better-auth.sh +303 -0
  119. package/backend/tests/manual/test-bulk-upsert.sh +410 -0
  120. package/backend/tests/manual/test-database-advance.sh +297 -0
  121. package/backend/tests/manual/test-postgrest-stability.sh +192 -0
  122. package/backend/tests/manual/test-rawsql-export-import.sh +412 -0
  123. package/backend/tests/manual/test-universal-storage.sh +264 -0
  124. package/backend/tests/manual/test-users.sql +18 -0
  125. package/backend/tests/run-all-tests.sh +140 -0
  126. package/backend/tests/setup.ts +22 -0
  127. package/backend/tests/test-config.sh +303 -0
  128. package/backend/tsconfig.json +23 -0
  129. package/backend/tsup.config.ts +18 -0
  130. package/backend/vitest.config.ts +22 -0
  131. package/docker-compose.prod.yml +145 -0
  132. package/docker-compose.yml +167 -0
  133. package/docker-init/db/db-init.sql +125 -0
  134. package/docker-init/db/jwt.sql +5 -0
  135. package/docker-init/db/logs.sql +9 -0
  136. package/docker-init/db/postgresql.conf +17 -0
  137. package/docs/deprecated/insforge-auth-api.md +215 -0
  138. package/docs/deprecated/insforge-auth-sdk.md +100 -0
  139. package/docs/deprecated/insforge-db-api.md +359 -0
  140. package/docs/deprecated/insforge-db-sdk.md +140 -0
  141. package/docs/deprecated/insforge-debug-sdk.md +157 -0
  142. package/docs/deprecated/insforge-debug.md +65 -0
  143. package/docs/deprecated/insforge-instructions.md +124 -0
  144. package/docs/deprecated/insforge-project.md +118 -0
  145. package/docs/deprecated/insforge-storage-api.md +279 -0
  146. package/docs/deprecated/insforge-storage-sdk.md +159 -0
  147. package/docs/insforge-instructions-sdk.md +407 -0
  148. package/eslint.config.js +317 -0
  149. package/examples/oauth/frontend-oauth-example.html +251 -0
  150. package/examples/response-examples.md +444 -0
  151. package/frontend/README.md +112 -0
  152. package/frontend/components.json +17 -0
  153. package/frontend/index.html +13 -0
  154. package/frontend/package.json +63 -0
  155. package/frontend/public/favicon.ico +0 -0
  156. package/frontend/src/App.tsx +106 -0
  157. package/frontend/src/assets/icons/checkbox_checked.svg +6 -0
  158. package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -0
  159. package/frontend/src/assets/icons/checked.svg +3 -0
  160. package/frontend/src/assets/icons/error.svg +3 -0
  161. package/frontend/src/assets/icons/pencil.svg +4 -0
  162. package/frontend/src/assets/icons/refresh.svg +4 -0
  163. package/frontend/src/assets/icons/step_active.svg +3 -0
  164. package/frontend/src/assets/icons/step_inactive.svg +11 -0
  165. package/frontend/src/assets/icons/warning.svg +3 -0
  166. package/frontend/src/assets/logos/amazon.svg +1 -0
  167. package/frontend/src/assets/logos/claude_code.svg +3 -0
  168. package/frontend/src/assets/logos/cline.svg +6 -0
  169. package/frontend/src/assets/logos/cursor.svg +20 -0
  170. package/frontend/src/assets/logos/discord.svg +9 -0
  171. package/frontend/src/assets/logos/gemini.svg +19 -0
  172. package/frontend/src/assets/logos/github.svg +5 -0
  173. package/frontend/src/assets/logos/google.svg +13 -0
  174. package/frontend/src/assets/logos/grok.svg +10 -0
  175. package/frontend/src/assets/logos/insforge_dark.svg +15 -0
  176. package/frontend/src/assets/logos/insforge_light.svg +15 -0
  177. package/frontend/src/assets/logos/openai.svg +10 -0
  178. package/frontend/src/assets/logos/roo_code.svg +9 -0
  179. package/frontend/src/assets/logos/trae.svg +3 -0
  180. package/frontend/src/assets/logos/windsurf.svg +10 -0
  181. package/frontend/src/components/ButtonWithLoading.tsx +27 -0
  182. package/frontend/src/components/Checkbox.tsx +61 -0
  183. package/frontend/src/components/CodeBlock.tsx +32 -0
  184. package/frontend/src/components/ConfirmDialog.tsx +96 -0
  185. package/frontend/src/components/CopyButton.tsx +69 -0
  186. package/frontend/src/components/DeleteActionButton.tsx +42 -0
  187. package/frontend/src/components/EmptyState.tsx +41 -0
  188. package/frontend/src/components/ErrorState.tsx +35 -0
  189. package/frontend/src/components/FeatureSidebar.tsx +126 -0
  190. package/frontend/src/components/FeatureSidebarItem.tsx +101 -0
  191. package/frontend/src/components/JsonHighlight.tsx +61 -0
  192. package/frontend/src/components/LoadingState.tsx +16 -0
  193. package/frontend/src/components/PaginationControls.tsx +54 -0
  194. package/frontend/src/components/PromptDialog.tsx +68 -0
  195. package/frontend/src/components/SearchInput.tsx +90 -0
  196. package/frontend/src/components/SelectionClearButton.tsx +26 -0
  197. package/frontend/src/components/Stepper.tsx +139 -0
  198. package/frontend/src/components/ThemeToggle.tsx +58 -0
  199. package/frontend/src/components/TypeBadge.tsx +20 -0
  200. package/frontend/src/components/datagrid/DataGrid.tsx +264 -0
  201. package/frontend/src/components/datagrid/DefaultCellRenderer.tsx +114 -0
  202. package/frontend/src/components/datagrid/IdCell.tsx +44 -0
  203. package/frontend/src/components/datagrid/SortableHeader.tsx +74 -0
  204. package/frontend/src/components/datagrid/cell-editors/BooleanCellEditor.tsx +54 -0
  205. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +483 -0
  206. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +362 -0
  207. package/frontend/src/components/datagrid/cell-editors/TextCellEditor.tsx +38 -0
  208. package/frontend/src/components/datagrid/cell-editors/index.ts +14 -0
  209. package/frontend/src/components/datagrid/cell-editors/types.ts +43 -0
  210. package/frontend/src/components/datagrid/datagridTypes.tsx +72 -0
  211. package/frontend/src/components/datagrid/index.tsx +20 -0
  212. package/frontend/src/components/index.ts +39 -0
  213. package/frontend/src/components/layout/AppHeader.tsx +146 -0
  214. package/frontend/src/components/layout/AppSidebar.tsx +190 -0
  215. package/frontend/src/components/layout/CloudLayout.tsx +95 -0
  216. package/frontend/src/components/layout/Layout.tsx +43 -0
  217. package/frontend/src/components/radix/Alert.tsx +45 -0
  218. package/frontend/src/components/radix/AlertDialog.tsx +115 -0
  219. package/frontend/src/components/radix/Avatar.tsx +45 -0
  220. package/frontend/src/components/radix/Badge.tsx +33 -0
  221. package/frontend/src/components/radix/Button.tsx +50 -0
  222. package/frontend/src/components/radix/Card.tsx +58 -0
  223. package/frontend/src/components/radix/Dialog.tsx +98 -0
  224. package/frontend/src/components/radix/DropdownMenu.tsx +185 -0
  225. package/frontend/src/components/radix/Form.tsx +167 -0
  226. package/frontend/src/components/radix/Input.tsx +22 -0
  227. package/frontend/src/components/radix/Label.tsx +19 -0
  228. package/frontend/src/components/radix/Popover.tsx +29 -0
  229. package/frontend/src/components/radix/ScrollArea.tsx +44 -0
  230. package/frontend/src/components/radix/Select.tsx +151 -0
  231. package/frontend/src/components/radix/Separator.tsx +26 -0
  232. package/frontend/src/components/radix/Sheet.tsx +119 -0
  233. package/frontend/src/components/radix/Skeleton.tsx +7 -0
  234. package/frontend/src/components/radix/Switch.tsx +29 -0
  235. package/frontend/src/components/radix/Tabs.tsx +50 -0
  236. package/frontend/src/components/radix/Textarea.tsx +21 -0
  237. package/frontend/src/components/radix/Tooltip.tsx +28 -0
  238. package/frontend/src/features/ai/components/AIConfigCard.tsx +154 -0
  239. package/frontend/src/features/ai/components/AIConfigDialog.tsx +76 -0
  240. package/frontend/src/features/ai/components/AIConfigForm.tsx +222 -0
  241. package/frontend/src/features/ai/components/AIEmptyState.tsx +18 -0
  242. package/frontend/src/features/ai/components/fields/ModalityField.tsx +87 -0
  243. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +134 -0
  244. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +33 -0
  245. package/frontend/src/features/ai/helpers.ts +155 -0
  246. package/frontend/src/features/ai/hooks/useAIConfigs.ts +221 -0
  247. package/frontend/src/features/ai/hooks/useAIUsage.ts +77 -0
  248. package/frontend/src/features/ai/page/AIPage.tsx +178 -0
  249. package/frontend/src/features/ai/services/ai.service.ts +148 -0
  250. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +106 -0
  251. package/frontend/src/features/auth/components/AuthMethodTab.tsx +238 -0
  252. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +303 -0
  253. package/frontend/src/features/auth/components/OAuthEmptyState.tsx +15 -0
  254. package/frontend/src/features/auth/components/UserFormDialog.tsx +248 -0
  255. package/frontend/src/features/auth/components/UsersDataGrid.tsx +183 -0
  256. package/frontend/src/features/auth/components/UsersTab.tsx +114 -0
  257. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +129 -0
  258. package/frontend/src/features/auth/hooks/useUsers.ts +57 -0
  259. package/frontend/src/features/auth/index.ts +9 -0
  260. package/frontend/src/features/auth/page/AuthenticationPage.tsx +169 -0
  261. package/frontend/src/features/auth/services/auth.service.ts +112 -0
  262. package/frontend/src/features/auth/services/oauth.service.ts +49 -0
  263. package/frontend/src/features/dashboard/page/DashboardPage.tsx +194 -0
  264. package/frontend/src/features/database/components/ColumnTypeSelect.tsx +64 -0
  265. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +282 -0
  266. package/frontend/src/features/database/components/ForeignKeyCell.tsx +187 -0
  267. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +378 -0
  268. package/frontend/src/features/database/components/LinkRecordModal.tsx +288 -0
  269. package/frontend/src/features/database/components/RecordFormDialog.tsx +164 -0
  270. package/frontend/src/features/database/components/RecordFormField.tsx +568 -0
  271. package/frontend/src/features/database/components/TableEmptyState.tsx +21 -0
  272. package/frontend/src/features/database/components/TableForm.tsx +656 -0
  273. package/frontend/src/features/database/components/TableFormColumn.tsx +137 -0
  274. package/frontend/src/features/database/components/TableListSkeleton.tsx +9 -0
  275. package/frontend/src/features/database/components/TableSidebar.tsx +47 -0
  276. package/frontend/src/features/database/constants.ts +26 -0
  277. package/frontend/src/features/database/helpers.ts +125 -0
  278. package/frontend/src/features/database/hooks/UseLinkModal.tsx +78 -0
  279. package/frontend/src/features/database/index.ts +12 -0
  280. package/frontend/src/features/database/page/DatabasePage.tsx +626 -0
  281. package/frontend/src/features/database/schema.ts +25 -0
  282. package/frontend/src/features/database/services/database.service.ts +216 -0
  283. package/frontend/src/features/functions/components/FunctionEmptyState.tsx +15 -0
  284. package/frontend/src/features/functions/components/FunctionRow.tsx +71 -0
  285. package/frontend/src/features/functions/components/FunctionViewer.tsx +46 -0
  286. package/frontend/src/features/functions/components/FunctionsContent.tsx +88 -0
  287. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +56 -0
  288. package/frontend/src/features/functions/components/SecretEmptyState.tsx +23 -0
  289. package/frontend/src/features/functions/components/SecretRow.tsx +68 -0
  290. package/frontend/src/features/functions/components/SecretsContent.tsx +120 -0
  291. package/frontend/src/features/functions/hooks/useFunctions.ts +106 -0
  292. package/frontend/src/features/functions/page/FunctionsPage.tsx +28 -0
  293. package/frontend/src/features/functions/services/functions.service.ts +48 -0
  294. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +87 -0
  295. package/frontend/src/features/login/components/PrivateRoute.tsx +24 -0
  296. package/frontend/src/features/login/page/CloudLoginPage.tsx +93 -0
  297. package/frontend/src/features/login/page/LoginPage.tsx +174 -0
  298. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +313 -0
  299. package/frontend/src/features/logs/components/LogsTable.tsx +199 -0
  300. package/frontend/src/features/logs/hooks/useAuditLogs.ts +39 -0
  301. package/frontend/src/features/logs/index.ts +5 -0
  302. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +530 -0
  303. package/frontend/src/features/logs/page/AuditsPage.tsx +192 -0
  304. package/frontend/src/features/logs/services/log.service.ts +171 -0
  305. package/frontend/src/features/metadata/hooks/useMetadata.ts +53 -0
  306. package/frontend/src/features/metadata/index.ts +0 -0
  307. package/frontend/src/features/metadata/page/MetadataPage.tsx +136 -0
  308. package/frontend/src/features/metadata/services/metadata.service.ts +17 -0
  309. package/frontend/src/features/onboard/components/CompletionCard.tsx +41 -0
  310. package/frontend/src/features/onboard/components/OnboardButton.tsx +84 -0
  311. package/frontend/src/features/onboard/components/StepContent.tsx +91 -0
  312. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +53 -0
  313. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +35 -0
  314. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +144 -0
  315. package/frontend/src/features/onboard/components/mcp/index.ts +4 -0
  316. package/frontend/src/features/onboard/components/mcp/mcp-helper.tsx +98 -0
  317. package/frontend/src/features/onboard/index.ts +3 -0
  318. package/frontend/src/features/onboard/page/OnBoardPage.tsx +104 -0
  319. package/frontend/src/features/onboard/types.ts +8 -0
  320. package/frontend/src/features/secrets/hooks/useSecrets.ts +139 -0
  321. package/frontend/src/features/secrets/services/secrets.service.ts +57 -0
  322. package/frontend/src/features/storage/components/BucketEmptyState.tsx +19 -0
  323. package/frontend/src/features/storage/components/BucketFormDialog.tsx +194 -0
  324. package/frontend/src/features/storage/components/BucketListSkeleton.tsx +17 -0
  325. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +287 -0
  326. package/frontend/src/features/storage/components/StorageDataGrid.tsx +239 -0
  327. package/frontend/src/features/storage/components/StorageManager.tsx +236 -0
  328. package/frontend/src/features/storage/components/StorageSidebar.tsx +44 -0
  329. package/frontend/src/features/storage/components/UploadToast.tsx +46 -0
  330. package/frontend/src/features/storage/index.ts +3 -0
  331. package/frontend/src/features/storage/page/StoragePage.tsx +553 -0
  332. package/frontend/src/features/storage/services/storage.service.ts +144 -0
  333. package/frontend/src/features/visualizer/components/AuthNode.tsx +107 -0
  334. package/frontend/src/features/visualizer/components/BucketNode.tsx +34 -0
  335. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +359 -0
  336. package/frontend/src/features/visualizer/components/TableNode.tsx +152 -0
  337. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +24 -0
  338. package/frontend/src/features/visualizer/components/index.ts +5 -0
  339. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +127 -0
  340. package/frontend/src/index.css +248 -0
  341. package/frontend/src/lib/api/client.ts +163 -0
  342. package/frontend/src/lib/contexts/AuthContext.tsx +157 -0
  343. package/frontend/src/lib/contexts/OnboardStepContext.tsx +68 -0
  344. package/frontend/src/lib/contexts/SocketContext.tsx +303 -0
  345. package/frontend/src/lib/contexts/ThemeContext.tsx +125 -0
  346. package/frontend/src/lib/hooks/useAuth.ts +4 -0
  347. package/frontend/src/lib/hooks/useConfirm.ts +55 -0
  348. package/frontend/src/lib/hooks/useInterval.ts +27 -0
  349. package/frontend/src/lib/hooks/useMediaQuery.ts +59 -0
  350. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +29 -0
  351. package/frontend/src/lib/hooks/usePagination.ts +27 -0
  352. package/frontend/src/lib/hooks/useTimeout.ts +27 -0
  353. package/frontend/src/lib/hooks/useToast.tsx +229 -0
  354. package/frontend/src/lib/utils/constants.ts +38 -0
  355. package/frontend/src/lib/utils/utils.ts +165 -0
  356. package/frontend/src/lib/utils/validation-schemas.ts +126 -0
  357. package/frontend/src/main.tsx +16 -0
  358. package/frontend/src/rdg.css +194 -0
  359. package/frontend/src/vite-env.d.ts +12 -0
  360. package/frontend/tailwind.config.js +97 -0
  361. package/frontend/tsconfig.json +26 -0
  362. package/frontend/tsconfig.node.json +10 -0
  363. package/frontend/vite.config.ts +37 -0
  364. package/frontend/vitest.config.ts +36 -0
  365. package/functions/deno.json +25 -0
  366. package/functions/server.ts +290 -0
  367. package/functions/worker-template.js +126 -0
  368. package/openapi/ai.yaml +689 -0
  369. package/openapi/auth.yaml +563 -0
  370. package/openapi/functions.yaml +476 -0
  371. package/openapi/health.yaml +30 -0
  372. package/openapi/logs.yaml +224 -0
  373. package/openapi/metadata.yaml +178 -0
  374. package/openapi/records.yaml +382 -0
  375. package/openapi/secrets.yaml +371 -0
  376. package/openapi/storage.yaml +876 -0
  377. package/openapi/tables.yaml +464 -0
  378. package/package.json +88 -0
  379. package/shared-schemas/package.json +31 -0
  380. package/shared-schemas/src/ai-api.schema.ts +167 -0
  381. package/shared-schemas/src/ai.schema.ts +54 -0
  382. package/shared-schemas/src/auth-api.schema.ts +193 -0
  383. package/shared-schemas/src/auth.schema.ts +94 -0
  384. package/shared-schemas/src/database-api.schema.ts +259 -0
  385. package/shared-schemas/src/database.schema.ts +69 -0
  386. package/shared-schemas/src/functions-api.schema.ts +25 -0
  387. package/shared-schemas/src/functions.schema.ts +16 -0
  388. package/shared-schemas/src/index.ts +13 -0
  389. package/shared-schemas/src/logs-api.schema.ts +49 -0
  390. package/shared-schemas/src/logs.schema.ts +14 -0
  391. package/shared-schemas/src/metadata.schema.ts +56 -0
  392. package/shared-schemas/src/storage-api.schema.ts +65 -0
  393. package/shared-schemas/src/storage.schema.ts +19 -0
  394. package/shared-schemas/tsconfig.json +21 -0
  395. package/tsconfig.json +8 -0
@@ -0,0 +1,146 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { LogOut, ChevronDown } from 'lucide-react';
3
+ import {
4
+ DropdownMenu,
5
+ DropdownMenuContent,
6
+ DropdownMenuItem,
7
+ DropdownMenuTrigger,
8
+ } from '@/components/radix/DropdownMenu';
9
+ import { Avatar, AvatarFallback } from '@/components/radix/Avatar';
10
+ import { Separator } from '@/components/radix/Separator';
11
+ import { cn } from '@/lib/utils/utils';
12
+ import { ThemeToggle } from '@/components/ThemeToggle';
13
+ import { useTheme } from '@/lib/contexts/ThemeContext';
14
+
15
+ // Import SVG icons
16
+ import DiscordIcon from '@/assets/logos/discord.svg?react';
17
+ import GitHubIcon from '@/assets/logos/github.svg?react';
18
+ import InsForgeLogoLight from '@/assets/logos/insforge_light.svg';
19
+ import InsForgeLogoDark from '@/assets/logos/insforge_dark.svg';
20
+ import { User } from '@/lib/contexts/AuthContext';
21
+
22
+ interface AppHeaderProps {
23
+ currentUser: User | null;
24
+ onLogout: () => void;
25
+ }
26
+
27
+ export default function AppHeader({ currentUser, onLogout }: AppHeaderProps) {
28
+ const { resolvedTheme } = useTheme();
29
+ const [currentEmojiIndex, setCurrentEmojiIndex] = useState(0);
30
+ const emojis = ['🙏', '🥺', '🫵'];
31
+
32
+ useEffect(() => {
33
+ const interval = setInterval(() => {
34
+ setCurrentEmojiIndex((prevIndex) => (prevIndex + 1) % emojis.length);
35
+ }, 2000);
36
+
37
+ return () => clearInterval(interval);
38
+ }, [emojis.length]);
39
+
40
+ const getUserInitials = (email: string) => {
41
+ if (!email) {
42
+ return 'U';
43
+ }
44
+ const parts = email.split('@')[0].split('.');
45
+ if (parts.length > 1) {
46
+ return (parts[0].charAt(0) + parts[1].charAt(0)).toUpperCase();
47
+ }
48
+ return email.substring(0, 2).toUpperCase();
49
+ };
50
+
51
+ const getAvatarColor = (email: string) => {
52
+ if (!email) {
53
+ return 'bg-gray-500';
54
+ }
55
+ const hash = email.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
56
+ const colors = [
57
+ 'bg-blue-500',
58
+ 'bg-green-500',
59
+ 'bg-yellow-500',
60
+ 'bg-purple-500',
61
+ 'bg-pink-500',
62
+ 'bg-indigo-500',
63
+ ];
64
+ return colors[hash % colors.length];
65
+ };
66
+
67
+ return (
68
+ <div className="h-16 w-full bg-white dark:bg-neutral-800 border-b border-border-gray dark:border-neutral-700 z-50 flex items-center justify-between px-6">
69
+ {/* Logo */}
70
+ <div className="px-2 py-3">
71
+ <img
72
+ src={resolvedTheme === 'light' ? InsForgeLogoLight : InsForgeLogoDark}
73
+ alt="Insforge Logo"
74
+ className="h-8 w-auto"
75
+ />
76
+ </div>
77
+
78
+ {/* Social Links */}
79
+ <div className="flex items-center gap-3">
80
+ {/* GitHub Badge */}
81
+ <a
82
+ href="https://github.com/InsForge/InsForge"
83
+ target="_blank"
84
+ rel="noopener noreferrer"
85
+ className="inline-flex items-center gap-3 h-10 px-4 text-zinc-50 text-sm font-medium bg-black hover:bg-[#28282F] rounded-full transition-all duration-200"
86
+ >
87
+ <GitHubIcon className="h-5 w-5 dark:text-white" />
88
+ <p className="text-sm text-white">
89
+ We need you
90
+ <span className="text-md ml-1">{emojis[currentEmojiIndex]}</span>
91
+ </p>
92
+ </a>
93
+
94
+ {/* Discord Badge */}
95
+ <a
96
+ href="https://discord.gg/mqPxArVZ26"
97
+ target="_blank"
98
+ rel="noopener noreferrer"
99
+ className="inline-flex items-center gap-3 h-10 px-4 text-zinc-50 text-sm font-medium bg-[#5765F2] hover:bg-[#3E4CD7] rounded-full transition-all duration-200"
100
+ >
101
+ <DiscordIcon className="h-5 w-5" />
102
+ <p className="text-sm text-white mr-1.5">Ask us anything</p>
103
+ </a>
104
+ <Separator className="h-6 mx-1" orientation="vertical" />
105
+ {/* Theme Toggle */}
106
+ <ThemeToggle />
107
+ <Separator className="h-6 mx-1" orientation="vertical" />
108
+ {/* User Profile */}
109
+ <DropdownMenu modal={false}>
110
+ <DropdownMenuTrigger asChild>
111
+ <button className="w-50 flex items-center gap-3 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-[8px] pr-3 transition-all duration-200 group">
112
+ <Avatar className="h-10 w-10 ring-2 ring-white dark:ring-gray-700 shadow-sm">
113
+ <AvatarFallback
114
+ className={cn(
115
+ 'text-white font-medium text-sm',
116
+ getAvatarColor(currentUser?.email ?? '')
117
+ )}
118
+ >
119
+ {getUserInitials(currentUser?.email ?? '')}
120
+ </AvatarFallback>
121
+ </Avatar>
122
+ <div className="text-left hidden md:block">
123
+ <p className="text-sm font-medium text-zinc-950 dark:text-zinc-100 leading-tight">
124
+ Admin
125
+ </p>
126
+ <p className="text-xs text-zinc-500 dark:text-zinc-400">
127
+ {currentUser?.email || 'Administrator'}
128
+ </p>
129
+ </div>
130
+ <ChevronDown className="h-5 w-5 text-black dark:text-white hidden md:block ml-auto" />
131
+ </button>
132
+ </DropdownMenuTrigger>
133
+ <DropdownMenuContent align="end" className="w-48" sideOffset={8} collisionPadding={16}>
134
+ <DropdownMenuItem
135
+ onClick={onLogout}
136
+ className="cursor-pointer text-red-600 dark:text-red-400"
137
+ >
138
+ <LogOut className="mr-2 h-4 w-4" />
139
+ <span>Sign Out</span>
140
+ </DropdownMenuItem>
141
+ </DropdownMenuContent>
142
+ </DropdownMenu>
143
+ </div>
144
+ </div>
145
+ );
146
+ }
@@ -0,0 +1,190 @@
1
+ import { Link, useLocation } from 'react-router-dom';
2
+ import {
3
+ Home,
4
+ Database,
5
+ UserRoundCog,
6
+ HardDrive,
7
+ PanelLeftOpen,
8
+ PanelRightOpen,
9
+ BookOpen,
10
+ ExternalLink,
11
+ RotateCw,
12
+ Sparkles,
13
+ Code2,
14
+ } from 'lucide-react';
15
+ import { cn } from '@/lib/utils/utils';
16
+ import { Button } from '@/components/radix/Button';
17
+ import { ScrollArea } from '@/components/radix/ScrollArea';
18
+ import {
19
+ Tooltip,
20
+ TooltipContent,
21
+ TooltipProvider,
22
+ TooltipTrigger,
23
+ } from '@/components/radix/Tooltip';
24
+ import { OnboardButton } from '@/features/onboard/components/OnboardButton';
25
+ import { useOnboardingCompletion } from '@/lib/hooks/useOnboardingCompletion';
26
+
27
+ interface AppSidebarProps extends React.HTMLAttributes<HTMLElement> {
28
+ onLogout: () => void;
29
+ isCollapsed: boolean;
30
+ onToggleCollapse: () => void;
31
+ }
32
+
33
+ interface NavigationProps {
34
+ name: string;
35
+ href: string;
36
+ icon: React.ComponentType<{ className?: string }>;
37
+ }
38
+
39
+ const navigation: NavigationProps[] = [
40
+ { name: 'Dashboard', href: '/dashboard', icon: Home },
41
+ { name: 'Authentications', href: '/dashboard/authentication', icon: UserRoundCog },
42
+ { name: 'Database', href: '/dashboard/database', icon: Database },
43
+ { name: 'Storage', href: '/dashboard/storage', icon: HardDrive },
44
+ { name: 'Functions', href: '/dashboard/functions', icon: Code2 },
45
+ //{ name: 'Audit', href: '/dashboard/logs', icon: Logs },
46
+ // { name: 'Analytics', href: '/dashboard/analytics', icon: Activity },
47
+ { name: 'AI', href: '/dashboard/ai', icon: Sparkles },
48
+ ];
49
+
50
+ const bottomNavigation = [
51
+ {
52
+ name: 'Documentation',
53
+ href: 'https://docs.insforge.dev',
54
+ icon: BookOpen,
55
+ external: true,
56
+ },
57
+ ];
58
+
59
+ export default function AppSidebar({
60
+ onLogout: _onLogout,
61
+ isCollapsed,
62
+ onToggleCollapse,
63
+ ...props
64
+ }: AppSidebarProps) {
65
+ const location = useLocation();
66
+ const { isCompleted } = useOnboardingCompletion();
67
+
68
+ // Add reinstall navigation item when onboarding is completed
69
+ const dynamicNavigation = isCompleted
70
+ ? [
71
+ ...navigation,
72
+ {
73
+ name: 'Reinstall',
74
+ href: '/dashboard/onboard?step=1',
75
+ icon: RotateCw,
76
+ },
77
+ ]
78
+ : navigation;
79
+
80
+ const NavItem = ({ item, onClick }: { item: NavigationProps; onClick?: () => void }) => {
81
+ const isActive = location.pathname === item.href.split('?')[0];
82
+
83
+ const buttonContent = (
84
+ <Button
85
+ variant={isActive ? 'default' : 'ghost'}
86
+ className={cn(
87
+ 'w-full h-12 relative transition-all duration-200 ease-in-out',
88
+ isActive
89
+ ? 'bg-zinc-950 dark:bg-emerald-300 text-white dark:text-black'
90
+ : 'hover:bg-zinc-100 dark:hover:bg-neutral-600 text-black dark:text-white'
91
+ )}
92
+ onClick={onClick}
93
+ >
94
+ <div className="absolute left-3.5 h-5 w-5">
95
+ <item.icon className="h-5 w-5" />
96
+ </div>
97
+ {!isCollapsed && (
98
+ <span className="absolute left-11.5 font-medium truncate">{item.name}</span>
99
+ )}
100
+ </Button>
101
+ );
102
+
103
+ return (
104
+ <TooltipProvider delayDuration={300}>
105
+ <Tooltip>
106
+ <TooltipTrigger asChild>
107
+ <Link to={item.href} className="block">
108
+ {buttonContent}
109
+ </Link>
110
+ </TooltipTrigger>
111
+ {isCollapsed && (
112
+ <TooltipContent side="right">
113
+ <p>{item.name}</p>
114
+ </TooltipContent>
115
+ )}
116
+ </Tooltip>
117
+ </TooltipProvider>
118
+ );
119
+ };
120
+
121
+ return (
122
+ <aside
123
+ {...props}
124
+ className={cn(
125
+ 'fixed left-0 z-40 bg-white dark:bg-neutral-800 border-r border-gray-200 dark:border-neutral-700 flex flex-col transition-all duration-300 ease-in-out',
126
+ 'top-16 bottom-0',
127
+ isCollapsed ? 'w-18' : 'w-60',
128
+ props.className
129
+ )}
130
+ >
131
+ {!isCompleted && (
132
+ <div className={`py-3 ${isCollapsed ? 'pl-1 pr-[3px]' : 'pl-3 pr-[11px]'} overflow-hidden`}>
133
+ <OnboardButton isCollapsed={isCollapsed} />
134
+ </div>
135
+ )}
136
+ {/* Navigation */}
137
+ <ScrollArea className="flex-1 pl-3 pr-[11px] py-4">
138
+ <nav className="space-y-2">
139
+ {dynamicNavigation.map((item) => (
140
+ <NavItem key={item.name} item={item} />
141
+ ))}
142
+ </nav>
143
+ </ScrollArea>
144
+
145
+ {/* Bottom section */}
146
+ <div className="p-3 pr-[11px] space-y-6 overflow-hidden">
147
+ {/* Bottom navigation items */}
148
+ {bottomNavigation.map((item) => (
149
+ <div key={item.name}>
150
+ <Button
151
+ variant="ghost"
152
+ className="w-full h-12 relative transition-all duration-200 ease-in-out border border-gray-200 dark:border-neutral-700 rounded-md hover:bg-zinc-100 dark:hover:bg-neutral-600 text-black dark:text-white"
153
+ onClick={() => window.open(item.href, '_blank')}
154
+ >
155
+ <div className="absolute left-3.5 h-5 w-5">
156
+ <item.icon className="h-5 w-5" />
157
+ </div>
158
+ {!isCollapsed && (
159
+ <>
160
+ <span className="absolute left-11.5 font-medium truncate">{item.name}</span>
161
+ {item.external && (
162
+ <ExternalLink className="absolute left-46.5 h-4 w-4 text-zinc-400" />
163
+ )}
164
+ </>
165
+ )}
166
+ </Button>
167
+ </div>
168
+ ))}
169
+
170
+ {/* Collapse button - only visible on 2xl screens */}
171
+ <div className="hidden 2xl:block">
172
+ <Button
173
+ variant="ghost"
174
+ className="w-full h-12 relative transition-all duration-200 ease-in-out hover:bg-zinc-100 dark:hover:bg-neutral-600 text-black dark:text-white"
175
+ onClick={onToggleCollapse}
176
+ >
177
+ <div className="absolute left-3.5 h-5 w-5">
178
+ {isCollapsed ? (
179
+ <PanelLeftOpen className="h-5 w-5" />
180
+ ) : (
181
+ <PanelRightOpen className="h-5 w-5" />
182
+ )}
183
+ </div>
184
+ {!isCollapsed && <span className="absolute left-11.5 font-medium">Collapse</span>}
185
+ </Button>
186
+ </div>
187
+ </div>
188
+ </aside>
189
+ );
190
+ }
@@ -0,0 +1,95 @@
1
+ import { useEffect } from 'react';
2
+ import { useNavigate, useLocation } from 'react-router-dom';
3
+ import { ThemeProvider } from '@/lib/contexts/ThemeContext';
4
+ import { cn } from '@/lib/utils/utils';
5
+ import { ServerEvents, useSocket } from '@/lib/contexts/SocketContext';
6
+
7
+ interface CloudLayoutProps {
8
+ children: React.ReactNode;
9
+ }
10
+
11
+ interface RouterMessage {
12
+ type: 'ROUTE_CHANGE' | 'REFRESH';
13
+ path: string;
14
+ }
15
+
16
+ export default function CloudLayout({ children }: CloudLayoutProps) {
17
+ const navigate = useNavigate();
18
+ const location = useLocation();
19
+ const { socket } = useSocket();
20
+
21
+ useEffect(() => {
22
+ const handleCloudMessage = (event: MessageEvent) => {
23
+ try {
24
+ const message = event.data as RouterMessage;
25
+
26
+ if (message.type === 'ROUTE_CHANGE' && message.path) {
27
+ // Navigate to the corresponding cloud route
28
+ void navigate(message.path);
29
+ } else if (message.type === 'REFRESH') {
30
+ window.location.reload();
31
+ }
32
+ } catch (error) {
33
+ console.error('Error handling router message:', error);
34
+ }
35
+ };
36
+
37
+ // Add event listener for messages from parent window
38
+ window.addEventListener('message', handleCloudMessage);
39
+
40
+ // Cleanup listener on unmount
41
+ return () => {
42
+ window.removeEventListener('message', handleCloudMessage);
43
+ };
44
+ }, [navigate]);
45
+
46
+ useEffect(() => {
47
+ // Only send messages if we're in an iframe (not the main window)
48
+ if (window.parent !== window) {
49
+ // Send the current route to the parent cloud application
50
+ window.parent.postMessage(
51
+ {
52
+ type: 'APP_ROUTE_CHANGE',
53
+ path: location.pathname,
54
+ },
55
+ '*'
56
+ );
57
+ }
58
+ }, [location.pathname]);
59
+
60
+ // Listen for MCP connection events and forward to parent
61
+ useEffect(() => {
62
+ if (!socket || window.parent === window) {
63
+ return;
64
+ }
65
+
66
+ const handleMcpConnected = () => {
67
+ window.parent.postMessage(
68
+ {
69
+ type: 'MCP_CONNECTION_STATUS',
70
+ connected: true,
71
+ },
72
+ '*'
73
+ );
74
+ };
75
+
76
+ socket.on(ServerEvents.MCP_CONNECTED, handleMcpConnected);
77
+
78
+ return () => {
79
+ socket.off(ServerEvents.MCP_CONNECTED, handleMcpConnected);
80
+ };
81
+ }, [socket]);
82
+
83
+ return (
84
+ <ThemeProvider forcedTheme="dark">
85
+ <div
86
+ className={cn(
87
+ 'h-screen bg-neutral-800',
88
+ location.pathname !== '/cloud/visualizer' && 'pt-13 pl-13'
89
+ )}
90
+ >
91
+ {children}
92
+ </div>
93
+ </ThemeProvider>
94
+ );
95
+ }
@@ -0,0 +1,43 @@
1
+ import React, { useState } from 'react';
2
+ import AppSidebar from './AppSidebar';
3
+ import AppHeader from './AppHeader';
4
+ import { cn } from '@/lib/utils/utils';
5
+ import { useAuth } from '@/lib/contexts/AuthContext';
6
+ import { useMediaQuery } from '@/lib/hooks/useMediaQuery';
7
+ import { ThemeProvider } from '@/lib/contexts/ThemeContext';
8
+
9
+ interface LayoutProps {
10
+ children: React.ReactNode;
11
+ }
12
+
13
+ export default function Layout({ children }: LayoutProps) {
14
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
15
+ const [isHovering, setIsHovering] = useState(false);
16
+ const { user, logout } = useAuth();
17
+ const is2xl = useMediaQuery('(min-width: 1536px)');
18
+
19
+ return (
20
+ <ThemeProvider>
21
+ <div className="h-screen bg-gray-50 dark:bg-neutral-800 flex flex-col">
22
+ <AppHeader currentUser={user} onLogout={logout} />
23
+
24
+ {/* Main content */}
25
+ <div
26
+ className={cn(
27
+ 'flex-1 transition-all duration-300 ease-in-out overflow-y-auto ml-18',
28
+ !sidebarCollapsed && '2xl:ml-60'
29
+ )}
30
+ >
31
+ <AppSidebar
32
+ onLogout={logout}
33
+ isCollapsed={is2xl ? sidebarCollapsed : !isHovering}
34
+ onToggleCollapse={() => setSidebarCollapsed(!sidebarCollapsed)}
35
+ onMouseEnter={() => setIsHovering(true)}
36
+ onMouseLeave={() => setIsHovering(false)}
37
+ />
38
+ {children}
39
+ </div>
40
+ </div>
41
+ </ThemeProvider>
42
+ );
43
+ }
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+
4
+ import { cn } from '@/lib/utils/utils';
5
+
6
+ const alertVariants = cva(
7
+ 'relative w-full rounded-lg border px-4 py-4 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: 'bg-background text-foreground',
12
+ destructive:
13
+ 'border-destructive/50 text-destructive dark:bg-red-200 dark:border-destructive [&>svg]:text-destructive',
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: 'default',
18
+ },
19
+ }
20
+ );
21
+
22
+ const Alert = React.forwardRef<
23
+ HTMLDivElement,
24
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
25
+ >(({ className, variant, ...props }, ref) => (
26
+ <div ref={ref} role="alert" className={cn(alertVariants({ variant }), className)} {...props} />
27
+ ));
28
+ Alert.displayName = 'Alert';
29
+
30
+ const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
31
+ ({ className, ...props }, ref) => (
32
+ <h5 ref={ref} className={cn('font-medium leading-none tracking-tight', className)} {...props} />
33
+ )
34
+ );
35
+ AlertTitle.displayName = 'AlertTitle';
36
+
37
+ const AlertDescription = React.forwardRef<
38
+ HTMLParagraphElement,
39
+ React.HTMLAttributes<HTMLParagraphElement>
40
+ >(({ className, ...props }, ref) => (
41
+ <div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />
42
+ ));
43
+ AlertDescription.displayName = 'AlertDescription';
44
+
45
+ export { Alert, AlertTitle, AlertDescription };
@@ -0,0 +1,115 @@
1
+ import * as React from 'react';
2
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
3
+
4
+ import { cn } from '@/lib/utils/utils';
5
+ import { buttonVariants } from '@/components/radix/Button';
6
+
7
+ const AlertDialog = AlertDialogPrimitive.Root;
8
+
9
+ const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
10
+
11
+ const AlertDialogPortal = AlertDialogPrimitive.Portal;
12
+
13
+ const AlertDialogOverlay = React.forwardRef<
14
+ React.ComponentRef<typeof AlertDialogPrimitive.Overlay>,
15
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
16
+ >(({ className, ...props }, ref) => (
17
+ <AlertDialogPrimitive.Overlay
18
+ className={cn(
19
+ 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
20
+ className
21
+ )}
22
+ {...props}
23
+ ref={ref}
24
+ />
25
+ ));
26
+ AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
27
+
28
+ const AlertDialogContent = React.forwardRef<
29
+ React.ComponentRef<typeof AlertDialogPrimitive.Content>,
30
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
31
+ >(({ className, ...props }, ref) => (
32
+ <AlertDialogPortal>
33
+ <AlertDialogOverlay />
34
+ <AlertDialogPrimitive.Content
35
+ ref={ref}
36
+ className={cn(
37
+ 'rounded-lg fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
38
+ className
39
+ )}
40
+ {...props}
41
+ />
42
+ </AlertDialogPortal>
43
+ ));
44
+ AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
45
+
46
+ const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
47
+ <div className={cn('flex flex-col space-y-2 text-center sm:text-left', className)} {...props} />
48
+ );
49
+ AlertDialogHeader.displayName = 'AlertDialogHeader';
50
+
51
+ const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
52
+ <div
53
+ className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
54
+ {...props}
55
+ />
56
+ );
57
+ AlertDialogFooter.displayName = 'AlertDialogFooter';
58
+
59
+ const AlertDialogTitle = React.forwardRef<
60
+ React.ComponentRef<typeof AlertDialogPrimitive.Title>,
61
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
62
+ >(({ className, ...props }, ref) => (
63
+ <AlertDialogPrimitive.Title
64
+ ref={ref}
65
+ className={cn('text-lg font-semibold', className)}
66
+ {...props}
67
+ />
68
+ ));
69
+ AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
70
+
71
+ const AlertDialogDescription = React.forwardRef<
72
+ React.ComponentRef<typeof AlertDialogPrimitive.Description>,
73
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
74
+ >(({ className, ...props }, ref) => (
75
+ <AlertDialogPrimitive.Description
76
+ ref={ref}
77
+ className={cn('text-sm text-gray-500', className)}
78
+ {...props}
79
+ />
80
+ ));
81
+ AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
82
+
83
+ const AlertDialogAction = React.forwardRef<
84
+ React.ComponentRef<typeof AlertDialogPrimitive.Action>,
85
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
86
+ >(({ className, ...props }, ref) => (
87
+ <AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />
88
+ ));
89
+ AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
90
+
91
+ const AlertDialogCancel = React.forwardRef<
92
+ React.ComponentRef<typeof AlertDialogPrimitive.Cancel>,
93
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
94
+ >(({ className, ...props }, ref) => (
95
+ <AlertDialogPrimitive.Cancel
96
+ ref={ref}
97
+ className={cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className)}
98
+ {...props}
99
+ />
100
+ ));
101
+ AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
102
+
103
+ export {
104
+ AlertDialog,
105
+ AlertDialogPortal,
106
+ AlertDialogOverlay,
107
+ AlertDialogTrigger,
108
+ AlertDialogContent,
109
+ AlertDialogHeader,
110
+ AlertDialogFooter,
111
+ AlertDialogTitle,
112
+ AlertDialogDescription,
113
+ AlertDialogAction,
114
+ AlertDialogCancel,
115
+ };
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
3
+
4
+ import { cn } from '@/lib/utils/utils';
5
+
6
+ const Avatar = React.forwardRef<
7
+ React.ComponentRef<typeof AvatarPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
9
+ >(({ className, ...props }, ref) => (
10
+ <AvatarPrimitive.Root
11
+ ref={ref}
12
+ className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-[8px]', className)}
13
+ {...props}
14
+ />
15
+ ));
16
+ Avatar.displayName = AvatarPrimitive.Root.displayName;
17
+
18
+ const AvatarImage = React.forwardRef<
19
+ React.ComponentRef<typeof AvatarPrimitive.Image>,
20
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
21
+ >(({ className, ...props }, ref) => (
22
+ <AvatarPrimitive.Image
23
+ ref={ref}
24
+ className={cn('aspect-square h-full w-full rounded-[8px]', className)}
25
+ {...props}
26
+ />
27
+ ));
28
+ AvatarImage.displayName = AvatarPrimitive.Image.displayName;
29
+
30
+ const AvatarFallback = React.forwardRef<
31
+ React.ComponentRef<typeof AvatarPrimitive.Fallback>,
32
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
33
+ >(({ className, ...props }, ref) => (
34
+ <AvatarPrimitive.Fallback
35
+ ref={ref}
36
+ className={cn(
37
+ 'flex h-full w-full items-center justify-center rounded-[8px] bg-muted',
38
+ className
39
+ )}
40
+ {...props}
41
+ />
42
+ ));
43
+ AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
44
+
45
+ export { Avatar, AvatarImage, AvatarFallback };