From 8c88a360bb2479ebf3ddf3534230ac16819c4ddd Mon Sep 17 00:00:00 2001 From: Rajat Saxena Date: Sun, 15 Jun 2025 04:45:06 +0000 Subject: [PATCH 01/38] Added initial files for emil-editor from v0. Published alpha versions to test the package --- .changeset/README.md | 8 + .changeset/config.json | 11 + .github/workflows/publish-docker-images.yaml | 53 -- .github/workflows/publish-packages.yaml | 62 ++ apps/queue/src/index.ts | 24 +- apps/queue/src/middlewares/verify-jwt.ts | 23 + .../admin/mails/mail-editor-and-preview.tsx | 126 +-- apps/web/package.json | 1 + package.json | 2 +- packages/common-models/package.json | 1 + packages/components-library/package.json | 1 + packages/email-editor/.eslintrc.js | 24 + packages/email-editor/.gitignore | 3 + packages/email-editor/package.json | 72 ++ packages/email-editor/postcss.config.js | 6 + .../email-editor/src/blocks/image/block.tsx | 76 ++ .../email-editor/src/blocks/image/index.ts | 10 + .../email-editor/src/blocks/image/metadata.ts | 9 + .../src/blocks/image/settings.tsx | 281 +++++++ .../email-editor/src/blocks/image/types.ts | 15 + .../email-editor/src/blocks/link/block.tsx | 91 +++ .../email-editor/src/blocks/link/index.ts | 10 + .../email-editor/src/blocks/link/metadata.ts | 9 + .../email-editor/src/blocks/link/settings.tsx | 314 ++++++++ .../email-editor/src/blocks/link/types.ts | 22 + .../src/blocks/separator/block.tsx | 45 ++ .../src/blocks/separator/index.ts | 10 + .../src/blocks/separator/metadata.ts | 9 + .../src/blocks/separator/settings.tsx | 134 ++++ .../src/blocks/separator/types.ts | 8 + .../email-editor/src/blocks/text/block.tsx | 49 ++ .../email-editor/src/blocks/text/index.ts | 10 + .../email-editor/src/blocks/text/metadata.ts | 9 + .../email-editor/src/blocks/text/settings.tsx | 175 +++++ .../email-editor/src/blocks/text/types.ts | 10 + .../src/components/add-block-button.tsx | 71 ++ .../src/components/block-settings-panel.tsx | 180 +++++ .../src/components/block-type-selector.tsx | 75 ++ .../src/components/block-wrapper.tsx | 196 +++++ .../src/components/editor-block-renderer.tsx | 286 +++++++ .../src/components/email-editor-root.tsx | 16 + .../src/components/email-editor.tsx | 113 +++ .../src/components/email-settings.tsx | 236 ++++++ .../src/components/layout/editor-layout.tsx | 33 + .../settings/settings-color-picker.tsx | 101 +++ .../components/settings/settings-input.tsx | 100 +++ .../components/settings/settings-section.tsx | 26 + .../components/settings/settings-select.tsx | 115 +++ .../components/settings/settings-slider.tsx | 103 +++ .../components/settings/settings-switch.tsx | 74 ++ .../components/settings/settings-textarea.tsx | 101 +++ .../src/components/settings/size-slider.tsx | 96 +++ .../email-editor/src/components/ui/button.tsx | 58 ++ .../email-editor/src/components/ui/dialog.tsx | 146 ++++ .../email-editor/src/components/ui/input.tsx | 21 + .../email-editor/src/components/ui/label.tsx | 24 + .../src/components/ui/popover.tsx | 48 ++ .../email-editor/src/components/ui/select.tsx | 191 +++++ .../email-editor/src/components/ui/slider.tsx | 61 ++ .../email-editor/src/components/ui/switch.tsx | 29 + .../src/components/ui/textarea.tsx | 18 + .../src/components/ui/tooltip.tsx | 59 ++ .../src/context/email-editor-context.tsx | 370 +++++++++ packages/email-editor/src/index.ts | 1 + .../email-editor/src/lib/block-registry.ts | 20 + .../email-editor/src/lib/default-email.ts | 188 +++++ .../email-editor/src/lib/email-renderer.tsx | 115 +++ packages/email-editor/src/lib/utils.ts | 6 + .../email-editor/src/types/block-registry.ts | 19 + .../email-editor/src/types/block-settings.ts | 86 +++ .../src/types/common-block-settings.ts | 6 + .../email-editor/src/types/email-editor.ts | 95 +++ packages/email-editor/tailwind.config.ts | 76 ++ packages/email-editor/tsconfig.json | 19 + packages/email-editor/tsup.config.ts | 13 + packages/icons/package.json | 1 + packages/page-blocks/package.json | 1 + packages/page-primitives/package.json | 1 + packages/state-management/package.json | 1 + packages/text-editor/package.json | 1 + packages/utils/package.json | 1 + pnpm-lock.yaml | 731 ++++++++++++++++-- services/app/Dockerfile | 1 + 83 files changed, 5850 insertions(+), 192 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .github/workflows/publish-packages.yaml create mode 100644 apps/queue/src/middlewares/verify-jwt.ts create mode 100644 packages/email-editor/.eslintrc.js create mode 100644 packages/email-editor/.gitignore create mode 100644 packages/email-editor/package.json create mode 100644 packages/email-editor/postcss.config.js create mode 100644 packages/email-editor/src/blocks/image/block.tsx create mode 100644 packages/email-editor/src/blocks/image/index.ts create mode 100644 packages/email-editor/src/blocks/image/metadata.ts create mode 100644 packages/email-editor/src/blocks/image/settings.tsx create mode 100644 packages/email-editor/src/blocks/image/types.ts create mode 100644 packages/email-editor/src/blocks/link/block.tsx create mode 100644 packages/email-editor/src/blocks/link/index.ts create mode 100644 packages/email-editor/src/blocks/link/metadata.ts create mode 100644 packages/email-editor/src/blocks/link/settings.tsx create mode 100644 packages/email-editor/src/blocks/link/types.ts create mode 100644 packages/email-editor/src/blocks/separator/block.tsx create mode 100644 packages/email-editor/src/blocks/separator/index.ts create mode 100644 packages/email-editor/src/blocks/separator/metadata.ts create mode 100644 packages/email-editor/src/blocks/separator/settings.tsx create mode 100644 packages/email-editor/src/blocks/separator/types.ts create mode 100644 packages/email-editor/src/blocks/text/block.tsx create mode 100644 packages/email-editor/src/blocks/text/index.ts create mode 100644 packages/email-editor/src/blocks/text/metadata.ts create mode 100644 packages/email-editor/src/blocks/text/settings.tsx create mode 100644 packages/email-editor/src/blocks/text/types.ts create mode 100644 packages/email-editor/src/components/add-block-button.tsx create mode 100644 packages/email-editor/src/components/block-settings-panel.tsx create mode 100644 packages/email-editor/src/components/block-type-selector.tsx create mode 100644 packages/email-editor/src/components/block-wrapper.tsx create mode 100644 packages/email-editor/src/components/editor-block-renderer.tsx create mode 100644 packages/email-editor/src/components/email-editor-root.tsx create mode 100644 packages/email-editor/src/components/email-editor.tsx create mode 100644 packages/email-editor/src/components/email-settings.tsx create mode 100644 packages/email-editor/src/components/layout/editor-layout.tsx create mode 100644 packages/email-editor/src/components/settings/settings-color-picker.tsx create mode 100644 packages/email-editor/src/components/settings/settings-input.tsx create mode 100644 packages/email-editor/src/components/settings/settings-section.tsx create mode 100644 packages/email-editor/src/components/settings/settings-select.tsx create mode 100644 packages/email-editor/src/components/settings/settings-slider.tsx create mode 100644 packages/email-editor/src/components/settings/settings-switch.tsx create mode 100644 packages/email-editor/src/components/settings/settings-textarea.tsx create mode 100644 packages/email-editor/src/components/settings/size-slider.tsx create mode 100644 packages/email-editor/src/components/ui/button.tsx create mode 100644 packages/email-editor/src/components/ui/dialog.tsx create mode 100644 packages/email-editor/src/components/ui/input.tsx create mode 100644 packages/email-editor/src/components/ui/label.tsx create mode 100644 packages/email-editor/src/components/ui/popover.tsx create mode 100644 packages/email-editor/src/components/ui/select.tsx create mode 100644 packages/email-editor/src/components/ui/slider.tsx create mode 100644 packages/email-editor/src/components/ui/switch.tsx create mode 100644 packages/email-editor/src/components/ui/textarea.tsx create mode 100644 packages/email-editor/src/components/ui/tooltip.tsx create mode 100644 packages/email-editor/src/context/email-editor-context.tsx create mode 100644 packages/email-editor/src/index.ts create mode 100644 packages/email-editor/src/lib/block-registry.ts create mode 100644 packages/email-editor/src/lib/default-email.ts create mode 100644 packages/email-editor/src/lib/email-renderer.tsx create mode 100644 packages/email-editor/src/lib/utils.ts create mode 100644 packages/email-editor/src/types/block-registry.ts create mode 100644 packages/email-editor/src/types/block-settings.ts create mode 100644 packages/email-editor/src/types/common-block-settings.ts create mode 100644 packages/email-editor/src/types/email-editor.ts create mode 100644 packages/email-editor/tailwind.config.ts create mode 100644 packages/email-editor/tsconfig.json create mode 100644 packages/email-editor/tsup.config.ts diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 000000000..d88011f61 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/publish-docker-images.yaml b/.github/workflows/publish-docker-images.yaml index 126546c9f..e48572cf2 100644 --- a/.github/workflows/publish-docker-images.yaml +++ b/.github/workflows/publish-docker-images.yaml @@ -6,60 +6,7 @@ on: - '*' jobs: -# publish-packages: -# runs-on: ubuntu-latest -# steps: -# - name: checkout -# uses: actions/checkout@v1 - -# - name: Configure CI Git User -# run: | -# git config --global user.name 'Rajat Saxena' -# git config --global user.email 'hi@sub.rajatsaxena.dev' -# git remote set-url origin https://$GITHUB_ACTOR:$GITHUB_PAT@github.com/codelitdev/courselit -# env: -# GITHUB_PAT: ${{ secrets.PAT }} - -# - name: Checkout and pull branch -# run: | -# LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) -# git checkout $LATEST_TAG - -# - name: Setup pnpm -# uses: pnpm/action-setup@v2 -# with: -# version: 8 - -# - name: Install Packages -# run: pnpm install - -# - name: Authenticate with Registry -# run: | -# echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc -# pnpm whoami -# env: -# NPM_TOKEN: ${{ secrets.NPM }} - -# - name: Build packages -# run: | -# pnpm --filter @courselit/icons build -# pnpm --filter @courselit/common-models build -# pnpm --filter @courselit/utils build -# pnpm --filter @courselit/text-editor build -# pnpm --filter @courselit/state-management build -# pnpm --filter @courselit/components-library build -# pnpm --filter @courselit/common-widgets build - -# - name: Publish package -# run: | -# pnpm publish -# env: -# GH_TOKEN: ${{ secrets.PAT }} -# GITHUB_TOKEN: ${{ secrets.PAT }} -# NPM_TOKEN: ${{ secrets.NPM }} - publish-docker-images: - # needs: publish-packages runs-on: ubuntu-latest steps: - name: checkout diff --git a/.github/workflows/publish-packages.yaml b/.github/workflows/publish-packages.yaml new file mode 100644 index 000000000..5f039619d --- /dev/null +++ b/.github/workflows/publish-packages.yaml @@ -0,0 +1,62 @@ +name: Publish Npm packages + +on: + push: + branches: + - main + tags-ignore: + - '**' + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +env: + CI: true + +jobs: + publish-packages: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v1 + + - name: Configure CI Git User + run: | + git config --global user.name 'Rajat Saxena' + git config --global user.email 'hi@sub.rajatsaxena.dev' + git remote set-url origin https://$GITHUB_ACTOR:$GITHUB_PAT@github.com/codelitdev/courselit + env: + GITHUB_PAT: ${{ secrets.PAT }} + + - name: Checkout and pull branch + run: | + LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) + git checkout $LATEST_TAG + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Install Packages + run: pnpm install + + - name: Authenticate with Registry + run: | + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > .npmrc + pnpm whoami + env: + NPM_TOKEN: ${{ secrets.NPM }} + + - name: Create and publish versions + id: changesets + uses: changesets/action@v1 + with: + commit: "chore: update versions" + title: "chore: update versions" + publish: pnpm ci:publish + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + NPM_TOKEN: ${{ secrets.NPM }} + + - name: Echo changeset output + run: echo "${{ steps.changesets.outputs.hasChangesets }}" \ No newline at end of file diff --git a/apps/queue/src/index.ts b/apps/queue/src/index.ts index 738b6e6b6..437e98a3d 100644 --- a/apps/queue/src/index.ts +++ b/apps/queue/src/index.ts @@ -1,7 +1,6 @@ import express from "express"; import jobRoutes from "./job/routes"; import sseRoutes from "./sse/routes"; -import { jwtUtils } from "@courselit/utils"; // start workers import "./domain/worker"; @@ -9,32 +8,11 @@ import "./workers/notifications"; // start loops import { startEmailAutomation } from "./start-email-automation"; -import { logger } from "./logger"; +import { verifyJWTMiddleware } from "./middlewares/verify-jwt"; const app = express(); app.use(express.json()); -const verifyJWTMiddleware = (req, res, next) => { - try { - const token = req.headers.authorization?.split(" ")[1]; - if (!token) { - return res.status(401).json({ error: "No token provided" }); - } - - const secret = process.env.COURSELIT_JWT_SECRET; - const decoded: any = jwtUtils.verifyToken(token, secret); - if (!decoded) { - return res.status(401).json({ error: "Invalid token" }); - } - - req.user = decoded.user; - next(); - } catch (err) { - logger.error(err); - return res.status(500).json({ error: err.message }); - } -}; - app.use("/job", verifyJWTMiddleware, jobRoutes); app.use("/sse", sseRoutes); diff --git a/apps/queue/src/middlewares/verify-jwt.ts b/apps/queue/src/middlewares/verify-jwt.ts new file mode 100644 index 000000000..3bec18973 --- /dev/null +++ b/apps/queue/src/middlewares/verify-jwt.ts @@ -0,0 +1,23 @@ +import { jwtUtils } from "@courselit/utils"; +import { logger } from "../logger"; + +export const verifyJWTMiddleware = (req, res, next) => { + try { + const token = req.headers.authorization?.split(" ")[1]; + if (!token) { + return res.status(401).json({ error: "No token provided" }); + } + + const secret = process.env.COURSELIT_JWT_SECRET; + const decoded: any = jwtUtils.verifyToken(token, secret); + if (!decoded) { + return res.status(401).json({ error: "Invalid token" }); + } + + req.user = decoded.user; + next(); + } catch (err) { + logger.error(err); + return res.status(500).json({ error: err.message }); + } +}; diff --git a/apps/web/components/admin/mails/mail-editor-and-preview.tsx b/apps/web/components/admin/mails/mail-editor-and-preview.tsx index ad7308642..1564e894d 100644 --- a/apps/web/components/admin/mails/mail-editor-and-preview.tsx +++ b/apps/web/components/admin/mails/mail-editor-and-preview.tsx @@ -1,6 +1,7 @@ import { FormField } from "@courselit/components-library"; import { renderEmailContent } from "@courselit/utils"; import { ChangeEvent, useEffect, useState } from "react"; +import { EmailEditor } from "@courselit/email-editor"; export function MailEditorAndPreview({ content, @@ -37,72 +38,75 @@ export function MailEditorAndPreview({ }, [content]); return ( -
-
-

Variables

-
-

- You can use the following variables in your content. -

-

- These will be replaced with the actual data while - sending emails. -

-
-

- {"{{ subscriber.email }}"} -

-

- The email of the subscriber +

+
+
+

Variables

+
+

+ You can use the following variables in your content.

-
-
-

- {"{{ subscriber.name}}"} -

-

- The name of the subscriber -

-
-
-

- {"{{ address }}"} -

-

- Your mailing address -

-
-
-

- {"{{ unsubscribe_link}}"} -

-

- A link to unsubscribe from the marketing emails +

+ These will be replaced with the actual data while + sending emails.

+
+

+ {"{{ subscriber.email }}"} +

+

+ The email of the subscriber +

+
+
+

+ {"{{ subscriber.name}}"} +

+

+ The name of the subscriber +

+
+
+

+ {"{{ address }}"} +

+

+ Your mailing address +

+
+
+

+ {"{{ unsubscribe_link}}"} +

+

+ A link to unsubscribe from the marketing emails +

+
+
+ ) => + onChange(e.target.value) + } + /> +
+
+

Preview

+