From c17f4776bcf4d9682a42fc7f17c69758b8ec6ffa Mon Sep 17 00:00:00 2001 From: Chirag Chhatrala <60499540+chiragchhatrala@users.noreply.github.com> Date: Mon, 19 May 2025 18:38:15 +0530 Subject: [PATCH] Integration pages from Notion (#753) * Integration pages from Notion * fix integration page * Refactor environment variables and update routing in integration pages - Removed unused environment variables related to MUX from `.env.docker` and `.env.example` to streamline configuration. - Updated routing links in `OpenFormFooter.vue` to correct navigation paths for "Integrations", "Report Abuse", and "Privacy Policy", enhancing user experience. - Added middleware to `definePageMeta` in `index.vue` and `[slug].vue` for integration pages to enforce self-hosted logic. These changes aim to improve code clarity and ensure proper routing functionality across the application. --------- Co-authored-by: Julien Nahum --- api/.env.docker | 11 - api/.env.example | 3 - client/components/global/NotionPage.vue | 67 ++++- client/components/pages/OpenFormFooter.vue | 19 +- .../components/pages/notion/CustomBlock.vue | 68 +++++ .../components/pages/notion/useNotionBlock.js | 107 ++++++++ client/pages/integrations/[slug].vue | 95 +++++++ client/pages/integrations/index.vue | 239 ++++++++++++++++++ client/pages/privacy-policy.vue | 27 +- client/pages/terms-conditions.vue | 27 +- client/stores/notion_cms.js | 127 ++++++++++ client/stores/notion_pages.js | 26 -- 12 files changed, 728 insertions(+), 88 deletions(-) create mode 100644 client/components/pages/notion/CustomBlock.vue create mode 100644 client/components/pages/notion/useNotionBlock.js create mode 100644 client/pages/integrations/[slug].vue create mode 100644 client/pages/integrations/index.vue create mode 100644 client/stores/notion_cms.js delete mode 100644 client/stores/notion_pages.js diff --git a/api/.env.docker b/api/.env.docker index 9c4e66d5..db728ef6 100644 --- a/api/.env.docker +++ b/api/.env.docker @@ -34,18 +34,7 @@ AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= -PUSHER_APP_ID= -PUSHER_APP_KEY= -PUSHER_APP_SECRET= -PUSHER_APP_CLUSTER=mt1 - -MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" -MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" - JWT_TTL=1440 JWT_SECRET= -MUX_WORKSPACE_ID= -MUX_API_TOKEN= - OPEN_AI_API_KEY= \ No newline at end of file diff --git a/api/.env.example b/api/.env.example index 41365481..61448dee 100644 --- a/api/.env.example +++ b/api/.env.example @@ -76,9 +76,6 @@ H_CAPTCHA_SECRET_KEY= RE_CAPTCHA_SITE_KEY= RE_CAPTCHA_SECRET_KEY= -MUX_WORKSPACE_ID= -MUX_API_TOKEN= - ADMIN_EMAILS= TEMPLATE_EDITOR_EMAILS= diff --git a/client/components/global/NotionPage.vue b/client/components/global/NotionPage.vue index 5263fc9f..b2ebf8af 100644 --- a/client/components/global/NotionPage.vue +++ b/client/components/global/NotionPage.vue @@ -1,7 +1,18 @@ diff --git a/client/pages/terms-conditions.vue b/client/pages/terms-conditions.vue index acdbe201..e76a4683 100644 --- a/client/pages/terms-conditions.vue +++ b/client/pages/terms-conditions.vue @@ -6,7 +6,7 @@ Terms & Conditions @@ -16,26 +16,19 @@ diff --git a/client/stores/notion_cms.js b/client/stores/notion_cms.js new file mode 100644 index 00000000..6d0b9538 --- /dev/null +++ b/client/stores/notion_cms.js @@ -0,0 +1,127 @@ +import { defineStore } from 'pinia' +import { computed, ref } from 'vue' +import opnformConfig from "~/opnform.config.js" + +function notionApiFetch (entityId, type = 'table') { + const apiUrl = opnformConfig.notion.worker + return useFetch(`${apiUrl}/${type}/${entityId}`) +} + +function fetchNotionDatabasePages (databaseId) { + return notionApiFetch(databaseId) +} + +function fetchNotionPageContent (pageId) { + return notionApiFetch(pageId, 'page') +} + +export const useNotionCmsStore = defineStore('notion_cms', () => { + + // State + const databases = ref({}) + const pages = ref({}) + const pageContents = ref({}) + const slugToIdMap = ref({}) + + const loading = ref(false) + + // Actions + const loadDatabase = (databaseId) => { + return new Promise((resolve, reject) => { + if (databases.value[databaseId]) return resolve() + + loading.value = true + return fetchNotionDatabasePages(databaseId).then((response) => { + databases.value[databaseId] = response.data.value.map(page => formatId(page.id)) + response.data.value.forEach(page => { + pages.value[formatId(page.id)] = { + ...page, + id: formatId(page.id) + } + const slug = page.Slug ?? page.slug ?? null + if (slug) { + setSlugToIdMap(slug, page.id) + } + }) + loading.value = false + resolve() + }).catch((error) => { + loading.value = false + console.error(error) + reject(error) + }) + }) + } + const loadPage = async (pageId) => { + return new Promise((resolve, reject) => { + if (pageContents.value[pageId]) return resolve('in already here') + loading.value = true + return fetchNotionPageContent(pageId).then((response) => { + pageContents.value[formatId(pageId)] = response.data.value + loading.value = false + return resolve('in finishg') + }).catch((error) => { + console.error(error) + loading.value = false + return reject(error) + }) + }) + } + + const loadPageBySlug = (slug) => { + if (!slugToIdMap.value[slug.toLowerCase()]) return + loadPage(slugToIdMap.value[slug.toLowerCase()]) + } + + const formatId = (id) => id.replaceAll('-', '') + + const getPage = (pageId) => { + return { + ...pages.value[pageId], + blocks: getPageBody(pageId) + } + } + + const getPageBody = (pageId) => { + return pageContents.value[pageId] + } + + const setSlugToIdMap = (slug, pageId) => { + if (!slug) return + slugToIdMap.value[slug.toLowerCase()] = formatId(pageId) + } + + const getPageBySlug = (slug) => { + if (!slug) return + const pageId = slugToIdMap.value[slug.toLowerCase()] + return getPage(pageId) + } + +// Getters + const databasePages = (databaseId) => computed(() => databases.value[databaseId]?.map(id => pages.value[id]) || []) + const pageContent = (pageId) => computed(() => pageContents.value[pageId]) + const pageBySlug = (slug) => computed(() => getPageBySlug(slug)) + + return { + // state + loading, + databases, + pages, + pageContents, + slugToIdMap, + + // actions + loadDatabase, + loadPage, + loadPageBySlug, + getPage, + getPageBody, + setSlugToIdMap, + getPageBySlug, + + // getters + databasePages, + pageContent, + pageBySlug + } +}) diff --git a/client/stores/notion_pages.js b/client/stores/notion_pages.js deleted file mode 100644 index 608f78c9..00000000 --- a/client/stores/notion_pages.js +++ /dev/null @@ -1,26 +0,0 @@ -import { defineStore } from "pinia" -import { useContentStore } from "~/composables/stores/useContentStore.js" -import opnformConfig from "~/opnform.config.js" -export const useNotionPagesStore = defineStore("notion_pages", () => { - const contentStore = useContentStore() - - const load = (pageId) => { - contentStore.startLoading() - - const apiUrl = opnformConfig.notion.worker - return useFetch(`${apiUrl}/page/${pageId}`) - .then(({ data }) => { - const val = data.value - val["id"] = pageId - contentStore.save(val) - }) - .finally(() => { - contentStore.stopLoading() - }) - } - - return { - ...contentStore, - load, - } -})