diff --git a/.bruno/Payment/account/create.bru b/.bruno/Payment/account/create.bru deleted file mode 100644 index 7a4bf7a..0000000 --- a/.bruno/Payment/account/create.bru +++ /dev/null @@ -1,24 +0,0 @@ -meta { - name: Create - type: http - seq: 1 -} - -post { - url: {{url}}/payment/wallets - body: json - auth: inherit -} - -body:json { - { - "ledgerId": "ee228d0d-b48c-4878-aca3-050a7434503b", - "entityId": "some-external-entity", - "label": "Securities" - } -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/account/folder.bru b/.bruno/Payment/account/folder.bru deleted file mode 100644 index 109fad9..0000000 --- a/.bruno/Payment/account/folder.bru +++ /dev/null @@ -1,4 +0,0 @@ -meta { - name: Wallet - seq: 3 -} diff --git a/.bruno/Payment/beneficiary/Ledgers.bru b/.bruno/Payment/beneficiary/Ledgers.bru deleted file mode 100644 index 3297d88..0000000 --- a/.bruno/Payment/beneficiary/Ledgers.bru +++ /dev/null @@ -1,20 +0,0 @@ -meta { - name: Ledgers - type: http - seq: 5 -} - -get { - url: {{url}}/payment/beneficiaries/:id/ledgers - body: json - auth: inherit -} - -params:path { - id: 16f41847-4bc4-4898-92d1-75fd314d15a8 -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/beneficiary/create.bru b/.bruno/Payment/beneficiary/create.bru deleted file mode 100644 index fe7b85d..0000000 --- a/.bruno/Payment/beneficiary/create.bru +++ /dev/null @@ -1,23 +0,0 @@ -meta { - name: Create - type: http - seq: 1 -} - -post { - url: {{url}}/payment/beneficiaries - body: json - auth: inherit -} - -body:json { - { - "tenantId": "valkyr-inc", - "label": "Valkyr Inc." - } -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/beneficiary/dashboard.bru b/.bruno/Payment/beneficiary/dashboard.bru deleted file mode 100644 index 84ff776..0000000 --- a/.bruno/Payment/beneficiary/dashboard.bru +++ /dev/null @@ -1,20 +0,0 @@ -meta { - name: Dashboard - type: http - seq: 2 -} - -get { - url: {{url}}/payment/dashboard/:id - body: json - auth: inherit -} - -params:path { - id: 16f41847-4bc4-4898-92d1-75fd314d15a8 -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/beneficiary/folder.bru b/.bruno/Payment/beneficiary/folder.bru deleted file mode 100644 index 31faaa3..0000000 --- a/.bruno/Payment/beneficiary/folder.bru +++ /dev/null @@ -1,4 +0,0 @@ -meta { - name: Beneficiary - seq: 1 -} diff --git a/.bruno/Payment/beneficiary/id.bru b/.bruno/Payment/beneficiary/id.bru deleted file mode 100644 index 9026f9b..0000000 --- a/.bruno/Payment/beneficiary/id.bru +++ /dev/null @@ -1,20 +0,0 @@ -meta { - name: :id - type: http - seq: 4 -} - -get { - url: {{url}}/payment/beneficiaries/:id - body: json - auth: inherit -} - -params:path { - id: a0a6aa39-5d13-4717-9554-a878d7f30ea7 -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/beneficiary/list.bru b/.bruno/Payment/beneficiary/list.bru deleted file mode 100644 index 3eac0d2..0000000 --- a/.bruno/Payment/beneficiary/list.bru +++ /dev/null @@ -1,16 +0,0 @@ -meta { - name: List - type: http - seq: 3 -} - -get { - url: {{url}}/payment/beneficiaries - body: json - auth: inherit -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/folder.bru b/.bruno/Payment/folder.bru deleted file mode 100644 index 366e4fe..0000000 --- a/.bruno/Payment/folder.bru +++ /dev/null @@ -1,4 +0,0 @@ -meta { - name: Payment - seq: 2 -} diff --git a/.bruno/Payment/ledger/create.bru b/.bruno/Payment/ledger/create.bru deleted file mode 100644 index 27bd308..0000000 --- a/.bruno/Payment/ledger/create.bru +++ /dev/null @@ -1,27 +0,0 @@ -meta { - name: Create - type: http - seq: 1 -} - -post { - url: {{url}}/payment/ledgers - body: json - auth: inherit -} - -body:json { - { - "beneficiaryId": "16f41847-4bc4-4898-92d1-75fd314d15a8", - "label": "Sample Ledger #1", - "currencies": [ - "NOK", - "SEK" - ] - } -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/ledger/folder.bru b/.bruno/Payment/ledger/folder.bru deleted file mode 100644 index 0e9edbe..0000000 --- a/.bruno/Payment/ledger/folder.bru +++ /dev/null @@ -1,4 +0,0 @@ -meta { - name: Ledger - seq: 2 -} diff --git a/.bruno/Payment/ledger/wallets.bru b/.bruno/Payment/ledger/wallets.bru deleted file mode 100644 index 0696533..0000000 --- a/.bruno/Payment/ledger/wallets.bru +++ /dev/null @@ -1,20 +0,0 @@ -meta { - name: Wallets - type: http - seq: 3 -} - -get { - url: {{url}}/payment/ledgers/:id/wallets - body: json - auth: inherit -} - -params:path { - id: 3c71d240-a375-42e1-9a78-0575bf33fabb -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/wallet/create.bru b/.bruno/Payment/wallet/create.bru deleted file mode 100644 index 5d5e834..0000000 --- a/.bruno/Payment/wallet/create.bru +++ /dev/null @@ -1,24 +0,0 @@ -meta { - name: Create - type: http - seq: 1 -} - -post { - url: {{url}}/payment/accounts - body: json - auth: inherit -} - -body:json { - { - "walletId": "c13bd907-d760-4628-95e8-a723a54dff83", - "currency": "NOK", - "label": "Sample Funds" - } -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/.bruno/Payment/wallet/folder.bru b/.bruno/Payment/wallet/folder.bru deleted file mode 100644 index 7bcba0a..0000000 --- a/.bruno/Payment/wallet/folder.bru +++ /dev/null @@ -1,4 +0,0 @@ -meta { - name: Account - seq: 4 -} diff --git a/.bruno/bruno.json b/.bruno/bruno.json deleted file mode 100644 index b2c9a3a..0000000 --- a/.bruno/bruno.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": "1", - "name": "Valkyr", - "type": "collection", - "ignore": [ - "node_modules", - ".git" - ] -} \ No newline at end of file diff --git a/.bruno/environments/localhost.bru b/.bruno/environments/localhost.bru deleted file mode 100644 index 1f2c42d..0000000 --- a/.bruno/environments/localhost.bru +++ /dev/null @@ -1,3 +0,0 @@ -vars { - url: http://localhost:8370/api/v1 -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 0425ac9..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "biome.enabled": true, - "deno.enable": true, - "deno.lint": false, - "editor.defaultFormatter": "biomejs.biome", - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.organizeImports.biome": "explicit", - "source.fixAll.biome": "explicit" - }, - "files.readonlyInclude": { - "**/routeTree.gen.ts": true - }, - "files.watcherExclude": { - "**/routeTree.gen.ts": true - }, - "search.exclude": { - "**/routeTree.gen.ts": true - }, - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/CVS": true, - "**/.DS_Store": true, - "**/Thumbs.db": true - } -} diff --git a/Dockerfile b/Dockerfile index 398d47c..c3e002b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM denoland/deno:2.5.1 +FROM denoland/deno:2.6.4 ENV TZ=UTC ENV PORT=8370 @@ -8,10 +8,11 @@ EXPOSE 8370 WORKDIR /app COPY api/ ./api/ -COPY relay/ ./relay/ +COPY modules/ ./modules/ +COPY platform/ ./platform/ COPY .npmrc . -COPY deno-docker.json ./deno.json +COPY deno.json ./deno.json RUN deno install --allow-scripts -CMD ["sh", "-c", "deno run --allow-all ./api/.tasks/migrate.ts && deno run --allow-all ./api/server.ts"] \ No newline at end of file +CMD ["sh", "-c", "deno run --allow-all ./api/.tasks/migrate.ts && deno run --allow-all ./api/server.ts"] diff --git a/apps/README.md b/apps/README.md deleted file mode 100644 index c7782ba..0000000 --- a/apps/README.md +++ /dev/null @@ -1 +0,0 @@ -# Apps \ No newline at end of file diff --git a/apps/react/.gitignore b/apps/react/.gitignore deleted file mode 100644 index a547bf3..0000000 --- a/apps/react/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/apps/react/.npmrc b/apps/react/.npmrc deleted file mode 100644 index 41583e3..0000000 --- a/apps/react/.npmrc +++ /dev/null @@ -1 +0,0 @@ -@jsr:registry=https://npm.jsr.io diff --git a/apps/react/README.md b/apps/react/README.md deleted file mode 100644 index 7959ce4..0000000 --- a/apps/react/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: - -```js -export default tseslint.config([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - - // Remove tseslint.configs.recommended and replace with this - ...tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - ...tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - ...tseslint.configs.stylisticTypeChecked, - - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) -``` - -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' - -export default tseslint.config([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) -``` diff --git a/apps/react/components.json b/apps/react/components.json deleted file mode 100644 index c3a0a52..0000000 --- a/apps/react/components.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "tailwind.config.js", - "css": "src/index.css", - "baseColor": "neutral", - "cssVariables": true, - "prefix": "" - }, - "iconLibrary": "lucide", - "aliases": { - "components": "@/components", - "utils": "@/libraries/utils", - "ui": "@/components/ui", - "lib": "@/libraries", - "hooks": "@/hooks" - }, - "registries": {} -} diff --git a/apps/react/index.html b/apps/react/index.html deleted file mode 100644 index acd2f9c..0000000 --- a/apps/react/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - Vite + React + TS - - -
- - - diff --git a/apps/react/package.json b/apps/react/package.json deleted file mode 100644 index c9904fb..0000000 --- a/apps/react/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "react", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "eslint .", - "preview": "vite preview" - }, - "dependencies": { - "@module/account": "workspace:*", - "@platform/relay": "workspace:*", - "@platform/spec": "workspace:*", - "@radix-ui/react-avatar": "^1.1.11", - "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-label": "^2.1.8", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-separator": "^1.1.8", - "@radix-ui/react-slot": "^1.2.4", - "@radix-ui/react-tooltip": "^1.2.8", - "@tabler/icons-react": "3.35.0", - "@tanstack/react-query": "5.89.0", - "@tanstack/react-router": "1.131.47", - "@valkyr/db": "npm:@jsr/valkyr__db@2.0.0", - "@valkyr/event-emitter": "npm:@jsr/valkyr__event-emitter@1.0.1", - "@zitadel/react": "1.1.0", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "fast-equals": "5.2.2", - "lucide-react": "^0.554.0", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "tailwind-merge": "^3.4.0", - "tailwindcss": "4.1.13", - "tailwindcss-animate": "^1.0.7", - "tw-animate-css": "1.4.0", - "zod": "4.3.5" - }, - "devDependencies": { - "@eslint/js": "9.35.0", - "@tailwindcss/vite": "4.1.13", - "@tanstack/react-router-devtools": "1.131.47", - "@types/react": "^19.2.7", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "4.7.0", - "eslint": "9.35.0", - "eslint-plugin-react-hooks": "5.2.0", - "eslint-plugin-react-refresh": "0.4.20", - "globals": "16.4.0", - "typescript": "5.9.2", - "typescript-eslint": "8.44.0", - "vite": "7.1.6" - } -} diff --git a/apps/react/public/vite.svg b/apps/react/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/apps/react/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/react/src/adapters/http.ts b/apps/react/src/adapters/http.ts deleted file mode 100644 index 33fa288..0000000 --- a/apps/react/src/adapters/http.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { - assertServerErrorResponse, - type RelayAdapter, - type RelayInput, - type RelayResponse, - ServerError, - type ServerErrorResponse, - type ServerErrorType, -} from "@platform/relay"; - -/** - * HttpAdapter provides a unified transport layer for Relay. - * - * It supports sending JSON objects, nested structures, arrays, and file uploads - * via FormData. The adapter automatically detects the payload type and formats - * the request accordingly. Responses are normalized into `RelayResponse`. - * - * @example - * ```ts - * const adapter = new HttpAdapter({ url: "https://api.example.com" }); - * - * // Sending JSON data - * const jsonResponse = await adapter.send({ - * method: "POST", - * endpoint: "/users", - * body: { name: "Alice", age: 30 }, - * }); - * - * // Sending files and nested objects - * const formResponse = await adapter.send({ - * method: "POST", - * endpoint: "/upload", - * body: { - * user: { name: "Bob", avatar: fileInput.files[0] }, - * documents: [fileInput.files[1], fileInput.files[2]], - * }, - * }); - * ``` - */ -export class HttpAdapter implements RelayAdapter { - /** - * Instantiate a new HttpAdapter instance. - * - * @param options - Adapter options. - */ - constructor(readonly options: HttpAdapterOptions) {} - - /** - * Override the initial url value set by instantiator. - */ - set url(value: string) { - this.options.url = value; - } - - /** - * Retrieve the URL value from options object. - */ - get url() { - return this.options.url; - } - - /** - * Return the full URL from given endpoint. - * - * @param endpoint - Endpoint to get url for. - */ - getUrl(endpoint: string): string { - return `${this.url}${endpoint}`; - } - - async send({ method, endpoint, query, body, headers = new Headers() }: RelayInput): Promise { - const init: RequestInit = { method, headers }; - - // ### Before Request - // If any before request hooks has been defined, we run them here passing in the - // request headers for further modification. - - await this.#beforeRequest(headers); - - // ### Body - - if (body !== undefined) { - const type = this.#getRequestFormat(body); - if (type === "form-data") { - headers.delete("content-type"); - init.body = this.#getFormData(body); - } - if (type === "json") { - headers.set("content-type", "application/json"); - init.body = JSON.stringify(body); - } - } - - // ### Response - - return this.request(`${endpoint}${query}`, init); - } - - /** - * Send a fetch request using the given fetch options and returns - * a relay formatted response. - * - * @param endpoint - Which endpoint to submit request to. - * @param init - Request init details to submit with the request. - */ - async request(endpoint: string, init?: RequestInit): Promise { - return this.#toResponse(await fetch(this.getUrl(endpoint), init)); - } - - /** - * Run before request operations. - * - * @param headers - Headers to pass to hooks. - */ - async #beforeRequest(headers: Headers) { - if (this.options.hooks?.beforeRequest !== undefined) { - for (const hook of this.options.hooks.beforeRequest) { - await hook(headers); - } - } - } - - /** - * Determine the parser method required for the request. - * - * @param body - Request body. - */ - #getRequestFormat(body: unknown): "form-data" | "json" { - if (containsFile(body) === true) { - return "form-data"; - } - return "json"; - } - - /** - * Get FormData instance for the given body. - * - * @param body - Request body. - */ - #getFormData(data: Record, formData = new FormData(), parentKey?: string): FormData { - for (const key in data) { - const value = data[key]; - if (value === undefined || value === null) continue; - - const formKey = parentKey ? `${parentKey}[${key}]` : key; - - if (value instanceof File) { - formData.append(formKey, value, value.name); - } else if (Array.isArray(value)) { - value.forEach((item, index) => { - if (item instanceof File) { - formData.append(`${formKey}[${index}]`, item, item.name); - } else if (typeof item === "object") { - this.#getFormData(item as Record, formData, `${formKey}[${index}]`); - } else { - formData.append(`${formKey}[${index}]`, String(item)); - } - }); - } else if (typeof value === "object") { - this.#getFormData(value as Record, formData, formKey); - } else { - formData.append(formKey, String(value)); - } - } - - return formData; - } - - /** - * Convert a fetch response to a compliant relay response. - * - * @param response - Fetch response to convert. - */ - async #toResponse(response: Response): Promise { - const type = response.headers.get("content-type"); - - // ### Content Type - // Ensure that the server responds with a 'content-type' definition. We should - // always expect the server to respond with a type. - - if (type === null) { - return { - result: "error", - error: { - status: response.status, - message: "Missing 'content-type' in header returned from server.", - }, - }; - } - - // ### Empty Response - // If the response comes back with empty response status 204 we simply return a - // empty success. - - if (response.status === 204) { - return { - result: "success", - data: null, - }; - } - - // ### JSON - // If the 'content-type' contains 'json' we treat it as a 'json' compliant response - // and attempt to resolve it as such. - - if (type.includes("json") === true) { - const parsed = await response.json(); - if ("data" in parsed) { - return { - result: "success", - data: parsed.data, - }; - } - if ("error" in parsed) { - return { - result: "error", - error: this.#toError(parsed), - }; - } - return { - result: "error", - error: { - status: response.status, - message: "Unsupported 'json' body returned from server, missing 'data' or 'error' key.", - }, - }; - } - - return { - result: "error", - error: { - status: response.status, - message: "Unsupported 'content-type' in header returned from server.", - }, - }; - } - - #toError(candidate: unknown, status: number = 500): ServerErrorType | ServerErrorResponse["error"] { - if (assertServerErrorResponse(candidate)) { - return ServerError.fromJSON({ type: "relay", ...candidate.error }); - } - if (typeof candidate === "string") { - return { - status, - message: candidate, - }; - } - return { - status, - message: "Unsupported 'error' returned from server.", - }; - } -} - -function containsFile(value: unknown): boolean { - if (value instanceof File) { - return true; - } - if (Array.isArray(value)) { - return value.some(containsFile); - } - if (typeof value === "object" && value !== null) { - return Object.values(value).some(containsFile); - } - return false; -} - -export type HttpAdapterOptions = { - url: string; - hooks?: { - beforeRequest?: ((headers: Headers) => Promise)[]; - }; -}; diff --git a/apps/react/src/assets/react.svg b/apps/react/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/apps/react/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/react/src/components/app-sidebar.tsx b/apps/react/src/components/app-sidebar.tsx deleted file mode 100644 index 3952ec0..0000000 --- a/apps/react/src/components/app-sidebar.tsx +++ /dev/null @@ -1,178 +0,0 @@ -"use client"; - -import { - IconCamera, - IconChartBar, - IconDashboard, - IconDatabase, - IconFileAi, - IconFileDescription, - IconFileWord, - IconFolder, - IconHelp, - IconInnerShadowTop, - IconListDetails, - IconReport, - IconSearch, - IconSettings, - IconUsers, -} from "@tabler/icons-react"; -import type * as React from "react"; - -import { NavDocuments } from "@/components/nav-documents"; -import { NavMain } from "@/components/nav-main"; -import { NavSecondary } from "@/components/nav-secondary"; -import { NavUser } from "@/components/nav-user"; -import { - Sidebar, - SidebarContent, - SidebarFooter, - SidebarHeader, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, -} from "@/components/ui/sidebar"; - -const data = { - user: { - name: "shadcn", - email: "m@example.com", - avatar: "/avatars/shadcn.jpg", - }, - navMain: [ - { - title: "Dashboard", - url: "#", - icon: IconDashboard, - }, - { - title: "Lifecycle", - url: "#", - icon: IconListDetails, - }, - { - title: "Analytics", - url: "#", - icon: IconChartBar, - }, - { - title: "Projects", - url: "#", - icon: IconFolder, - }, - { - title: "Team", - url: "#", - icon: IconUsers, - }, - ], - navClouds: [ - { - title: "Capture", - icon: IconCamera, - isActive: true, - url: "#", - items: [ - { - title: "Active Proposals", - url: "#", - }, - { - title: "Archived", - url: "#", - }, - ], - }, - { - title: "Proposal", - icon: IconFileDescription, - url: "#", - items: [ - { - title: "Active Proposals", - url: "#", - }, - { - title: "Archived", - url: "#", - }, - ], - }, - { - title: "Prompts", - icon: IconFileAi, - url: "#", - items: [ - { - title: "Active Proposals", - url: "#", - }, - { - title: "Archived", - url: "#", - }, - ], - }, - ], - navSecondary: [ - { - title: "Settings", - url: "#", - icon: IconSettings, - }, - { - title: "Get Help", - url: "#", - icon: IconHelp, - }, - { - title: "Search", - url: "#", - icon: IconSearch, - }, - ], - documents: [ - { - name: "Data Library", - url: "#", - icon: IconDatabase, - }, - { - name: "Reports", - url: "#", - icon: IconReport, - }, - { - name: "Word Assistant", - url: "#", - icon: IconFileWord, - }, - ], -}; - -export function AppSidebar({ ...props }: React.ComponentProps) { - return ( - - - - - - - - Acme Inc. - - - - - - - - - - - - - - - ); -} diff --git a/apps/react/src/components/nav-documents.tsx b/apps/react/src/components/nav-documents.tsx deleted file mode 100644 index 972a543..0000000 --- a/apps/react/src/components/nav-documents.tsx +++ /dev/null @@ -1,83 +0,0 @@ -"use client"; - -import { type Icon, IconDots, IconFolder, IconShare3, IconTrash } from "@tabler/icons-react"; - -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { - SidebarGroup, - SidebarGroupLabel, - SidebarMenu, - SidebarMenuAction, - SidebarMenuButton, - SidebarMenuItem, - useSidebar, -} from "@/components/ui/sidebar"; - -export function NavDocuments({ - items, -}: { - items: { - name: string; - url: string; - icon: Icon; - }[]; -}) { - const { isMobile } = useSidebar(); - - return ( - - Documents - - {items.map((item) => ( - - - - - {item.name} - - - - - - - More - - - - - - Open - - - - Share - - - - - Delete - - - - - ))} - - - - More - - - - - ); -} diff --git a/apps/react/src/components/nav-main.tsx b/apps/react/src/components/nav-main.tsx deleted file mode 100644 index ac0332f..0000000 --- a/apps/react/src/components/nav-main.tsx +++ /dev/null @@ -1,54 +0,0 @@ -"use client"; - -import { type Icon, IconCirclePlusFilled, IconMail } from "@tabler/icons-react"; - -import { Button } from "@/components/ui/button"; -import { - SidebarGroup, - SidebarGroupContent, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, -} from "@/components/ui/sidebar"; - -export function NavMain({ - items, -}: { - items: { - title: string; - url: string; - icon?: Icon; - }[]; -}) { - return ( - - - - - - - Quick Create - - - - - - {items.map((item) => ( - - - {item.icon && } - {item.title} - - - ))} - - - - ); -} diff --git a/apps/react/src/components/nav-secondary.tsx b/apps/react/src/components/nav-secondary.tsx deleted file mode 100644 index 7690c2d..0000000 --- a/apps/react/src/components/nav-secondary.tsx +++ /dev/null @@ -1,42 +0,0 @@ -"use client"; - -import type { Icon } from "@tabler/icons-react"; -import type * as React from "react"; - -import { - SidebarGroup, - SidebarGroupContent, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, -} from "@/components/ui/sidebar"; - -export function NavSecondary({ - items, - ...props -}: { - items: { - title: string; - url: string; - icon: Icon; - }[]; -} & React.ComponentPropsWithoutRef) { - return ( - - - - {items.map((item) => ( - - - - - {item.title} - - - - ))} - - - - ); -} diff --git a/apps/react/src/components/nav-user.controller.ts b/apps/react/src/components/nav-user.controller.ts deleted file mode 100644 index 00667ce..0000000 --- a/apps/react/src/components/nav-user.controller.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Controller } from "../libraries/controller.tsx"; -import { type User as ZitadelUser, zitadel } from "../services/zitadel.ts"; - -export class NavUserController extends Controller<{ - user: User; -}> { - async onInit() { - return { - user: await this.#getAuthenticatedUser(), - }; - } - - async #getAuthenticatedUser(): Promise { - const user = await zitadel.userManager.getUser(); - if (user === null) { - throw new Error("Failed to resolve user session"); - } - return getUserProfile(user); - } - - signout() { - zitadel.signout(); - } -} - -function getUserProfile({ profile }: ZitadelUser): User { - const user: User = { name: "Unknown", email: "unknown@acme.none", avatar: "" }; - if (profile.name) { - user.name = profile.name; - } else if (profile.given_name && profile.family_name) { - user.name = `${profile.given_name} ${profile.family_name}`; - } else if (profile.given_name) { - user.name = profile.given_name; - } - if (profile.email) { - user.email = profile.email; - } - if (profile.picture !== undefined) { - user.avatar = profile.picture; - } - return user; -} - -type User = { - name: string; - email: string; - avatar: string; -}; diff --git a/apps/react/src/components/nav-user.tsx b/apps/react/src/components/nav-user.tsx deleted file mode 100644 index 0566929..0000000 --- a/apps/react/src/components/nav-user.tsx +++ /dev/null @@ -1,158 +0,0 @@ -"use client"; - -import { IconCreditCard, IconDotsVertical, IconLogout, IconNotification, IconUserCircle } from "@tabler/icons-react"; - -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar } from "@/components/ui/sidebar"; - -import { makeControllerComponent } from "../libraries/controller.tsx"; -import { NavUserController } from "./nav-user.controller.ts"; - -export const NavUser = makeControllerComponent(NavUserController, ({ user, signout }) => { - const { isMobile } = useSidebar(); - return ( - - - - - - - - CN - -
- {user.name} - {user.email} -
- -
-
- - -
- - - CN - -
- {user.name} - {user.email} -
-
-
- - - - - Account - - - - Billing - - - - Notifications - - - - signout()}> - - Log out - -
-
-
-
- ); -}); - -/* -export function NavUser() { - const [{ user }, loading, { signout }] = useController(NavUserController); - const { isMobile } = useSidebar(); - if (loading === true || user === undefined) { - return null; - } - return ( - - - - - - - - CN - -
- {user.name} - {user.email} -
- -
-
- - -
- - - CN - -
- {user.name} - {user.email} -
-
-
- - - - - Account - - - - Billing - - - - Notifications - - - - signout()}> - - Log out - -
-
-
-
- ); -} -*/ diff --git a/apps/react/src/components/site-header.tsx b/apps/react/src/components/site-header.tsx deleted file mode 100644 index c21931f..0000000 --- a/apps/react/src/components/site-header.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Button } from "@/components/ui/button"; -import { Separator } from "@/components/ui/separator"; -import { SidebarTrigger } from "@/components/ui/sidebar"; - -export function SiteHeader() { - return ( -
-
- - -

Documents

-
- -
-
-
- ); -} diff --git a/apps/react/src/components/theme-provider.tsx b/apps/react/src/components/theme-provider.tsx deleted file mode 100644 index 4d676bd..0000000 --- a/apps/react/src/components/theme-provider.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { createContext, useContext, useEffect, useState } from "react"; - -type Theme = "dark" | "light" | "system"; - -type ThemeProviderProps = { - children: React.ReactNode; - defaultTheme?: Theme; - storageKey?: string; -}; - -type ThemeProviderState = { - theme: Theme; - setTheme: (theme: Theme) => void; -}; - -const initialState: ThemeProviderState = { - theme: "system", - setTheme: () => null, -}; - -const ThemeProviderContext = createContext(initialState); - -export function ThemeProvider({ - children, - defaultTheme = "system", - storageKey = "vite-ui-theme", - ...props -}: ThemeProviderProps) { - const [theme, setTheme] = useState(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme); - - useEffect(() => { - const root = window.document.documentElement; - - root.classList.remove("light", "dark"); - - if (theme === "system") { - const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; - - root.classList.add(systemTheme); - return; - } - - root.classList.add(theme); - }, [theme]); - - const value = { - theme, - setTheme: (theme: Theme) => { - localStorage.setItem(storageKey, theme); - setTheme(theme); - }, - }; - - return ( - - {children} - - ); -} - -export const useTheme = () => { - const context = useContext(ThemeProviderContext); - - if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider"); - - return context; -}; diff --git a/apps/react/src/components/ui/avatar.tsx b/apps/react/src/components/ui/avatar.tsx deleted file mode 100644 index 35db151..0000000 --- a/apps/react/src/components/ui/avatar.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as AvatarPrimitive from "@radix-ui/react-avatar"; -import * as React from "react"; - -import { cn } from "../../libraries/utils.ts"; - -const Avatar = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -Avatar.displayName = AvatarPrimitive.Root.displayName; - -const AvatarImage = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AvatarImage.displayName = AvatarPrimitive.Image.displayName; - -const AvatarFallback = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; - -export { Avatar, AvatarImage, AvatarFallback }; diff --git a/apps/react/src/components/ui/breadcrumb.tsx b/apps/react/src/components/ui/breadcrumb.tsx deleted file mode 100644 index 126581a..0000000 --- a/apps/react/src/components/ui/breadcrumb.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { Slot } from "@radix-ui/react-slot"; -import { ChevronRight, MoreHorizontal } from "lucide-react"; -import * as React from "react"; - -import { cn } from "@/libraries/utils"; - -const Breadcrumb = React.forwardRef< - HTMLElement, - React.ComponentPropsWithoutRef<"nav"> & { - separator?: React.ReactNode; - } ->(({ ...props }, ref) =>