From 29550317f7f913f5cc807a2b27a79aef30e2cc35 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 4 Apr 2024 14:46:41 +0530 Subject: [PATCH 1/4] Enable the jsx-runtime plugin for vite's ESLint This prevents it complaining about a missing React import. Enabling this is recommended by the vite starter itself: > Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list --- web/packages/build-config/eslintrc-vite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/packages/build-config/eslintrc-vite.js b/web/packages/build-config/eslintrc-vite.js index 131d8902dd..37032546bd 100644 --- a/web/packages/build-config/eslintrc-vite.js +++ b/web/packages/build-config/eslintrc-vite.js @@ -1,5 +1,5 @@ /* eslint-env node */ module.exports = { - extends: ["./eslintrc-react.js"], + extends: ["./eslintrc-react.js", "plugin:react/jsx-runtime"], ignorePatterns: [".eslintrc.cjs", "vite.config.ts", "dist"], }; From 384ec365e89b9e59cf0198686722e9730bc4f09c Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 4 Apr 2024 15:15:50 +0530 Subject: [PATCH 2/4] Add starter staff app --- web/apps/payments/README.md | 2 + web/apps/staff/.eslintrc.cjs | 3 ++ web/apps/staff/README.md | 3 ++ web/apps/staff/index.html | 12 ++++++ web/apps/staff/package.json | 22 +++++++++++ web/apps/staff/src/App.tsx | 11 ++++++ web/apps/staff/src/components/Container.tsx | 5 +++ web/apps/staff/src/main.tsx | 13 +++++++ .../staff/src/services/support-service.ts | 17 +++++++++ web/apps/staff/src/styles/globals.css | 38 +++++++++++++++++++ web/apps/staff/src/utils/strings.ts | 13 +++++++ web/apps/staff/src/vite-env.d.ts | 18 +++++++++ web/apps/staff/tsconfig.json | 5 +++ web/apps/staff/tsconfig.node.json | 4 ++ web/apps/staff/vite.config.ts | 7 ++++ web/package.json | 5 ++- 16 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 web/apps/staff/.eslintrc.cjs create mode 100644 web/apps/staff/README.md create mode 100644 web/apps/staff/index.html create mode 100644 web/apps/staff/package.json create mode 100644 web/apps/staff/src/App.tsx create mode 100644 web/apps/staff/src/components/Container.tsx create mode 100644 web/apps/staff/src/main.tsx create mode 100644 web/apps/staff/src/services/support-service.ts create mode 100644 web/apps/staff/src/styles/globals.css create mode 100644 web/apps/staff/src/utils/strings.ts create mode 100644 web/apps/staff/src/vite-env.d.ts create mode 100644 web/apps/staff/tsconfig.json create mode 100644 web/apps/staff/tsconfig.node.json create mode 100644 web/apps/staff/vite.config.ts diff --git a/web/apps/payments/README.md b/web/apps/payments/README.md index eeac0a397b..959bedabe8 100644 --- a/web/apps/payments/README.md +++ b/web/apps/payments/README.md @@ -1,3 +1,5 @@ +# Payments + Code that runs on `payments.ente.io`. It brokers between our services and Stripe's API for payments. diff --git a/web/apps/staff/.eslintrc.cjs b/web/apps/staff/.eslintrc.cjs new file mode 100644 index 0000000000..99b4b9226c --- /dev/null +++ b/web/apps/staff/.eslintrc.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ["@/build-config/eslintrc-vite"], +}; diff --git a/web/apps/staff/README.md b/web/apps/staff/README.md new file mode 100644 index 0000000000..90423e499c --- /dev/null +++ b/web/apps/staff/README.md @@ -0,0 +1,3 @@ +## Staff dashboard + +Web app for staff members to help with support etc. diff --git a/web/apps/staff/index.html b/web/apps/staff/index.html new file mode 100644 index 0000000000..5600e3a53f --- /dev/null +++ b/web/apps/staff/index.html @@ -0,0 +1,12 @@ + + + + + + Staff | ente.io + + +
+ + + diff --git a/web/apps/staff/package.json b/web/apps/staff/package.json new file mode 100644 index 0000000000..2c7c01998b --- /dev/null +++ b/web/apps/staff/package.json @@ -0,0 +1,22 @@ +{ + "name": "staff", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "tsc && vite build", + "dev": "vite", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@/build-config": "*", + "@types/react": "^18", + "@types/react-dom": "^18", + "@vitejs/plugin-react": "^4.2", + "vite": "^5.2" + } +} diff --git a/web/apps/staff/src/App.tsx b/web/apps/staff/src/App.tsx new file mode 100644 index 0000000000..f3f0a9f150 --- /dev/null +++ b/web/apps/staff/src/App.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import S from "./utils/strings"; + +export const App: React.FC = () => { + return ( +
+

{S.hello}

+ help.ente.io +
+ ); +}; diff --git a/web/apps/staff/src/components/Container.tsx b/web/apps/staff/src/components/Container.tsx new file mode 100644 index 0000000000..bf8c57b5dc --- /dev/null +++ b/web/apps/staff/src/components/Container.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export const Container: React.FC = ({ children }) => ( +
{children}
+); diff --git a/web/apps/staff/src/main.tsx b/web/apps/staff/src/main.tsx new file mode 100644 index 0000000000..4ed8c32054 --- /dev/null +++ b/web/apps/staff/src/main.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import { App } from "./App"; +import "./styles/globals.css"; + +const root = document.getElementById("root"); +if (!root) throw new Error("Could not load root element to render onto"); + +ReactDOM.createRoot(root).render( + + + , +); diff --git a/web/apps/staff/src/services/support-service.ts b/web/apps/staff/src/services/support-service.ts new file mode 100644 index 0000000000..4898e1ee56 --- /dev/null +++ b/web/apps/staff/src/services/support-service.ts @@ -0,0 +1,17 @@ +const apiOrigin = import.meta.env.VITE_ENTE_ENDPOINT ?? "https://api.ente.io"; + +/** Fetch details of the user associated with the given {@link authToken}. */ +export const getUserDetails = async (authToken: string) => { + const url = `${apiOrigin}/users/details/v2`; + const res = await fetch(url, { + headers: { + "X-Auth-Token": authToken, + }, + }); + if (!res.ok) throw new Error(`Failed to fetch ${url}: HTTP ${res.status}`); + const json: unknown = await res.json(); + if (json && typeof json === "object") { + return json; + } + throw new Error(`Unexpected response for ${url}: ${JSON.stringify(json)}`); +}; diff --git a/web/apps/staff/src/styles/globals.css b/web/apps/staff/src/styles/globals.css new file mode 100644 index 0000000000..158d0e10ce --- /dev/null +++ b/web/apps/staff/src/styles/globals.css @@ -0,0 +1,38 @@ +:root { + color-scheme: light dark; + color: #213547; + background-color: #ffffff; +} + +body { + font-family: system-ui, sans-serif; + + margin: 0; + display: flex; + justify-content: center; + text-align: center; + min-height: 100svh; +} + +a { + color: green; +} + +a:hover { + color: darkgreen; +} + +@media (prefers-color-scheme: dark) { + :root { + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + } + + a { + color: lightgreen; + } + + a:hover { + color: chartreuse; + } +} diff --git a/web/apps/staff/src/utils/strings.ts b/web/apps/staff/src/utils/strings.ts new file mode 100644 index 0000000000..39b22fcd76 --- /dev/null +++ b/web/apps/staff/src/utils/strings.ts @@ -0,0 +1,13 @@ +/** + * User facing strings in the app. + * + * By keeping them separate, we make our lives easier if/when we need to + * localize the corresponding pages. Right now, these are just the values in the + * default language, English. + */ +const S = { + hello: "Hello Ente!", + error_generic: "Oops, something went wrong.", +}; + +export default S; diff --git a/web/apps/staff/src/vite-env.d.ts b/web/apps/staff/src/vite-env.d.ts new file mode 100644 index 0000000000..b49bd06d07 --- /dev/null +++ b/web/apps/staff/src/vite-env.d.ts @@ -0,0 +1,18 @@ +/* Type shims provided by vite, e.g. for asset imports + https://vitejs.dev/guide/features.html#client-types */ + +/// + +/** Types for the vite injected environment variables */ +interface ImportMetaEnv { + /** + * Override the origin (scheme://host:port) of Ente's API to connect to. + * + * This is useful when testing or connecting to alternative installations. + */ + readonly VITE_ENTE_ENDPOINT: string | undefined; +} + +interface ImportMeta { + env: ImportMetaEnv; +} diff --git a/web/apps/staff/tsconfig.json b/web/apps/staff/tsconfig.json new file mode 100644 index 0000000000..291fed6caf --- /dev/null +++ b/web/apps/staff/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@/build-config/tsconfig-vite.json", + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/web/apps/staff/tsconfig.node.json b/web/apps/staff/tsconfig.node.json new file mode 100644 index 0000000000..a8d6e3fc8f --- /dev/null +++ b/web/apps/staff/tsconfig.node.json @@ -0,0 +1,4 @@ +{ + "extends": "@/build-config/tsconfig-vite.node.json", + "include": ["vite.config.ts"] +} diff --git a/web/apps/staff/vite.config.ts b/web/apps/staff/vite.config.ts new file mode 100644 index 0000000000..d89c4f4453 --- /dev/null +++ b/web/apps/staff/vite.config.ts @@ -0,0 +1,7 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}); diff --git a/web/package.json b/web/package.json index d27f9a6cbe..3b8697bd8c 100644 --- a/web/package.json +++ b/web/package.json @@ -13,6 +13,7 @@ "build:cast": "yarn workspace cast next build", "build:payments": "yarn workspace payments build", "build:photos": "yarn workspace photos next build", + "build:staff": "yarn workspace staff build", "deploy:accounts": "open 'https://github.com/ente-io/ente/compare/deploy/accounts...main?quick_pull=1&title=[web]+Deploy+accounts&body=Deploy+accounts.ente.io'", "deploy:auth": "open 'https://github.com/ente-io/ente/compare/deploy/auth...main?quick_pull=1&title=[web]+Deploy+auth&body=Deploy+auth.ente.io'", "deploy:cast": "open 'https://github.com/ente-io/ente/compare/deploy/cast...main?quick_pull=1&title=[web]+Deploy+cast&body=Deploy+cast.ente.io'", @@ -25,6 +26,7 @@ "dev:cast": "yarn workspace cast next dev -p 3001", "dev:payments": "yarn workspace payments dev", "dev:photos": "yarn workspace photos next dev", + "dev:staff": "yarn workspace staff dev", "lint": "yarn prettier --check . && yarn workspaces run eslint --report-unused-disable-directives", "lint-fix": "yarn prettier --write . && yarn workspaces run eslint --fix .", "preview": "yarn preview:photos", @@ -32,7 +34,8 @@ "preview:auth": "yarn build:auth && python3 -m http.server -d apps/auth/out 3000", "preview:cast": "yarn build:cast && python3 -m http.server -d apps/accounts/out 3001", "preview:payments": "yarn workspace payments preview", - "preview:photos": "yarn build:photos && python3 -m http.server -d apps/photos/out 3000" + "preview:photos": "yarn build:photos && python3 -m http.server -d apps/photos/out 3000", + "preview:staff": "yarn workspace staff preview" }, "resolutions": { "libsodium": "0.7.9" From 39228270c1b218ddc3ba1383b2bc309f2566ef31 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 4 Apr 2024 15:40:17 +0530 Subject: [PATCH 3/4] Deploy --- .github/workflows/web-deploy-accounts.yml | 2 +- .github/workflows/web-deploy-auth.yml | 2 +- .github/workflows/web-deploy-cast.yml | 2 +- .github/workflows/web-deploy-payments.yml | 2 +- .github/workflows/web-deploy-photos.yml | 2 +- .github/workflows/web-deploy-staff.yml | 48 +++++++++++++++++++++++ .github/workflows/web-nightly.yml | 2 +- .github/workflows/web-preview.yml | 2 +- web/apps/staff/README.md | 5 +++ web/docs/deploy.md | 35 +++++++++-------- 10 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/web-deploy-staff.yml diff --git a/.github/workflows/web-deploy-accounts.yml b/.github/workflows/web-deploy-accounts.yml index 8164aea441..61411cac6f 100644 --- a/.github/workflows/web-deploy-accounts.yml +++ b/.github/workflows/web-deploy-accounts.yml @@ -24,7 +24,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/.github/workflows/web-deploy-auth.yml b/.github/workflows/web-deploy-auth.yml index 63a56b95be..d195b62f8c 100644 --- a/.github/workflows/web-deploy-auth.yml +++ b/.github/workflows/web-deploy-auth.yml @@ -24,7 +24,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/.github/workflows/web-deploy-cast.yml b/.github/workflows/web-deploy-cast.yml index be4861c71f..c5bbca9542 100644 --- a/.github/workflows/web-deploy-cast.yml +++ b/.github/workflows/web-deploy-cast.yml @@ -24,7 +24,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/.github/workflows/web-deploy-payments.yml b/.github/workflows/web-deploy-payments.yml index 8f4aeae85e..367e1db186 100644 --- a/.github/workflows/web-deploy-payments.yml +++ b/.github/workflows/web-deploy-payments.yml @@ -24,7 +24,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/.github/workflows/web-deploy-photos.yml b/.github/workflows/web-deploy-photos.yml index 64a88421d3..cb3a9db86d 100644 --- a/.github/workflows/web-deploy-photos.yml +++ b/.github/workflows/web-deploy-photos.yml @@ -24,7 +24,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/.github/workflows/web-deploy-staff.yml b/.github/workflows/web-deploy-staff.yml new file mode 100644 index 0000000000..4d386344df --- /dev/null +++ b/.github/workflows/web-deploy-staff.yml @@ -0,0 +1,48 @@ +name: "Deploy (staff)" + +on: + # Run on every push to main that changes web/apps/staff/ + push: + branches: [main] + paths: + - "web/apps/staff/**" + - ".github/workflows/web-deploy-staff.yml" + # Also allow manually running the workflow + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: web + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup node and enable yarn caching + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "yarn" + cache-dependency-path: "web/yarn.lock" + + - name: Install dependencies + run: yarn install + + - name: Build staff + run: yarn build:staff + + - name: Publish staff + uses: cloudflare/pages-action@1 + with: + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + projectName: ente + branch: deploy/staff + directory: web/apps/staff/dist + wranglerVersion: "3" diff --git a/.github/workflows/web-nightly.yml b/.github/workflows/web-nightly.yml index 89d5ecaa5c..b5d8c411f1 100644 --- a/.github/workflows/web-nightly.yml +++ b/.github/workflows/web-nightly.yml @@ -34,7 +34,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/.github/workflows/web-preview.yml b/.github/workflows/web-preview.yml index 2ad73b7a1f..8f39c02474 100644 --- a/.github/workflows/web-preview.yml +++ b/.github/workflows/web-preview.yml @@ -34,7 +34,7 @@ jobs: with: node-version: 20 cache: "yarn" - cache-dependency-path: "docs/yarn.lock" + cache-dependency-path: "web/yarn.lock" - name: Install dependencies run: yarn install diff --git a/web/apps/staff/README.md b/web/apps/staff/README.md index 90423e499c..e54b674d3d 100644 --- a/web/apps/staff/README.md +++ b/web/apps/staff/README.md @@ -1,3 +1,8 @@ ## Staff dashboard Web app for staff members to help with support etc. + +### Deployment + +The app gets redeployed whenever a PR is merged into main. See +[docs/deploy.md](../../docs/deploy.md) for more details. diff --git a/web/docs/deploy.md b/web/docs/deploy.md index 6b51a0199d..0b6579eccf 100644 --- a/web/docs/deploy.md +++ b/web/docs/deploy.md @@ -29,21 +29,22 @@ and publish to [web.ente.io](https://web.ente.io). Here is a list of all the deployments, whether or not they are production deployments, and the action that triggers them: -| URL | Type | Deployment action | -| -------------------------------------------- | ---------- | ------------------------------------------- | -| [web.ente.io](https://web.ente.io) | Production | Push to `deploy/photos` | -| [photos.ente.io](https://photos.ente.io) | Production | Alias of [web.ente.io](https://web.ente.io) | -| [auth.ente.io](https://auth.ente.io) | Production | Push to `deploy/auth` | -| [accounts.ente.io](https://accounts.ente.io) | Production | Push to `deploy/accounts` | -| [cast.ente.io](https://cast.ente.io) | Production | Push to `deploy/cast` | -| [payments.ente.io](https://payments.ente.io) | Production | Push to `deploy/payments` | -| [help.ente.io](https://help.ente.io) | Production | Push to `main` + changes in `docs/` | -| [accounts.ente.sh](https://accounts.ente.sh) | Preview | Nightly deploy of `main` | -| [auth.ente.sh](https://auth.ente.sh) | Preview | Nightly deploy of `main` | -| [cast.ente.sh](https://cast.ente.sh) | Preview | Nightly deploy of `main` | -| [payments.ente.sh](https://payments.ente.sh) | Preview | Nightly deploy of `main` | -| [photos.ente.sh](https://photos.ente.sh) | Preview | Nightly deploy of `main` | -| [preview.ente.sh](https://preview.ente.sh) | Preview | Manually triggered | +| URL | Type | Deployment action | +| -------------------------------------------- | ---------- | ---------------------------------------------| +| [web.ente.io](https://web.ente.io) | Production | Push to `deploy/photos` | +| [photos.ente.io](https://photos.ente.io) | Production | Alias of [web.ente.io](https://web.ente.io) | +| [auth.ente.io](https://auth.ente.io) | Production | Push to `deploy/auth` | +| [accounts.ente.io](https://accounts.ente.io) | Production | Push to `deploy/accounts` | +| [cast.ente.io](https://cast.ente.io) | Production | Push to `deploy/cast` | +| [payments.ente.io](https://payments.ente.io) | Production | Push to `deploy/payments` | +| [help.ente.io](https://help.ente.io) | Production | Push to `main` + changes in `docs/` | +| [staff.ente.io](https://staff.ente.io) | Production | Push to `main` + changes in `web/apps/staff` | +| [accounts.ente.sh](https://accounts.ente.sh) | Preview | Nightly deploy of `main` | +| [auth.ente.sh](https://auth.ente.sh) | Preview | Nightly deploy of `main` | +| [cast.ente.sh](https://cast.ente.sh) | Preview | Nightly deploy of `main` | +| [payments.ente.sh](https://payments.ente.sh) | Preview | Nightly deploy of `main` | +| [photos.ente.sh](https://photos.ente.sh) | Preview | Nightly deploy of `main` | +| [preview.ente.sh](https://preview.ente.sh) | Preview | Manually triggered | ### Other subdomains @@ -54,8 +55,8 @@ Apart from this, there are also some other deployments: `albums.ente.io`, it redirects to the `/shared-albums` page (Enhancement: serve it as a separate app with a smaller bundle size). -- `family.ente.io` is currently in a separate repositories (Enhancement: bring - them in here). +- `family.ente.io` is currently in a separate repository (Enhancement: bring + it in here). ### Preview deployments From e53c923675817cf46b52e68edbd48bbe1feb6d89 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Thu, 4 Apr 2024 15:44:03 +0530 Subject: [PATCH 4/4] Lint fix + update URL --- web/docs/deploy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/docs/deploy.md b/web/docs/deploy.md index 0b6579eccf..6358cb87f2 100644 --- a/web/docs/deploy.md +++ b/web/docs/deploy.md @@ -30,7 +30,7 @@ Here is a list of all the deployments, whether or not they are production deployments, and the action that triggers them: | URL | Type | Deployment action | -| -------------------------------------------- | ---------- | ---------------------------------------------| +| -------------------------------------------- | ---------- | -------------------------------------------- | | [web.ente.io](https://web.ente.io) | Production | Push to `deploy/photos` | | [photos.ente.io](https://photos.ente.io) | Production | Alias of [web.ente.io](https://web.ente.io) | | [auth.ente.io](https://auth.ente.io) | Production | Push to `deploy/auth` | @@ -38,7 +38,7 @@ deployments, and the action that triggers them: | [cast.ente.io](https://cast.ente.io) | Production | Push to `deploy/cast` | | [payments.ente.io](https://payments.ente.io) | Production | Push to `deploy/payments` | | [help.ente.io](https://help.ente.io) | Production | Push to `main` + changes in `docs/` | -| [staff.ente.io](https://staff.ente.io) | Production | Push to `main` + changes in `web/apps/staff` | +| [staff.ente.sh](https://staff.ente.sh) | Production | Push to `main` + changes in `web/apps/staff` | | [accounts.ente.sh](https://accounts.ente.sh) | Preview | Nightly deploy of `main` | | [auth.ente.sh](https://auth.ente.sh) | Preview | Nightly deploy of `main` | | [cast.ente.sh](https://cast.ente.sh) | Preview | Nightly deploy of `main` |