diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..6e87a003 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..3c3629e6 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..232e6d02 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,112 @@ +{ + "root": true, + "ignorePatterns": [ + "**/*" + ], + "plugins": [ + "@nx", + "@typescript-eslint", + "import", + "prettier" + ], + "extends": [ + "eslint:recommended", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript", + "plugin:prettier/recommended", + "google", + "plugin:@typescript-eslint/recommended" + ], + "overrides": [ + { + "files": [ + "*.ts", + "*.tsx", + "*.js", + "*.jsx" + ], + "rules": { + "@nx/enforce-module-boundaries": [ + "error", + { + "enforceBuildableLibDependency": true, + "allow": [], + "depConstraints": [ + { + "sourceTag": "app:frontend", + "onlyDependOnLibsWithTags": [ + "lib:frontend" + ] + }, + { + "sourceTag": "app:backend", + "onlyDependOnLibsWithTags": [ + "lib:backend" + ] + }, + { + "sourceTag": "lib:frontend", + "onlyDependOnLibsWithTags": [ + "lib:frontend" + ] + }, + { + "sourceTag": "lib:shared", + "onlyDependOnLibsWithTags": [ + "lib:shared" + ] + } + ] + } + ] + } + }, + { + "files": [ + "*.ts", + "*.tsx" + ], + "extends": [ + "plugin:@nx/typescript" + ], + "rules": {} + }, + { + "files": [ + "*.js", + "*.jsx" + ], + "extends": [ + "plugin:@nx/javascript" + ], + "rules": {} + } + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": [ + "tsconfig.json", + "tsconfig.dev.json" + ], + "sourceType": "module" + }, + "rules": { + "quotes": "off", // Use config from prettier + "max-len": "off", + "require-jsdoc": "off", + "import/no-unresolved": 0, + "indent": [ + "error", + 2, + { + "SwitchCase": 1 + } + ], + "operator-linebreak": [ + "error", + "before" + ], + "prettier/prettier": "error" + } +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..428f2b2c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + +permissions: + actions: read + contents: read + +jobs: + main: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # This enables task distribution via Nx Cloud + # Run this command as early as possible, before dependencies are installed + # Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun + - run: npx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci" + + # Cache node_modules + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + + - run: npm ci --legacy-peer-deps + - uses: nrwl/nx-set-shas@v4 + + # Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud + # - run: npx nx-cloud record -- echo Hello World + # Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected + - run: npx nx affected -t lint test build e2e-ci diff --git a/.gitignore b/.gitignore index 5b701348..2eb5c13f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,65 +4,68 @@ logs npm-debug.log* yarn-debug.log* yarn-error.log* -firebase-debug.log* -firebase-debug.*.log* -# Firebase cache -.firebase/ - -# Firebase config - -# Uncomment this if you'd like others to create their own Firebase project. -# For a team working on the same Firebase project(s), it is recommended to leave -# it commented so all members can deploy to the same project(s) in .firebaserc. -# .firebaserc - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript +# compiled output +dist +tmp +/out-tsc + +# dependencies +node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +.nx/cache +.nx/workspace-data + +# Next.js +.next +out -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity # dotenv environment variables file .env -.ignore/ \ No newline at end of file +.ignore/ + +# Firebase +.runtimeconfig.json +**/.emulators/* +**/.firebase/* +database-debug.log +firestore-debug.log +pubsub-debug.log +ui-debug.log +firebase-export* +.secret.local + +# Firebase cache +.firebase/ \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..e26f0b3f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache +/.nx/workspace-data \ No newline at end of file diff --git a/functions/.prettierrc b/.prettierrc similarity index 100% rename from functions/.prettierrc rename to .prettierrc diff --git a/.vscode/cspell.json b/.vscode/cspell.json index b7024fda..435751b6 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -2,10 +2,15 @@ "version": "0.2", "language": "en", "words": [ + "Buildable", + "datepicker", "firebaseui", "firestore", + "formgroup", "Genkit", "googleai", + "linebreak", + "satoshi", "tanam", "tiptap" ] diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..4e311339 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "nrwl.angular-console", + "esbenp.prettier-vscode", + "ms-playwright.playwright", + "firsttris.vscode-jest-runner" + ] +} diff --git a/apps/cloud-functions/.eslintrc.json b/apps/cloud-functions/.eslintrc.json new file mode 100644 index 00000000..9d9c0db5 --- /dev/null +++ b/apps/cloud-functions/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/cloud-functions/jest.config.ts b/apps/cloud-functions/jest.config.ts new file mode 100644 index 00000000..7f219476 --- /dev/null +++ b/apps/cloud-functions/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'cloud-functions', + preset: '../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/apps/cloud-functions', +}; diff --git a/apps/cloud-functions/project.json b/apps/cloud-functions/project.json new file mode 100644 index 00000000..655a99be --- /dev/null +++ b/apps/cloud-functions/project.json @@ -0,0 +1,68 @@ +{ + "name": "cloud-functions", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/cloud-functions/src", + "projectType": "application", + "tags": [ + "app:backend" + ], + "targets": { + "build": { + "executor": "@nx/esbuild:esbuild", + "outputs": [ + "{options.outputPath}" + ], + "defaultConfiguration": "production", + "options": { + "platform": "node", + "outputPath": "dist/apps/cloud-functions", + "format": [ + "cjs" + ], + "bundle": false, + "main": "apps/cloud-functions/src/main.ts", + "tsConfig": "apps/cloud-functions/tsconfig.app.json", + "assets": [ + "apps/cloud-functions/src/assets" + ], + "generatePackageJson": true, + "esbuildOptions": { + "sourcemap": true, + "outExtension": { + ".js": ".js" + } + } + }, + "configurations": { + "development": {}, + "production": { + "esbuildOptions": { + "sourcemap": false, + "outExtension": { + ".js": ".js" + } + } + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "dependsOn": [ + "build" + ], + "options": { + "buildTarget": "cloud-functions:build", + "runBuildTargetDependencies": false + }, + "configurations": { + "development": { + "buildTarget": "cloud-functions:build:development" + }, + "production": { + "buildTarget": "cloud-functions:build:production" + } + } + } + } +} diff --git a/functions/src/config.ts b/apps/cloud-functions/src/config.ts similarity index 100% rename from functions/src/config.ts rename to apps/cloud-functions/src/config.ts diff --git a/functions/src/index.ts b/apps/cloud-functions/src/index.ts similarity index 100% rename from functions/src/index.ts rename to apps/cloud-functions/src/index.ts diff --git a/apps/cloud-functions/src/main.ts b/apps/cloud-functions/src/main.ts new file mode 100644 index 00000000..accefceb --- /dev/null +++ b/apps/cloud-functions/src/main.ts @@ -0,0 +1 @@ +console.log("Hello World"); diff --git a/functions/src/triggers/document-publish.ts b/apps/cloud-functions/src/triggers/document-publish.ts similarity index 97% rename from functions/src/triggers/document-publish.ts rename to apps/cloud-functions/src/triggers/document-publish.ts index e24d1f41..0e80ea88 100644 --- a/functions/src/triggers/document-publish.ts +++ b/apps/cloud-functions/src/triggers/document-publish.ts @@ -1,3 +1,4 @@ +import {ITanamDocument, TanamDocumentAdmin} from "@tanam/domain-backend"; import * as admin from "firebase-admin"; import {Timestamp} from "firebase-admin/firestore"; import {getFunctions} from "firebase-admin/functions"; @@ -5,8 +6,6 @@ import {getStorage} from "firebase-admin/storage"; import {logger} from "firebase-functions/v2"; import {onDocumentWritten} from "firebase-functions/v2/firestore"; import {onTaskDispatched} from "firebase-functions/v2/tasks"; -import {ITanamDocument} from "tanam-shared/models/TanamDocument"; -import {TanamDocumentAdmin} from "../models/TanamDocumentAdmin"; const db = admin.firestore(); const storage = getStorage().bucket(); diff --git a/functions/src/triggers/users.ts b/apps/cloud-functions/src/triggers/users.ts similarity index 98% rename from functions/src/triggers/users.ts rename to apps/cloud-functions/src/triggers/users.ts index 12c08fcd..c3bff6a7 100644 --- a/functions/src/triggers/users.ts +++ b/apps/cloud-functions/src/triggers/users.ts @@ -1,3 +1,4 @@ +import {TanamRole, TanamUserAdmin} from "@tanam/domain-backend"; import axios from "axios"; import * as admin from "firebase-admin"; import {Timestamp} from "firebase-admin/firestore"; @@ -5,8 +6,6 @@ import {logger} from "firebase-functions/v2"; import {onDocumentCreated, onDocumentDeleted, onDocumentUpdated} from "firebase-functions/v2/firestore"; import {onObjectFinalized} from "firebase-functions/v2/storage"; import sharp from "sharp"; -import {TanamRole} from "tanam-shared/models/TanamUser"; -import {TanamUserAdmin} from "../models/TanamUserAdmin"; const auth = admin.auth(); const db = admin.firestore(); diff --git a/functions/src/utils/task-queue-utility.ts b/apps/cloud-functions/src/utils/task-queue-utility.ts similarity index 100% rename from functions/src/utils/task-queue-utility.ts rename to apps/cloud-functions/src/utils/task-queue-utility.ts diff --git a/functions/tsconfig.json b/apps/cloud-functions/tsconfig.app.json similarity index 53% rename from functions/tsconfig.json rename to apps/cloud-functions/tsconfig.app.json index 4894bc7d..8c46eaf3 100644 --- a/functions/tsconfig.json +++ b/apps/cloud-functions/tsconfig.app.json @@ -1,19 +1,26 @@ { + "extends": "./tsconfig.json", "compileOnSave": true, - "include": ["src"], + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts" + ], + "include": [ + "src/**/*.ts" + ], "compilerOptions": { + "outDir": "../../dist/out-tsc", "module": "commonjs", + "types": [ + "node" + ], "noImplicitReturns": true, - "outDir": "lib", "sourceMap": true, "strict": true, "target": "es2017", "skipLibCheck": true, "esModuleInterop": true, "noUnusedLocals": true, - "paths": { - "@/*": ["./src/*"], - "tanam-shared/*": ["../shared/src/*"] - } } } diff --git a/apps/cloud-functions/tsconfig.json b/apps/cloud-functions/tsconfig.json new file mode 100644 index 00000000..cdeaa11b --- /dev/null +++ b/apps/cloud-functions/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/apps/cloud-functions/tsconfig.spec.json b/apps/cloud-functions/tsconfig.spec.json new file mode 100644 index 00000000..9b2a121d --- /dev/null +++ b/apps/cloud-functions/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/cms-e2e/.eslintrc.json b/apps/cms-e2e/.eslintrc.json new file mode 100644 index 00000000..fbf2c975 --- /dev/null +++ b/apps/cms-e2e/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "extends": ["plugin:playwright/recommended", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["src/**/*.{ts,js,tsx,jsx}"], + "rules": {} + } + ] +} diff --git a/apps/cms-e2e/playwright.config.ts b/apps/cms-e2e/playwright.config.ts new file mode 100644 index 00000000..bcde6ce1 --- /dev/null +++ b/apps/cms-e2e/playwright.config.ts @@ -0,0 +1,69 @@ +import {nxE2EPreset} from "@nx/playwright/preset"; +import {defineConfig, devices} from "@playwright/test"; + +import {workspaceRoot} from "@nx/devkit"; + +// For CI, you may want to set BASE_URL to the deployed application. +const baseURL = process.env["BASE_URL"] || "http://localhost:3000"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + ...nxE2EPreset(__filename, {testDir: "./src"}), + /* domain settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + baseURL, + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + /* Run your local dev server before starting the tests */ + webServer: { + command: "npx nx run cms:serve-static", + url: "http://localhost:3000", + reuseExistingServer: !process.env.CI, + cwd: workspaceRoot, + }, + projects: [ + { + name: "chromium", + use: {...devices["Desktop Chrome"]}, + }, + + { + name: "firefox", + use: {...devices["Desktop Firefox"]}, + }, + + { + name: "webkit", + use: {...devices["Desktop Safari"]}, + }, + + // Uncomment for mobile browsers support + /* { + name: 'Mobile Chrome', + use: { ...devices['Pixel 5'] }, + }, + { + name: 'Mobile Safari', + use: { ...devices['iPhone 12'] }, + }, */ + + // Uncomment for branded browsers + /* { + name: 'Microsoft Edge', + use: { ...devices['Desktop Edge'], channel: 'msedge' }, + }, + { + name: 'Google Chrome', + use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + } */ + ], +}); diff --git a/apps/cms-e2e/project.json b/apps/cms-e2e/project.json new file mode 100644 index 00000000..e929488b --- /dev/null +++ b/apps/cms-e2e/project.json @@ -0,0 +1,11 @@ +{ + "name": "cms-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/cms-e2e/src", + "tags": [], + "implicitDependencies": [ + "cms" + ], + "// targets": "to see all targets run: nx show project cms-e2e --web", + "targets": {} +} diff --git a/apps/cms-e2e/src/example.spec.ts b/apps/cms-e2e/src/example.spec.ts new file mode 100644 index 00000000..8e974754 --- /dev/null +++ b/apps/cms-e2e/src/example.spec.ts @@ -0,0 +1,8 @@ +import {test, expect} from "@playwright/test"; + +test("has title", async ({page}) => { + await page.goto("/"); + + // Expect h1 to contain a substring. + expect(await page.locator("h1").innerText()).toContain("Welcome"); +}); diff --git a/apps/cms-e2e/tsconfig.json b/apps/cms-e2e/tsconfig.json new file mode 100644 index 00000000..affcc88c --- /dev/null +++ b/apps/cms-e2e/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "allowJs": true, + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "sourceMap": false + }, + "include": [ + "**/*.ts", + "**/*.js", + "playwright.config.ts", + "src/**/*.spec.ts", + "src/**/*.spec.js", + "src/**/*.test.ts", + "src/**/*.test.js", + "src/**/*.d.ts" + ] +} diff --git a/apps/cms/.env.local.example b/apps/cms/.env.local.example new file mode 100644 index 00000000..14e24ee0 --- /dev/null +++ b/apps/cms/.env.local.example @@ -0,0 +1,7 @@ +NEXT_PUBLIC_FIREBASE_API_KEY= +NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN= +NEXT_PUBLIC_FIREBASE_DATABASE_URL= +NEXT_PUBLIC_FIREBASE_PROJECT_ID= +NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET= +NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID= +NEXT_PUBLIC_FIREBASE_APP_ID= diff --git a/apps/cms/.eslintrc.json b/apps/cms/.eslintrc.json new file mode 100644 index 00000000..2bde8185 --- /dev/null +++ b/apps/cms/.eslintrc.json @@ -0,0 +1,53 @@ +{ + "extends": [ + "plugin:@nx/react-typescript", + "next", + "next/core-web-vitals", + "../../.eslintrc.json" + ], + "ignorePatterns": [ + "!**/*", + ".next/**/*" + ], + "overrides": [ + { + "files": [ + "*.ts", + "*.tsx", + "*.js", + "*.jsx" + ], + "rules": { + "@next/next/no-html-link-for-pages": [ + "error", + "apps/cms/pages" + ] + } + }, + { + "files": [ + "*.ts", + "*.tsx" + ], + "rules": {} + }, + { + "files": [ + "*.js", + "*.jsx" + ], + "rules": {} + }, + { + "files": [ + "*.spec.ts", + "*.spec.tsx", + "*.spec.js", + "*.spec.jsx" + ], + "env": { + "jest": true + } + } + ] +} diff --git a/hosting/genkit-tools.conf.js b/apps/cms/genkit-tools.conf.js similarity index 100% rename from hosting/genkit-tools.conf.js rename to apps/cms/genkit-tools.conf.js diff --git a/apps/cms/index.d.ts b/apps/cms/index.d.ts new file mode 100644 index 00000000..2ac88d92 --- /dev/null +++ b/apps/cms/index.d.ts @@ -0,0 +1,6 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +declare module "*.svg" { + const content: any; + export const ReactComponent: any; + export default content; +} diff --git a/apps/cms/jest.config.ts b/apps/cms/jest.config.ts new file mode 100644 index 00000000..f7c9b3ea --- /dev/null +++ b/apps/cms/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'cms', + preset: '../../jest.preset.js', + transform: { + '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', + '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/next/babel'] }], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/apps/cms', +}; diff --git a/apps/cms/next-env.d.ts b/apps/cms/next-env.d.ts new file mode 100644 index 00000000..5636f3f6 --- /dev/null +++ b/apps/cms/next-env.d.ts @@ -0,0 +1,6 @@ +// / +// / +// / + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/apps/cms/next.config.js b/apps/cms/next.config.js new file mode 100644 index 00000000..2c302962 --- /dev/null +++ b/apps/cms/next.config.js @@ -0,0 +1,35 @@ +// @ts-check + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const {composePlugins, withNx} = require("@nx/next"); + +/** + * @type {import('@nx/next/plugins/with-nx').WithNxOptions} + **/ +const nextConfig = { + images: { + domains: ["lh3.googleusercontent.com", "firebasestorage.googleapis.com"], + }, + redirects() { + return Promise.resolve([ + { + source: "/auth", + destination: "/auth/signin", + permanent: true, + }, + ]); + }, + + nx: { + // Set this to true if you would like to use SVGR + // See: https://github.com/gregberge/svgr + svgr: false, + }, +}; + +const plugins = [ + // Add more Next.js plugins to this list if needed. + withNx, +]; + +module.exports = composePlugins(...plugins)(nextConfig); diff --git a/hosting/postcss.config.js b/apps/cms/postcss.config.js similarity index 100% rename from hosting/postcss.config.js rename to apps/cms/postcss.config.js diff --git a/apps/cms/project.json b/apps/cms/project.json new file mode 100644 index 00000000..44a5fe6b --- /dev/null +++ b/apps/cms/project.json @@ -0,0 +1,11 @@ +{ + "name": "cms", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/cms", + "projectType": "application", + "tags": [ + "app:frontend" + ], + "// targets": "to see all targets run: nx show project cms --web", + "targets": {} +} diff --git a/hosting/public/images/logo.svg b/apps/cms/public/images/logo.svg similarity index 100% rename from hosting/public/images/logo.svg rename to apps/cms/public/images/logo.svg diff --git a/hosting/public/images/no-image.png b/apps/cms/public/images/no-image.png similarity index 100% rename from hosting/public/images/no-image.png rename to apps/cms/public/images/no-image.png diff --git a/apps/cms/specs/index.spec.tsx b/apps/cms/specs/index.spec.tsx new file mode 100644 index 00000000..92f24c9f --- /dev/null +++ b/apps/cms/specs/index.spec.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import {render} from "@testing-library/react"; + +import Page from "../src/app/page"; + +describe("Page", () => { + it("should render successfully", () => { + const {baseElement} = render(); + expect(baseElement).toBeTruthy(); + }); +}); diff --git a/hosting/src/app/(protected)/content/[documentTypeId]/[documentId]/page.tsx b/apps/cms/src/app/(protected)/content/[documentTypeId]/[documentId]/page.tsx similarity index 82% rename from hosting/src/app/(protected)/content/[documentTypeId]/[documentId]/page.tsx rename to apps/cms/src/app/(protected)/content/[documentTypeId]/[documentId]/page.tsx index 4c6c588f..79f34f97 100644 --- a/hosting/src/app/(protected)/content/[documentTypeId]/[documentId]/page.tsx +++ b/apps/cms/src/app/(protected)/content/[documentTypeId]/[documentId]/page.tsx @@ -1,27 +1,26 @@ "use client"; -import ContentCard from "@/components/Containers/ContentCard"; +import {TanamDocumentField, UserNotification} from "@tanam/domain-frontend"; import { Checkbox, + ContentCard, DatePicker, Dropdown, FileUpload, FormGroup, Input, + Loader, + Notification, + PageHeader, RadioButton, Switcher, TextArea, -} from "@/components/Form"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {useTanamDocumentFields} from "@/hooks/useTanamDocumentFields"; -import {useTanamDocumentType} from "@/hooks/useTanamDocumentTypes"; -import {useTanamDocument} from "@/hooks/useTanamDocuments"; -import {UserNotification} from "@/models/UserNotification"; +} from "@tanam/ui-components"; import {Timestamp} from "firebase/firestore"; import {useParams, useRouter} from "next/navigation"; import {Suspense, useEffect, useState} from "react"; -import {TanamDocumentField} from "tanam-shared/models/TanamDocumentField"; +import {useTanamDocumentFields} from "../../../../../hooks/useTanamDocumentFields"; +import {useTanamDocumentType} from "../../../../../hooks/useTanamDocumentTypes"; +import {useTanamDocument} from "../../../../../hooks/useTanamDocuments"; const DocumentDetailsPage = () => { const router = useRouter(); @@ -33,14 +32,15 @@ const DocumentDetailsPage = () => { const [readonlyMode] = useState(true); const [notification, setNotification] = useState(null); - if (!!document?.documentType && document?.documentType !== documentTypeId) { - router.push(`/content/${document?.documentType}/${document?.id}`); - return ; - } - useEffect(() => { setNotification(documentError ?? typeError ?? fieldsError); - }, [documentError]); + }, [documentError, typeError, fieldsError]); + + useEffect(() => { + if (!!document?.documentType && document?.documentType !== documentTypeId) { + router.push(`/content/${document?.documentType}/${document?.id}`); + } + }, [document, documentTypeId, router]); const renderFormElement = (field: TanamDocumentField, value: any) => { const formgroupKey = `formgroup-${field.id}`; diff --git a/hosting/src/app/(protected)/content/[documentTypeId]/page.tsx b/apps/cms/src/app/(protected)/content/[documentTypeId]/page.tsx similarity index 74% rename from hosting/src/app/(protected)/content/[documentTypeId]/page.tsx rename to apps/cms/src/app/(protected)/content/[documentTypeId]/page.tsx index e7c4851c..2ad033a0 100644 --- a/hosting/src/app/(protected)/content/[documentTypeId]/page.tsx +++ b/apps/cms/src/app/(protected)/content/[documentTypeId]/page.tsx @@ -1,14 +1,10 @@ "use client"; -import {DocumentTypeGenericList} from "@/components/DocumentType/DocumentTypeGenericList"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {useTanamDocumentType} from "@/hooks/useTanamDocumentTypes"; -import {useTanamDocuments} from "@/hooks/useTanamDocuments"; -import {Suspense, useEffect, useState} from "react"; +import {UserNotification} from "@tanam/domain-frontend"; +import {Button, DocumentTypeGenericList, Loader, Notification, PageHeader} from "@tanam/ui-components"; import {useParams} from "next/navigation"; -import {UserNotification} from "@/models/UserNotification"; -import {Button} from "@/components/Button"; +import {Suspense, useEffect, useState} from "react"; +import {useTanamDocumentType} from "../../../../hooks/useTanamDocumentTypes"; +import {useTanamDocuments} from "../../../../hooks/useTanamDocuments"; export default function DocumentTypeDocumentsPage() { const {documentTypeId} = useParams<{documentTypeId: string}>() ?? {}; @@ -20,7 +16,9 @@ export default function DocumentTypeDocumentsPage() { setNotification(docsError); }, [docsError]); - const addNewDocument = async () => {}; + const addNewDocument = async () => { + // Add your code here + }; return ( <> diff --git a/hosting/src/app/(protected)/content/article/[documentId]/page.tsx b/apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx similarity index 83% rename from hosting/src/app/(protected)/content/article/[documentId]/page.tsx rename to apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx index 4b580e00..bf019683 100644 --- a/hosting/src/app/(protected)/content/article/[documentId]/page.tsx +++ b/apps/cms/src/app/(protected)/content/article/[documentId]/page.tsx @@ -1,17 +1,13 @@ "use client"; -import {Button} from "@/components/Button"; -import {Input} from "@/components/Form"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {useCrudTanamDocument, useTanamDocument} from "@/hooks/useTanamDocuments"; -import {UserNotification} from "@/models/UserNotification"; +import { UserNotification } from "@tanam/domain-frontend"; +import { Button, Input, Loader, Notification, PageHeader } from "@tanam/ui-components"; import dynamic from "next/dynamic"; -import {useParams, useRouter} from "next/navigation"; -import {Suspense, useEffect, useState} from "react"; +import { useParams, useRouter } from "next/navigation"; +import { Suspense, useEffect, useState } from "react"; +import { useCrudTanamDocument, useTanamDocument } from "../../../../../hooks/useTanamDocuments"; // TiptapEditor is also detected as ssr, even though it uses "use client" :( -const TiptapEditor = dynamic(() => import("@/components/Tiptap/TiptapEditor"), { +const TiptapEditor = dynamic(() => import("@tanam/ui-components"; ssr: false, }); diff --git a/hosting/src/app/(protected)/content/article/page.tsx b/apps/cms/src/app/(protected)/content/article/page.tsx similarity index 87% rename from hosting/src/app/(protected)/content/article/page.tsx rename to apps/cms/src/app/(protected)/content/article/page.tsx index 7ed3ca61..a2a31b30 100644 --- a/hosting/src/app/(protected)/content/article/page.tsx +++ b/apps/cms/src/app/(protected)/content/article/page.tsx @@ -1,25 +1,19 @@ "use client"; -import {Button} from "@/components/Button"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {DocumentTypeGenericList} from "@/components/DocumentType/DocumentTypeGenericList"; -import FilePicker from "@/components/FilePicker"; -import {Modal} from "@/components/Modal"; -import {useAuthentication} from "@/hooks/useAuthentication"; -import {ProcessingState, useGenkitArticle} from "@/hooks/useGenkitArticle"; -import {useCrudTanamDocument, useTanamDocuments} from "@/hooks/useTanamDocuments"; -import {useTanamDocumentType} from "@/hooks/useTanamDocumentTypes"; -import {UserNotification} from "@/models/UserNotification"; -import {base64ToFile} from "@/plugins/fileUpload"; +import { UserNotification } from "@tanam/domain-frontend"; +import { Button } from "@tanam/ui-components"; import dynamic from "next/dynamic"; -import {useRouter} from "next/navigation"; -import {Suspense, useEffect, useState} from "react"; +import { useRouter } from "next/navigation"; +import { Suspense, useEffect, useState } from "react"; +import { useAuthentication } from "../../../../hooks/useAuthentication"; +import { ProcessingState, useGenkitArticle } from "../../../../hooks/useGenkitArticle"; +import { useCrudTanamDocument, useTanamDocuments } from "../../../../hooks/useTanamDocuments"; +import { useTanamDocumentType } from "../../../../hooks/useTanamDocumentTypes"; +import { base64ToFile } from "../../../../plugins/fileUpload"; // I don't know why this component always errors // when built because this component is still detected as a component rendered on the server. // Even though I've used "use client" inside the component :( -const VoiceRecorder = dynamic(() => import("@/components/VoiceRecorder"), { +const VoiceRecorder = dynamic(() => import("@tanam/ui-components"; ssr: false, }); diff --git a/hosting/src/app/(protected)/content/page.tsx b/apps/cms/src/app/(protected)/content/page.tsx similarity index 77% rename from hosting/src/app/(protected)/content/page.tsx rename to apps/cms/src/app/(protected)/content/page.tsx index 6ae89282..9e67acb2 100644 --- a/hosting/src/app/(protected)/content/page.tsx +++ b/apps/cms/src/app/(protected)/content/page.tsx @@ -1,16 +1,11 @@ "use client"; -import {Button} from "@/components/Button"; -import ContentCard from "@/components/Containers/ContentCard"; -import {Table, TableRowLabel} from "@/components/Table"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {useCreateDocumentType} from "@/hooks/useCreateDocumentType"; -import {useTanamDocumentTypes} from "@/hooks/useTanamDocumentTypes"; -import {UserNotification} from "@/models/UserNotification"; -import {getDocumentTypeArticle, getDocumentTypePerson} from "@/utils/documentTypeGenerator"; +import {UserNotification} from "@tanam/domain-frontend"; +import {Button, ContentCard, Loader, Notification, PageHeader, Table, TableRowLabel} from "@tanam/ui-components"; import Link from "next/link"; import {Suspense, useEffect, useState} from "react"; +import {useCreateDocumentType} from "../../../hooks/useCreateDocumentType"; +import {useTanamDocumentTypes} from "../../../hooks/useTanamDocumentTypes"; +import {getDocumentTypeArticle, getDocumentTypePerson} from "../../../utils/documentTypeGenerator"; export default function DocumentTypeDocumentsPage() { const {data: documentTypes, error: typesError} = useTanamDocumentTypes(); diff --git a/hosting/src/app/(protected)/dashboard/page.tsx b/apps/cms/src/app/(protected)/dashboard/page.tsx similarity index 100% rename from hosting/src/app/(protected)/dashboard/page.tsx rename to apps/cms/src/app/(protected)/dashboard/page.tsx diff --git a/hosting/src/app/(protected)/error/insufficient-role/page.tsx b/apps/cms/src/app/(protected)/error/insufficient-role/page.tsx similarity index 64% rename from hosting/src/app/(protected)/error/insufficient-role/page.tsx rename to apps/cms/src/app/(protected)/error/insufficient-role/page.tsx index 9f68ba91..f3094520 100644 --- a/hosting/src/app/(protected)/error/insufficient-role/page.tsx +++ b/apps/cms/src/app/(protected)/error/insufficient-role/page.tsx @@ -1,10 +1,8 @@ "use client"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {useAuthentication} from "@/hooks/useAuthentication"; -import {useTanamUser} from "@/hooks/useTanamUser"; +import {Loader, Notification, PageHeader} from "@tanam/ui-components"; import {Suspense} from "react"; +import {useAuthentication} from "../../../../hooks/useAuthentication"; +import {useTanamUser} from "../../../../hooks/useTanamUser"; export default function ErrorInsufficientRolePage() { const {authUser} = useAuthentication(); diff --git a/hosting/src/app/(protected)/error/page.tsx b/apps/cms/src/app/(protected)/error/page.tsx similarity index 64% rename from hosting/src/app/(protected)/error/page.tsx rename to apps/cms/src/app/(protected)/error/page.tsx index ba7ce983..170fe462 100644 --- a/hosting/src/app/(protected)/error/page.tsx +++ b/apps/cms/src/app/(protected)/error/page.tsx @@ -1,7 +1,5 @@ "use client"; -import Loader from "@/components/common/Loader"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; +import {Loader, Notification, PageHeader} from "@tanam/ui-components"; import {Suspense} from "react"; export default function ErrorPage() { diff --git a/hosting/src/app/(protected)/layout.tsx b/apps/cms/src/app/(protected)/layout.tsx similarity index 74% rename from hosting/src/app/(protected)/layout.tsx rename to apps/cms/src/app/(protected)/layout.tsx index 96eee477..19ca83b0 100644 --- a/hosting/src/app/(protected)/layout.tsx +++ b/apps/cms/src/app/(protected)/layout.tsx @@ -1,8 +1,8 @@ "use client"; -import CmsLayout from "@/components/Layouts/CmsLayout"; -import {useAuthentication} from "@/hooks/useAuthentication"; import {redirect} from "next/navigation"; import React from "react"; +import CmsLayout from "../../components/Layouts/CmsLayout"; +import {useAuthentication} from "../../hooks/useAuthentication"; interface ProtectedLayoutProps { children: React.ReactNode; diff --git a/hosting/src/app/(protected)/settings/page.tsx b/apps/cms/src/app/(protected)/settings/page.tsx similarity index 94% rename from hosting/src/app/(protected)/settings/page.tsx rename to apps/cms/src/app/(protected)/settings/page.tsx index b65074ad..27ebea5a 100644 --- a/hosting/src/app/(protected)/settings/page.tsx +++ b/apps/cms/src/app/(protected)/settings/page.tsx @@ -1,17 +1,12 @@ "use client"; -import Notification from "@/components/common/Notification"; -import PageHeader from "@/components/common/PageHeader"; -import {CropImage} from "@/components/CropImage"; -import DarkModeSwitcher from "@/components/DarkModeSwitcher"; -import {Dropzone} from "@/components/Form/Dropzone"; -import {Modal} from "@/components/Modal"; -import {useAuthentication} from "@/hooks/useAuthentication"; -import {useFirebaseStorage} from "@/hooks/useFirebaseStorage"; -import {useTanamUser} from "@/hooks/useTanamUser"; -import {UserNotification} from "@/models/UserNotification"; +import {AcceptFileType, UserNotification} from "@tanam/domain-frontend"; +import {CropImage, Dropzone, Modal, Notification, PageHeader} from "@tanam/ui-components"; import Image from "next/image"; import {useEffect, useState} from "react"; -import {AcceptFileType} from "tanam-shared/definitions/AcceptFileType"; +import DarkModeSwitcher from "../../../components/DarkModeSwitcher"; +import {useAuthentication} from "../../../hooks/useAuthentication"; +import {useFirebaseStorage} from "../../../hooks/useFirebaseStorage"; +import {useTanamUser} from "../../../hooks/useTanamUser"; const defaultImage = "/images/no-image.png"; diff --git a/hosting/src/app/(public)/auth/[authAction]/page.tsx b/apps/cms/src/app/(public)/auth/[authAction]/page.tsx similarity index 90% rename from hosting/src/app/(public)/auth/[authAction]/page.tsx rename to apps/cms/src/app/(public)/auth/[authAction]/page.tsx index 023ed26b..ed81d55c 100644 --- a/hosting/src/app/(public)/auth/[authAction]/page.tsx +++ b/apps/cms/src/app/(public)/auth/[authAction]/page.tsx @@ -1,9 +1,9 @@ "use client"; -import "@/assets/scss/layout-authentication.scss"; -import {useFirebaseUi} from "@/hooks/useFirebaseUi"; +import "@tanam/cms/assets/scss/layout-authentication.scss"; import Image from "next/image"; import {notFound, useParams} from "next/navigation"; import {useEffect} from "react"; +import {useFirebaseUi} from "../../../../../hooks/useFirebaseUi"; export default function AuthPage() { const {authAction} = useParams<{authAction: string}>() ?? {}; diff --git a/hosting/src/app/(public)/layout.tsx b/apps/cms/src/app/(public)/layout.tsx similarity index 72% rename from hosting/src/app/(public)/layout.tsx rename to apps/cms/src/app/(public)/layout.tsx index 7a69c065..88bfb6eb 100644 --- a/hosting/src/app/(public)/layout.tsx +++ b/apps/cms/src/app/(public)/layout.tsx @@ -1,7 +1,7 @@ "use client"; -import "@/assets/css/satoshi.css"; -import "@/assets/css/style.css"; +import "@tanam/cms/assets/css/satoshi.css"; +import "@tanam/cms/assets/css/style.css"; import React from "react"; interface PublicLayoutProps { diff --git a/hosting/src/app/favicon.ico b/apps/cms/src/app/favicon.ico similarity index 100% rename from hosting/src/app/favicon.ico rename to apps/cms/src/app/favicon.ico diff --git a/hosting/src/app/layout.tsx b/apps/cms/src/app/layout.tsx similarity index 100% rename from hosting/src/app/layout.tsx rename to apps/cms/src/app/layout.tsx diff --git a/hosting/src/app/page.tsx b/apps/cms/src/app/page.tsx similarity index 71% rename from hosting/src/app/page.tsx rename to apps/cms/src/app/page.tsx index dd1994f7..28743711 100644 --- a/hosting/src/app/page.tsx +++ b/apps/cms/src/app/page.tsx @@ -1,7 +1,7 @@ "use client"; -import {useAuthentication} from "@/hooks/useAuthentication"; +import {Loader} from "@tanam/ui-components"; import {redirect} from "next/navigation"; -import Loader from "../components/common/Loader"; +import {useAuthentication} from "../hooks/useAuthentication"; export default function HomePage() { const {isSignedIn} = useAuthentication(); diff --git a/hosting/src/assets/css/satoshi.css b/apps/cms/src/assets/css/satoshi.css similarity index 100% rename from hosting/src/assets/css/satoshi.css rename to apps/cms/src/assets/css/satoshi.css diff --git a/hosting/src/assets/css/style.css b/apps/cms/src/assets/css/style.css similarity index 100% rename from hosting/src/assets/css/style.css rename to apps/cms/src/assets/css/style.css diff --git a/hosting/src/assets/fonts/Satoshi-Black.eot b/apps/cms/src/assets/fonts/Satoshi-Black.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Black.eot rename to apps/cms/src/assets/fonts/Satoshi-Black.eot diff --git a/hosting/src/assets/fonts/Satoshi-Black.ttf b/apps/cms/src/assets/fonts/Satoshi-Black.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Black.ttf rename to apps/cms/src/assets/fonts/Satoshi-Black.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Black.woff b/apps/cms/src/assets/fonts/Satoshi-Black.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Black.woff rename to apps/cms/src/assets/fonts/Satoshi-Black.woff diff --git a/hosting/src/assets/fonts/Satoshi-Black.woff2 b/apps/cms/src/assets/fonts/Satoshi-Black.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Black.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Black.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-BlackItalic.eot b/apps/cms/src/assets/fonts/Satoshi-BlackItalic.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BlackItalic.eot rename to apps/cms/src/assets/fonts/Satoshi-BlackItalic.eot diff --git a/hosting/src/assets/fonts/Satoshi-BlackItalic.ttf b/apps/cms/src/assets/fonts/Satoshi-BlackItalic.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BlackItalic.ttf rename to apps/cms/src/assets/fonts/Satoshi-BlackItalic.ttf diff --git a/hosting/src/assets/fonts/Satoshi-BlackItalic.woff b/apps/cms/src/assets/fonts/Satoshi-BlackItalic.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BlackItalic.woff rename to apps/cms/src/assets/fonts/Satoshi-BlackItalic.woff diff --git a/hosting/src/assets/fonts/Satoshi-BlackItalic.woff2 b/apps/cms/src/assets/fonts/Satoshi-BlackItalic.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BlackItalic.woff2 rename to apps/cms/src/assets/fonts/Satoshi-BlackItalic.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-Bold.eot b/apps/cms/src/assets/fonts/Satoshi-Bold.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Bold.eot rename to apps/cms/src/assets/fonts/Satoshi-Bold.eot diff --git a/hosting/src/assets/fonts/Satoshi-Bold.ttf b/apps/cms/src/assets/fonts/Satoshi-Bold.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Bold.ttf rename to apps/cms/src/assets/fonts/Satoshi-Bold.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Bold.woff b/apps/cms/src/assets/fonts/Satoshi-Bold.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Bold.woff rename to apps/cms/src/assets/fonts/Satoshi-Bold.woff diff --git a/hosting/src/assets/fonts/Satoshi-Bold.woff2 b/apps/cms/src/assets/fonts/Satoshi-Bold.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Bold.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Bold.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-BoldItalic.eot b/apps/cms/src/assets/fonts/Satoshi-BoldItalic.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BoldItalic.eot rename to apps/cms/src/assets/fonts/Satoshi-BoldItalic.eot diff --git a/hosting/src/assets/fonts/Satoshi-BoldItalic.ttf b/apps/cms/src/assets/fonts/Satoshi-BoldItalic.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BoldItalic.ttf rename to apps/cms/src/assets/fonts/Satoshi-BoldItalic.ttf diff --git a/hosting/src/assets/fonts/Satoshi-BoldItalic.woff b/apps/cms/src/assets/fonts/Satoshi-BoldItalic.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BoldItalic.woff rename to apps/cms/src/assets/fonts/Satoshi-BoldItalic.woff diff --git a/hosting/src/assets/fonts/Satoshi-BoldItalic.woff2 b/apps/cms/src/assets/fonts/Satoshi-BoldItalic.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-BoldItalic.woff2 rename to apps/cms/src/assets/fonts/Satoshi-BoldItalic.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-Italic.eot b/apps/cms/src/assets/fonts/Satoshi-Italic.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Italic.eot rename to apps/cms/src/assets/fonts/Satoshi-Italic.eot diff --git a/hosting/src/assets/fonts/Satoshi-Italic.ttf b/apps/cms/src/assets/fonts/Satoshi-Italic.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Italic.ttf rename to apps/cms/src/assets/fonts/Satoshi-Italic.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Italic.woff b/apps/cms/src/assets/fonts/Satoshi-Italic.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Italic.woff rename to apps/cms/src/assets/fonts/Satoshi-Italic.woff diff --git a/hosting/src/assets/fonts/Satoshi-Italic.woff2 b/apps/cms/src/assets/fonts/Satoshi-Italic.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Italic.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Italic.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-Light.eot b/apps/cms/src/assets/fonts/Satoshi-Light.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Light.eot rename to apps/cms/src/assets/fonts/Satoshi-Light.eot diff --git a/hosting/src/assets/fonts/Satoshi-Light.ttf b/apps/cms/src/assets/fonts/Satoshi-Light.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Light.ttf rename to apps/cms/src/assets/fonts/Satoshi-Light.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Light.woff b/apps/cms/src/assets/fonts/Satoshi-Light.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Light.woff rename to apps/cms/src/assets/fonts/Satoshi-Light.woff diff --git a/hosting/src/assets/fonts/Satoshi-Light.woff2 b/apps/cms/src/assets/fonts/Satoshi-Light.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Light.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Light.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-LightItalic.eot b/apps/cms/src/assets/fonts/Satoshi-LightItalic.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-LightItalic.eot rename to apps/cms/src/assets/fonts/Satoshi-LightItalic.eot diff --git a/hosting/src/assets/fonts/Satoshi-LightItalic.ttf b/apps/cms/src/assets/fonts/Satoshi-LightItalic.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-LightItalic.ttf rename to apps/cms/src/assets/fonts/Satoshi-LightItalic.ttf diff --git a/hosting/src/assets/fonts/Satoshi-LightItalic.woff b/apps/cms/src/assets/fonts/Satoshi-LightItalic.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-LightItalic.woff rename to apps/cms/src/assets/fonts/Satoshi-LightItalic.woff diff --git a/hosting/src/assets/fonts/Satoshi-LightItalic.woff2 b/apps/cms/src/assets/fonts/Satoshi-LightItalic.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-LightItalic.woff2 rename to apps/cms/src/assets/fonts/Satoshi-LightItalic.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-Medium.eot b/apps/cms/src/assets/fonts/Satoshi-Medium.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Medium.eot rename to apps/cms/src/assets/fonts/Satoshi-Medium.eot diff --git a/hosting/src/assets/fonts/Satoshi-Medium.ttf b/apps/cms/src/assets/fonts/Satoshi-Medium.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Medium.ttf rename to apps/cms/src/assets/fonts/Satoshi-Medium.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Medium.woff b/apps/cms/src/assets/fonts/Satoshi-Medium.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Medium.woff rename to apps/cms/src/assets/fonts/Satoshi-Medium.woff diff --git a/hosting/src/assets/fonts/Satoshi-Medium.woff2 b/apps/cms/src/assets/fonts/Satoshi-Medium.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Medium.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Medium.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-MediumItalic.eot b/apps/cms/src/assets/fonts/Satoshi-MediumItalic.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-MediumItalic.eot rename to apps/cms/src/assets/fonts/Satoshi-MediumItalic.eot diff --git a/hosting/src/assets/fonts/Satoshi-MediumItalic.ttf b/apps/cms/src/assets/fonts/Satoshi-MediumItalic.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-MediumItalic.ttf rename to apps/cms/src/assets/fonts/Satoshi-MediumItalic.ttf diff --git a/hosting/src/assets/fonts/Satoshi-MediumItalic.woff b/apps/cms/src/assets/fonts/Satoshi-MediumItalic.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-MediumItalic.woff rename to apps/cms/src/assets/fonts/Satoshi-MediumItalic.woff diff --git a/hosting/src/assets/fonts/Satoshi-MediumItalic.woff2 b/apps/cms/src/assets/fonts/Satoshi-MediumItalic.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-MediumItalic.woff2 rename to apps/cms/src/assets/fonts/Satoshi-MediumItalic.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-Regular.eot b/apps/cms/src/assets/fonts/Satoshi-Regular.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Regular.eot rename to apps/cms/src/assets/fonts/Satoshi-Regular.eot diff --git a/hosting/src/assets/fonts/Satoshi-Regular.ttf b/apps/cms/src/assets/fonts/Satoshi-Regular.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Regular.ttf rename to apps/cms/src/assets/fonts/Satoshi-Regular.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Regular.woff b/apps/cms/src/assets/fonts/Satoshi-Regular.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Regular.woff rename to apps/cms/src/assets/fonts/Satoshi-Regular.woff diff --git a/hosting/src/assets/fonts/Satoshi-Regular.woff2 b/apps/cms/src/assets/fonts/Satoshi-Regular.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Regular.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Regular.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-Variable.eot b/apps/cms/src/assets/fonts/Satoshi-Variable.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Variable.eot rename to apps/cms/src/assets/fonts/Satoshi-Variable.eot diff --git a/hosting/src/assets/fonts/Satoshi-Variable.ttf b/apps/cms/src/assets/fonts/Satoshi-Variable.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Variable.ttf rename to apps/cms/src/assets/fonts/Satoshi-Variable.ttf diff --git a/hosting/src/assets/fonts/Satoshi-Variable.woff b/apps/cms/src/assets/fonts/Satoshi-Variable.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Variable.woff rename to apps/cms/src/assets/fonts/Satoshi-Variable.woff diff --git a/hosting/src/assets/fonts/Satoshi-Variable.woff2 b/apps/cms/src/assets/fonts/Satoshi-Variable.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-Variable.woff2 rename to apps/cms/src/assets/fonts/Satoshi-Variable.woff2 diff --git a/hosting/src/assets/fonts/Satoshi-VariableItalic.eot b/apps/cms/src/assets/fonts/Satoshi-VariableItalic.eot similarity index 100% rename from hosting/src/assets/fonts/Satoshi-VariableItalic.eot rename to apps/cms/src/assets/fonts/Satoshi-VariableItalic.eot diff --git a/hosting/src/assets/fonts/Satoshi-VariableItalic.ttf b/apps/cms/src/assets/fonts/Satoshi-VariableItalic.ttf similarity index 100% rename from hosting/src/assets/fonts/Satoshi-VariableItalic.ttf rename to apps/cms/src/assets/fonts/Satoshi-VariableItalic.ttf diff --git a/hosting/src/assets/fonts/Satoshi-VariableItalic.woff b/apps/cms/src/assets/fonts/Satoshi-VariableItalic.woff similarity index 100% rename from hosting/src/assets/fonts/Satoshi-VariableItalic.woff rename to apps/cms/src/assets/fonts/Satoshi-VariableItalic.woff diff --git a/hosting/src/assets/fonts/Satoshi-VariableItalic.woff2 b/apps/cms/src/assets/fonts/Satoshi-VariableItalic.woff2 similarity index 100% rename from hosting/src/assets/fonts/Satoshi-VariableItalic.woff2 rename to apps/cms/src/assets/fonts/Satoshi-VariableItalic.woff2 diff --git a/hosting/src/assets/scss/example.scss b/apps/cms/src/assets/scss/example.scss similarity index 100% rename from hosting/src/assets/scss/example.scss rename to apps/cms/src/assets/scss/example.scss diff --git a/hosting/src/assets/scss/layout-authentication.scss b/apps/cms/src/assets/scss/layout-authentication.scss similarity index 100% rename from hosting/src/assets/scss/layout-authentication.scss rename to apps/cms/src/assets/scss/layout-authentication.scss diff --git a/hosting/src/assets/scss/layout-blank.scss b/apps/cms/src/assets/scss/layout-blank.scss similarity index 100% rename from hosting/src/assets/scss/layout-blank.scss rename to apps/cms/src/assets/scss/layout-blank.scss diff --git a/hosting/src/assets/scss/layout-default.scss b/apps/cms/src/assets/scss/layout-default.scss similarity index 100% rename from hosting/src/assets/scss/layout-default.scss rename to apps/cms/src/assets/scss/layout-default.scss diff --git a/hosting/src/assets/scss/layout-landing-page.scss b/apps/cms/src/assets/scss/layout-landing-page.scss similarity index 100% rename from hosting/src/assets/scss/layout-landing-page.scss rename to apps/cms/src/assets/scss/layout-landing-page.scss diff --git a/hosting/src/components/Auth/AuthRestricted.tsx b/apps/cms/src/components/Auth/AuthRestricted.tsx similarity index 87% rename from hosting/src/components/Auth/AuthRestricted.tsx rename to apps/cms/src/components/Auth/AuthRestricted.tsx index 12d85246..22d22615 100644 --- a/hosting/src/components/Auth/AuthRestricted.tsx +++ b/apps/cms/src/components/Auth/AuthRestricted.tsx @@ -1,5 +1,5 @@ "use client"; -import {useAuthentication} from "@/hooks/useAuthentication"; +import {useAuthentication} from "../../hooks/useAuthentication"; interface AuthRestrictedProps { children: React.ReactNode; diff --git a/hosting/src/components/Auth/PublicOnlyRestriction.tsx b/apps/cms/src/components/Auth/PublicOnlyRestriction.tsx similarity index 87% rename from hosting/src/components/Auth/PublicOnlyRestriction.tsx rename to apps/cms/src/components/Auth/PublicOnlyRestriction.tsx index edab64e4..793f6d14 100644 --- a/hosting/src/components/Auth/PublicOnlyRestriction.tsx +++ b/apps/cms/src/components/Auth/PublicOnlyRestriction.tsx @@ -1,5 +1,5 @@ "use client"; -import {useAuthentication} from "@/hooks/useAuthentication"; +import {useAuthentication} from "../../hooks/useAuthentication"; interface PublicOnlyRestrictionProps { children: React.ReactNode; diff --git a/hosting/src/components/DarkModeSwitcher.tsx b/apps/cms/src/components/DarkModeSwitcher.tsx similarity index 73% rename from hosting/src/components/DarkModeSwitcher.tsx rename to apps/cms/src/components/DarkModeSwitcher.tsx index 5e139f25..cb34e2c8 100644 --- a/hosting/src/components/DarkModeSwitcher.tsx +++ b/apps/cms/src/components/DarkModeSwitcher.tsx @@ -1,8 +1,8 @@ -import {Switcher} from "@/components/Form/Switcher"; -import {useAuthentication} from "@/hooks/useAuthentication"; -import useColorMode from "@/hooks/useColorMode"; -import {useTanamUser} from "@/hooks/useTanamUser"; +import {Switcher} from "@tanam/ui-components"; import {useEffect} from "react"; +import {useAuthentication} from "../hooks/useAuthentication"; +import useColorMode from "../hooks/useColorMode"; +import {useTanamUser} from "../hooks/useTanamUser"; const DarkModeSwitcher = () => { const [colorMode, setColorMode] = useColorMode(); @@ -13,7 +13,7 @@ const DarkModeSwitcher = () => { if (typeof setColorMode === "function" && !!tanamUser?.colorMode) { setColorMode(tanamUser.colorMode); } - }, [tanamUser]); + }, [setColorMode, tanamUser]); return (
diff --git a/hosting/src/components/Layouts/CmsLayout.tsx b/apps/cms/src/components/Layouts/CmsLayout.tsx similarity index 82% rename from hosting/src/components/Layouts/CmsLayout.tsx rename to apps/cms/src/components/Layouts/CmsLayout.tsx index 09ce62ef..daeeb1f3 100644 --- a/hosting/src/components/Layouts/CmsLayout.tsx +++ b/apps/cms/src/components/Layouts/CmsLayout.tsx @@ -1,13 +1,13 @@ "use client"; -import "@/assets/css/satoshi.css"; -import "@/assets/css/style.css"; -import "@/assets/scss/layout-default.scss"; -import Header from "@/components/Header"; -import Sidebar from "@/components/Sidebar"; -import {useAuthentication} from "@/hooks/useAuthentication"; -import useColorMode from "@/hooks/useColorMode"; +import "@tanam/cms/assets/css/satoshi.css"; +import "@tanam/cms/assets/css/style.css"; +import "@tanam/cms/assets/scss/layout-default.scss"; import "flatpickr/dist/flatpickr.min.css"; import React, {useState} from "react"; +import {useAuthentication} from "../../hooks/useAuthentication"; +import useColorMode from "../../hooks/useColorMode"; +import {Header} from "../Header"; +import Sidebar from "../Sidebar/Sidebar"; export default function CmsLayout({children}: {children: React.ReactNode}) { useAuthentication(); diff --git a/hosting/src/components/Sidebar/Sidebar.tsx b/apps/cms/src/components/Sidebar/Sidebar.tsx similarity index 92% rename from hosting/src/components/Sidebar/Sidebar.tsx rename to apps/cms/src/components/Sidebar/Sidebar.tsx index dfff5578..a76ca20b 100644 --- a/hosting/src/components/Sidebar/Sidebar.tsx +++ b/apps/cms/src/components/Sidebar/Sidebar.tsx @@ -1,13 +1,13 @@ "use client"; -import {SidebarExpandableMenu, SidebarExpandableMenuSubItem} from "@/components/Sidebar/SidebarExpandableMenu"; -import {SidebarMenuGroup} from "@/components/Sidebar/SidebarMenuGroup"; -import {SidebarMenuItem} from "@/components/Sidebar/SidebarMenuItem"; -import {useAuthentication} from "@/hooks/useAuthentication"; -import {useTanamDocumentTypes} from "@/hooks/useTanamDocumentTypes"; import Image from "next/image"; import Link from "next/link"; import {usePathname} from "next/navigation"; import {useEffect, useState} from "react"; +import {useAuthentication} from "../../hooks/useAuthentication"; +import {useTanamDocumentTypes} from "../../hooks/useTanamDocumentTypes"; +import {SidebarExpandableMenu, SidebarExpandableMenuSubItem} from "./SidebarExpandableMenu"; +import {SidebarMenuGroup} from "./SidebarMenuGroup"; +import {SidebarMenuItem} from "./SidebarMenuItem"; interface SidebarProps { sidebarOpen: boolean; diff --git a/hosting/src/components/Sidebar/SidebarExpandableMenu.tsx b/apps/cms/src/components/Sidebar/SidebarExpandableMenu.tsx similarity index 100% rename from hosting/src/components/Sidebar/SidebarExpandableMenu.tsx rename to apps/cms/src/components/Sidebar/SidebarExpandableMenu.tsx diff --git a/hosting/src/components/Sidebar/SidebarLinkGroup.tsx b/apps/cms/src/components/Sidebar/SidebarLinkGroup.tsx similarity index 100% rename from hosting/src/components/Sidebar/SidebarLinkGroup.tsx rename to apps/cms/src/components/Sidebar/SidebarLinkGroup.tsx diff --git a/hosting/src/components/Sidebar/SidebarMenuGroup.tsx b/apps/cms/src/components/Sidebar/SidebarMenuGroup.tsx similarity index 100% rename from hosting/src/components/Sidebar/SidebarMenuGroup.tsx rename to apps/cms/src/components/Sidebar/SidebarMenuGroup.tsx diff --git a/hosting/src/components/Sidebar/SidebarMenuItem.tsx b/apps/cms/src/components/Sidebar/SidebarMenuItem.tsx similarity index 100% rename from hosting/src/components/Sidebar/SidebarMenuItem.tsx rename to apps/cms/src/components/Sidebar/SidebarMenuItem.tsx diff --git a/hosting/src/components/Sidebar/index.ts b/apps/cms/src/components/Sidebar/index.ts similarity index 100% rename from hosting/src/components/Sidebar/index.ts rename to apps/cms/src/components/Sidebar/index.ts diff --git a/hosting/src/components/SignoutUser.tsx b/apps/cms/src/components/SignoutUser.tsx similarity index 81% rename from hosting/src/components/SignoutUser.tsx rename to apps/cms/src/components/SignoutUser.tsx index 56ad77bd..3a4e845f 100644 --- a/hosting/src/components/SignoutUser.tsx +++ b/apps/cms/src/components/SignoutUser.tsx @@ -1,6 +1,6 @@ "use client"; import {useEffect} from "react"; -import {useAuthentication} from "@/hooks/useAuthentication"; +import {useAuthentication} from "../hooks/useAuthentication"; const SignoutUser: React.FC = () => { const {signout} = useAuthentication(); diff --git a/hosting/src/components/TogglePublishDocument.tsx b/apps/cms/src/components/TogglePublishDocument.tsx similarity index 94% rename from hosting/src/components/TogglePublishDocument.tsx rename to apps/cms/src/components/TogglePublishDocument.tsx index ff0c478e..3681b344 100644 --- a/hosting/src/components/TogglePublishDocument.tsx +++ b/apps/cms/src/components/TogglePublishDocument.tsx @@ -1,11 +1,9 @@ -import {Button} from "@/components/Button"; -import {DatePicker} from "@/components/Form"; -import {Modal} from "@/components/Modal"; -import {useTanamDocument} from "@/hooks/useTanamDocuments"; -import {formatDate} from "@/utils/date"; +import {TanamPublishStatus} from "@tanam/domain-frontend"; +import {Button, DatePicker, Modal} from "@tanam/ui-components"; import {useParams} from "next/navigation"; import {useMemo, useState} from "react"; -import {TanamPublishStatus} from "tanam-shared/definitions/TanamPublishStatus"; +import {useTanamDocument} from "../hooks/useTanamDocuments"; +import {formatDate} from "../utils/date"; export function TogglePublishDocument() { const {documentId} = useParams<{documentId: string}>() ?? {}; diff --git a/hosting/src/components/UserAvatar.tsx b/apps/cms/src/components/UserAvatar.tsx similarity index 93% rename from hosting/src/components/UserAvatar.tsx rename to apps/cms/src/components/UserAvatar.tsx index bd3de053..d1256b2b 100644 --- a/hosting/src/components/UserAvatar.tsx +++ b/apps/cms/src/components/UserAvatar.tsx @@ -1,6 +1,6 @@ -import {useTanamUserImage} from "@/hooks/useTanamUser"; import Image from "next/image"; import {Suspense} from "react"; +import {useTanamUserImage} from "../hooks/useTanamUser"; interface UserImageProps { uid?: string; diff --git a/hosting/src/hooks/useAuthentication.tsx b/apps/cms/src/hooks/useAuthentication.tsx similarity index 93% rename from hosting/src/hooks/useAuthentication.tsx rename to apps/cms/src/hooks/useAuthentication.tsx index 3df6881b..754dcd49 100644 --- a/hosting/src/hooks/useAuthentication.tsx +++ b/apps/cms/src/hooks/useAuthentication.tsx @@ -1,9 +1,9 @@ "use client"; -import {firebaseAuth} from "@/plugins/firebase"; +import {TanamRole} from "@tanam/domain-frontend"; import {User} from "firebase/auth"; import {redirect, usePathname} from "next/navigation"; import {useEffect, useState} from "react"; -import {TanamRole} from "tanam-shared/models/TanamUser"; +import {firebaseAuth} from "../plugins/firebase"; export function useAuthentication() { const pathname = usePathname(); diff --git a/hosting/src/hooks/useColorMode.tsx b/apps/cms/src/hooks/useColorMode.tsx similarity index 88% rename from hosting/src/hooks/useColorMode.tsx rename to apps/cms/src/hooks/useColorMode.tsx index 385250e8..803a1b34 100644 --- a/hosting/src/hooks/useColorMode.tsx +++ b/apps/cms/src/hooks/useColorMode.tsx @@ -1,5 +1,5 @@ import {useEffect} from "react"; -import useLocalStorage from "@/hooks/useLocalStorage"; +import useLocalStorage from "./useLocalStorage"; const useColorMode = () => { const [colorMode, setColorMode] = useLocalStorage("color-theme", "light"); diff --git a/hosting/src/hooks/useCreateDocumentType.tsx b/apps/cms/src/hooks/useCreateDocumentType.tsx similarity index 91% rename from hosting/src/hooks/useCreateDocumentType.tsx rename to apps/cms/src/hooks/useCreateDocumentType.tsx index fd7e9a69..48e5320f 100644 --- a/hosting/src/hooks/useCreateDocumentType.tsx +++ b/apps/cms/src/hooks/useCreateDocumentType.tsx @@ -1,9 +1,7 @@ -import {TanamDocumentTypeClient} from "@/models/TanamDocumentTypeClient"; -import {UserNotification} from "@/models/UserNotification"; -import {firestore} from "@/plugins/firebase"; +import {TanamDocumentField, TanamDocumentTypeClient, UserNotification} from "@tanam/domain-frontend"; import {collection, doc, serverTimestamp, writeBatch} from "firebase/firestore"; import {useState} from "react"; -import {TanamDocumentField} from "tanam-shared/models/TanamDocumentField"; +import {firestore} from "../plugins/firebase"; interface CreateDocumentTypeHook { createType: (type: TanamDocumentTypeClient, fields: TanamDocumentField[]) => Promise; diff --git a/hosting/src/hooks/useFirebaseStorage.tsx b/apps/cms/src/hooks/useFirebaseStorage.tsx similarity index 95% rename from hosting/src/hooks/useFirebaseStorage.tsx rename to apps/cms/src/hooks/useFirebaseStorage.tsx index d2201cad..da1c9dfe 100644 --- a/hosting/src/hooks/useFirebaseStorage.tsx +++ b/apps/cms/src/hooks/useFirebaseStorage.tsx @@ -1,8 +1,8 @@ -import {UserNotification} from "@/models/UserNotification"; -import {storage} from "@/plugins/firebase"; -import {base64ToBlob} from "@/utils/fileUpload"; +import {UserNotification} from "@tanam/domain-frontend"; import {getDownloadURL, ref, uploadBytes} from "firebase/storage"; import {useState} from "react"; +import {storage} from "../plugins/firebase"; +import {base64ToBlob} from "../utils/fileUpload"; interface FirebaseStorageHook { isLoading: boolean; diff --git a/hosting/src/hooks/useFirebaseUi.tsx b/apps/cms/src/hooks/useFirebaseUi.tsx similarity index 97% rename from hosting/src/hooks/useFirebaseUi.tsx rename to apps/cms/src/hooks/useFirebaseUi.tsx index 2c79d611..c44ed3ec 100644 --- a/hosting/src/hooks/useFirebaseUi.tsx +++ b/apps/cms/src/hooks/useFirebaseUi.tsx @@ -1,9 +1,9 @@ "use client"; -import {firebaseAuth} from "@/plugins/firebase"; import {AuthCredential, GoogleAuthProvider} from "firebase/auth"; import {auth as firebaseAuthUi} from "firebaseui"; import "firebaseui/dist/firebaseui.css"; import {useEffect, useState} from "react"; +import {firebaseAuth} from "../plugins/firebase"; const firebaseUi = firebaseAuthUi.AuthUI.getInstance() || new firebaseAuthUi.AuthUI(firebaseAuth); diff --git a/hosting/src/hooks/useGenkitArticle.tsx b/apps/cms/src/hooks/useGenkitArticle.tsx similarity index 88% rename from hosting/src/hooks/useGenkitArticle.tsx rename to apps/cms/src/hooks/useGenkitArticle.tsx index f96180eb..310ce562 100644 --- a/hosting/src/hooks/useGenkitArticle.tsx +++ b/apps/cms/src/hooks/useGenkitArticle.tsx @@ -1,12 +1,9 @@ -import {TanamDocumentClient} from "@/models/TanamDocumentClient"; -import {UserNotification} from "@/models/UserNotification"; -import {firestore, storage} from "@/plugins/firebase"; -import {generateArticle} from "@/plugins/genkit/article"; +import {ArticleSchema, TanamDocumentClient, TanamPublishStatus, UserNotification} from "@tanam/domain-frontend"; import {collection, doc, getDocs, limit, orderBy, query, setDoc, where} from "firebase/firestore"; import {getDownloadURL, ref, uploadBytes} from "firebase/storage"; import {useEffect, useState} from "react"; -import {TanamPublishStatus} from "tanam-shared/definitions/TanamPublishStatus"; -import {ArticleSchema} from "tanam-shared/schemas/article"; +import {firestore, storage} from "../plugins/firebase"; +import {generateArticle} from "../plugins/genkit/article"; // NOTE: (Dennis) For some reason, the enum values are warning for not being used export enum ProcessingState { diff --git a/hosting/src/hooks/useLocalStorage.tsx b/apps/cms/src/hooks/useLocalStorage.tsx similarity index 100% rename from hosting/src/hooks/useLocalStorage.tsx rename to apps/cms/src/hooks/useLocalStorage.tsx diff --git a/hosting/src/hooks/useTanamDocumentFields.tsx b/apps/cms/src/hooks/useTanamDocumentFields.tsx similarity index 89% rename from hosting/src/hooks/useTanamDocumentFields.tsx rename to apps/cms/src/hooks/useTanamDocumentFields.tsx index 607eb905..f3c0e09d 100644 --- a/hosting/src/hooks/useTanamDocumentFields.tsx +++ b/apps/cms/src/hooks/useTanamDocumentFields.tsx @@ -1,9 +1,8 @@ -import {UserNotification} from "@/models/UserNotification"; -import {firestore} from "@/plugins/firebase"; +import {ITanamDocumentField, TanamDocumentField, UserNotification} from "@tanam/domain-frontend"; import {collection, onSnapshot} from "firebase/firestore"; import {useParams} from "next/navigation"; import {useEffect, useState} from "react"; -import {ITanamDocumentField, TanamDocumentField} from "tanam-shared/models/TanamDocumentField"; +import {firestore} from "../plugins/firebase"; interface TanamDocumentFieldHook { data: TanamDocumentField[]; diff --git a/hosting/src/hooks/useTanamDocumentTypes.tsx b/apps/cms/src/hooks/useTanamDocumentTypes.tsx similarity index 93% rename from hosting/src/hooks/useTanamDocumentTypes.tsx rename to apps/cms/src/hooks/useTanamDocumentTypes.tsx index c5a61d98..bd7847ca 100644 --- a/hosting/src/hooks/useTanamDocumentTypes.tsx +++ b/apps/cms/src/hooks/useTanamDocumentTypes.tsx @@ -1,9 +1,8 @@ -import {TanamDocumentTypeClient} from "@/models/TanamDocumentTypeClient"; -import {firestore} from "@/plugins/firebase"; +import {TanamDocumentTypeClient, UserNotification} from "@tanam/domain-frontend"; import {collection, doc, onSnapshot} from "firebase/firestore"; import {useParams} from "next/navigation"; import {useEffect, useState} from "react"; -import {UserNotification} from "@/models/UserNotification"; +import {firestore} from "../plugins/firebase"; interface TanamDocumentTypeHook { data: TanamDocumentTypeClient[]; diff --git a/hosting/src/hooks/useTanamDocuments.tsx b/apps/cms/src/hooks/useTanamDocuments.tsx similarity index 95% rename from hosting/src/hooks/useTanamDocuments.tsx rename to apps/cms/src/hooks/useTanamDocuments.tsx index a52bacfb..b534234e 100644 --- a/hosting/src/hooks/useTanamDocuments.tsx +++ b/apps/cms/src/hooks/useTanamDocuments.tsx @@ -1,7 +1,5 @@ "use client"; -import {TanamDocumentClient} from "@/models/TanamDocumentClient"; -import {UserNotification} from "@/models/UserNotification"; -import {firestore} from "@/plugins/firebase"; +import {TanamDocumentClient, TanamPublishStatus, UserNotification} from "@tanam/domain-frontend"; import { collection, doc, @@ -14,7 +12,7 @@ import { where, } from "firebase/firestore"; import {useEffect, useState} from "react"; -import {TanamPublishStatus} from "tanam-shared/definitions/TanamPublishStatus"; +import {firestore} from "../plugins/firebase"; interface UseTanamDocumentsResult { data: TanamDocumentClient[]; diff --git a/hosting/src/hooks/useTanamUser.tsx b/apps/cms/src/hooks/useTanamUser.tsx similarity index 94% rename from hosting/src/hooks/useTanamUser.tsx rename to apps/cms/src/hooks/useTanamUser.tsx index e2d64395..d71cdf7b 100644 --- a/hosting/src/hooks/useTanamUser.tsx +++ b/apps/cms/src/hooks/useTanamUser.tsx @@ -1,9 +1,8 @@ -import {TanamUserClient} from "@/models/TanamUserClient"; -import {UserNotification} from "@/models/UserNotification"; -import {firestore, storage} from "@/plugins/firebase"; +import {TanamUserClient, UserNotification} from "@tanam/domain-frontend"; import {doc, onSnapshot, updateDoc} from "firebase/firestore"; import {getDownloadURL, ref} from "firebase/storage"; import {useEffect, useState} from "react"; +import {firestore, storage} from "../plugins/firebase"; /** * Hook to get a Tanam user document from Firestore diff --git a/hosting/src/plugins/fileUpload.ts b/apps/cms/src/plugins/fileUpload.ts similarity index 100% rename from hosting/src/plugins/fileUpload.ts rename to apps/cms/src/plugins/fileUpload.ts diff --git a/hosting/src/plugins/firebase.ts b/apps/cms/src/plugins/firebase.ts similarity index 100% rename from hosting/src/plugins/firebase.ts rename to apps/cms/src/plugins/firebase.ts diff --git a/hosting/src/plugins/genkit/article.ts b/apps/cms/src/plugins/genkit/article.ts similarity index 90% rename from hosting/src/plugins/genkit/article.ts rename to apps/cms/src/plugins/genkit/article.ts index 6d46156b..6630e970 100644 --- a/hosting/src/plugins/genkit/article.ts +++ b/apps/cms/src/plugins/genkit/article.ts @@ -4,7 +4,7 @@ import {configureGenkit} from "@genkit-ai/core"; import {firebase} from "@genkit-ai/firebase"; import {defineFlow, runFlow} from "@genkit-ai/flow"; import googleAI, {gemini15Pro} from "@genkit-ai/googleai"; -import {ArticleSchema} from "tanam-shared/schemas/article"; +import {ArticleSchema} from "@tanam/domain-frontend"; import {z} from "zod"; import {zodToJsonSchema} from "zod-to-json-schema"; @@ -44,14 +44,14 @@ const articlePrompt = definePrompt( You are an AI ghostwriter assisting the user in writing articles. # Strategy - Adapt to the user's writing style if provided with example articles. Mirror their + Adapt to the user's writing style if provided with example articles. Mirror their tone, word choice, paragraph structure, and overall style. - When given a voice recording, expand on the content, adding detail, reducing - repetition, and structuring the information into a coherent, engaging article. Capture + When given a voice recording, expand on the content, adding detail, reducing + repetition, and structuring the information into a coherent, engaging article. Capture the user's speaking style but ensure the output is a polished article, not a transcript. - Your goal is to create articles that are engaging, informative, and easy to read, with + Your goal is to create articles that are engaging, informative, and easy to read, with a focus on storytelling, providing information, or entertainment. `, }, @@ -66,35 +66,35 @@ const articlePrompt = definePrompt( {media: {url: input.recordingUrl}}, { text: ` - The generated output must follow the schema: + The generated output must follow the schema: ${JSON.stringify((zodToJsonSchema(ArticleSchema) as {properties: Record}).properties)}`, }, { text: ` - # Articles to learn from + # Articles to learn from ${JSON.stringify(input.sampleArticles)}`, }, { text: ` # Rules Rules and guidelines for article generation. - + ## Title - Title should be max 60 characters. It can be shorter. - Choose a natural and engaging title for the article. - ## Article + ## Article - Make the article about ${input.length} minutes of read time. - Make a lead paragraph that introduces the topic with a hook to engage the reader. - Use HTML markup and only using:

,

,

,

,,,,