From 4526698d0fab993315c096a52518fc47f6a02ceb Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Sun, 31 Mar 2024 16:58:26 +0200 Subject: [PATCH 01/20] move files, remove unused exports and update readme --- README.md | 3 +-- app/actions/patchDocument.ts | 4 ++-- components/File.tsx | 4 ++-- .../{audits/index.tsx => audits.tsx} | 6 +++--- tina/entityMapper.ts | 9 --------- .../patchable-entity/patchableEntityMapper.ts | 6 ++++++ .../variants/audit}/handle/patch.ts | 0 .../variants/audit}/handle/placeholders.ts | 0 .../variants/audit}/handle/tinaFields.ts | 0 .../variants/audit}/handle/values.ts | 2 +- .../variants/audit}/handle/viewTypes.ts | 0 .../variants/audit}/index.ts | 16 +++++++-------- types/index.ts | 6 ------ utils/constants/index.ts | 20 +++++++------------ utils/supabase.ts | 2 ++ 15 files changed, 32 insertions(+), 46 deletions(-) rename tina/collections/{audits/index.tsx => audits.tsx} (98%) delete mode 100644 tina/entityMapper.ts create mode 100644 tina/patchable-entity/patchableEntityMapper.ts rename tina/{collections/audits => patchable-entity/variants/audit}/handle/patch.ts (100%) rename tina/{collections/audits => patchable-entity/variants/audit}/handle/placeholders.ts (100%) rename tina/{collections/audits => patchable-entity/variants/audit}/handle/tinaFields.ts (100%) rename tina/{collections/audits => patchable-entity/variants/audit}/handle/values.ts (98%) rename tina/{collections/audits => patchable-entity/variants/audit}/handle/viewTypes.ts (100%) rename tina/{collections/audits/handle => patchable-entity/variants/audit}/index.ts (69%) diff --git a/README.md b/README.md index 15bdb22..0979944 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,7 @@ npm run dev Prepare the project for a deployment (with Vercel). Just add some environment variables: ``` -NEXT_PUBLIC_TINA_URL=http://localhost:4001/graphql (or in production the tinacms url) -NEXT_PUBLIC_TINA_TOKEN= +TINA_TOKEN= NEXT_PUBLIC_TINA_CLIENT_ID= NEXT_PUBLIC_SUPABASE_URL= diff --git a/app/actions/patchDocument.ts b/app/actions/patchDocument.ts index d896da0..a38f82b 100644 --- a/app/actions/patchDocument.ts +++ b/app/actions/patchDocument.ts @@ -1,16 +1,16 @@ 'use server'; +import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; import type { PatchParcel, Patches } from '@/types/index'; import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; -import entityMapper from 'tina/entityMapper'; import { IS_RUNNING_LOCALLY } from '../../utils/constants'; import { staticFilePath } from '../../utils/path'; import { supabaseUpsert } from '../../utils/supabase'; export default async (patchParcel: PatchParcel) => { const { entity, filename, placeholders, skeleton } = patchParcel; - const givenEntity = entityMapper(entity?.__typename!); + const givenEntity = patchableEntityMapper[entity?.__typename!]; const patches: Patches = givenEntity.patches(entity, placeholders); const file = readFileSync(staticFilePath(skeleton)); diff --git a/components/File.tsx b/components/File.tsx index 82ebb02..9b054d5 100644 --- a/components/File.tsx +++ b/components/File.tsx @@ -1,9 +1,9 @@ 'use client'; import patchDocument from '@/app/actions/patchDocument'; +import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; import type { Placeholders, Skeleton } from '@/types/index'; import { uniqueUuid } from 'docx'; import { useEffect, useState } from 'react'; -import entityMapper from 'tina/entityMapper'; import { useTina } from 'tinacms/dist/react'; import { FileQuery } from '../tina/__generated__/types'; import EditorPanel from './EditorPanel'; @@ -23,7 +23,7 @@ type FileProps = { export default ({ placeholders, result }: FileProps) => { const { data } = useTina(result); const [patchedDocument, setPatchedDocument] = useState(); - const givenEntity = entityMapper(data.file.entity?.__typename!); + const givenEntity = patchableEntityMapper[data.file.entity?.__typename!]; useEffect( () => { diff --git a/tina/collections/audits/index.tsx b/tina/collections/audits.tsx similarity index 98% rename from tina/collections/audits/index.tsx rename to tina/collections/audits.tsx index f8d843b..0dae36b 100644 --- a/tina/collections/audits/index.tsx +++ b/tina/collections/audits.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { Collection } from 'tinacms'; -import { DURATIONS, LOCATIONS, TIMES } from '../../../utils/constants/tina'; +import { DURATIONS, LOCATIONS, TIMES } from '../../utils/constants/tina'; import { readableDateFromDatetime, readableFileNameFromEntity, -} from '../../../utils/readables'; -import Picker from '../../picker/Picker'; +} from '../../utils/readables'; +import Picker from '../picker/Picker'; export default { name: 'audit', diff --git a/tina/entityMapper.ts b/tina/entityMapper.ts deleted file mode 100644 index 93e4644..0000000 --- a/tina/entityMapper.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { PatchableEntity } from '@/types/index'; -import { audit } from './collections/audits/handle'; - -const patchableEntities: Record = { - Audit: audit, -}; - -// TODO type with generated type -export default (entityType: 'Audit') => patchableEntities[entityType]; diff --git a/tina/patchable-entity/patchableEntityMapper.ts b/tina/patchable-entity/patchableEntityMapper.ts new file mode 100644 index 0000000..a6e7366 --- /dev/null +++ b/tina/patchable-entity/patchableEntityMapper.ts @@ -0,0 +1,6 @@ +import type { PatchableEntity } from '@/types/index'; +import audit from './variants/audit'; + +export default { + Audit: audit, +} as Record; diff --git a/tina/collections/audits/handle/patch.ts b/tina/patchable-entity/variants/audit/handle/patch.ts similarity index 100% rename from tina/collections/audits/handle/patch.ts rename to tina/patchable-entity/variants/audit/handle/patch.ts diff --git a/tina/collections/audits/handle/placeholders.ts b/tina/patchable-entity/variants/audit/handle/placeholders.ts similarity index 100% rename from tina/collections/audits/handle/placeholders.ts rename to tina/patchable-entity/variants/audit/handle/placeholders.ts diff --git a/tina/collections/audits/handle/tinaFields.ts b/tina/patchable-entity/variants/audit/handle/tinaFields.ts similarity index 100% rename from tina/collections/audits/handle/tinaFields.ts rename to tina/patchable-entity/variants/audit/handle/tinaFields.ts diff --git a/tina/collections/audits/handle/values.ts b/tina/patchable-entity/variants/audit/handle/values.ts similarity index 98% rename from tina/collections/audits/handle/values.ts rename to tina/patchable-entity/variants/audit/handle/values.ts index 9ce1387..9461831 100644 --- a/tina/collections/audits/handle/values.ts +++ b/tina/patchable-entity/variants/audit/handle/values.ts @@ -1,6 +1,6 @@ import type { Time } from '@/types/index'; import { FileQuery } from 'tina/__generated__/types'; -import { readableDateFromDatetime } from '../../../../utils/readables'; +import { readableDateFromDatetime } from '../../../../../utils/readables'; import type { AuditPlaceholder } from './placeholders'; export default ( diff --git a/tina/collections/audits/handle/viewTypes.ts b/tina/patchable-entity/variants/audit/handle/viewTypes.ts similarity index 100% rename from tina/collections/audits/handle/viewTypes.ts rename to tina/patchable-entity/variants/audit/handle/viewTypes.ts diff --git a/tina/collections/audits/handle/index.ts b/tina/patchable-entity/variants/audit/index.ts similarity index 69% rename from tina/collections/audits/handle/index.ts rename to tina/patchable-entity/variants/audit/index.ts index be51970..657f570 100644 --- a/tina/collections/audits/handle/index.ts +++ b/tina/patchable-entity/variants/audit/index.ts @@ -1,12 +1,12 @@ +import type { FileQuery } from '@/tina/__generated__/types'; import type { PatchableEntity, Patches } from '@/types/index'; -import type { FileQuery } from 'tina/__generated__/types'; -import { retrievePatchInstruction } from './patch'; -import type { AuditPlaceholder } from './placeholders'; -import tinaFields from './tinaFields'; -import values from './values'; -import viewTypes from './viewTypes'; +import { retrievePatchInstruction } from './handle/patch'; +import type { AuditPlaceholder } from './handle/placeholders'; +import tinaFields from './handle/tinaFields'; +import values from './handle/values'; +import viewTypes from './handle/viewTypes'; -export const audit: PatchableEntity = { +export default { placeholderTinaField: (data: FileQuery, placeholder: string) => tinaFields(placeholder, data), @@ -29,4 +29,4 @@ export const audit: PatchableEntity = { return patches; }, -}; +} as PatchableEntity; diff --git a/types/index.ts b/types/index.ts index 38ee941..3580c47 100644 --- a/types/index.ts +++ b/types/index.ts @@ -5,12 +5,6 @@ import type client from '../tina/__generated__/client'; export type Skeleton = `/uploads/skeletons/${string}.docx`; export type Placeholders = `{{field_${string}}}`[]; -/** Entity-bound placeholder to value relation */ -export type PlaceholderRecord = Record< - T, - any ->; - export type FileLinkInfo = { link: string; name: string; diff --git a/utils/constants/index.ts b/utils/constants/index.ts index 21e060f..938ebc6 100644 --- a/utils/constants/index.ts +++ b/utils/constants/index.ts @@ -7,16 +7,10 @@ export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; export const IS_RUNNING_LOCALLY = !!process && process.env.NODE_ENV === 'development'; -export const SUPABASE_CLIENT = process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_KEY ? createClient( - process.env.NEXT_PUBLIC_SUPABASE_URL, - process.env.NEXT_PUBLIC_SUPABASE_KEY -) : undefined; - -export const TINA_URL = - !!process && - process.env.NEXT_PUBLIC_TINA_URL && - process.env.NEXT_PUBLIC_TINA_URL.includes('localhost') - ? process.env.NEXT_PUBLIC_TINA_URL - : `${process.env.NEXT_PUBLIC_TINA_URL}${ - process.env.HEAD || process.env.VERCEL_GIT_COMMIT_REF || 'main' - }`; \ No newline at end of file +export const SUPABASE_CLIENT = + process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_KEY + ? createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_KEY + ) + : undefined; \ No newline at end of file diff --git a/utils/supabase.ts b/utils/supabase.ts index de13125..a6c2b01 100644 --- a/utils/supabase.ts +++ b/utils/supabase.ts @@ -1,5 +1,7 @@ import { SUPABASE_CLIENT } from './constants'; +// TODO do on server + export const supabaseDownload = async (filename: string) => { if (!SUPABASE_CLIENT) { return null From f12ab0b6f7aa744c45dfc190285b42aa8e4c1187 Mon Sep 17 00:00:00 2001 From: "tina-cloud-app[bot]" <58178390+tina-cloud-app[bot]@users.noreply.github.com> Date: Sun, 31 Mar 2024 15:01:34 +0000 Subject: [PATCH 02/20] TinaCMS content update --- "content/entities/companies/\303\226BB_PV.json" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/content/entities/companies/\303\226BB_PV.json" "b/content/entities/companies/\303\226BB_PV.json" index 0643cd9..863ef92 100644 --- "a/content/entities/companies/\303\226BB_PV.json" +++ "b/content/entities/companies/\303\226BB_PV.json" @@ -10,5 +10,5 @@ } ], "size": 95, - "name": "ÖBB Personenverkehr" + "name": "ÖBB Personenverkehr AG" } \ No newline at end of file From 0d0f5d7d4194416ebae5a307a670416414466cff Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Sun, 31 Mar 2024 23:38:15 +0200 Subject: [PATCH 03/20] oofff, too much stuff: backend patch, refactor --- app/actions/patchDocument.ts | 55 ----------------- app/api/patch/hook.ts | 23 +++++++ app/api/patch/route.ts | 21 +++++++ tina/utils/index.ts => app/api/tina/hook.ts | 0 app/files/[slug]/page.tsx | 4 +- components/EditorPanel.tsx | 2 +- components/File.tsx | 50 +++------------ env.ts | 10 +-- tina/collections/audits.tsx | 3 +- tina/picker/Picker.tsx | 3 +- utils/{constants/tina.ts => constants.ts} | 8 +++ utils/constants/index.ts | 16 ----- {app/actions => utils}/downloadDocument.ts | 6 +- utils/patchDocument.ts | 68 +++++++++++++++++++++ utils/supabase.ts | 53 ---------------- 15 files changed, 143 insertions(+), 179 deletions(-) delete mode 100644 app/actions/patchDocument.ts create mode 100644 app/api/patch/hook.ts create mode 100644 app/api/patch/route.ts rename tina/utils/index.ts => app/api/tina/hook.ts (100%) rename utils/{constants/tina.ts => constants.ts} (74%) delete mode 100644 utils/constants/index.ts rename {app/actions => utils}/downloadDocument.ts (78%) create mode 100644 utils/patchDocument.ts delete mode 100644 utils/supabase.ts diff --git a/app/actions/patchDocument.ts b/app/actions/patchDocument.ts deleted file mode 100644 index a38f82b..0000000 --- a/app/actions/patchDocument.ts +++ /dev/null @@ -1,55 +0,0 @@ -'use server'; -import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; -import type { PatchParcel, Patches } from '@/types/index'; -import { patchDocument } from 'docx'; -import { readFileSync, writeFileSync } from 'fs'; -import path from 'path'; -import { IS_RUNNING_LOCALLY } from '../../utils/constants'; -import { staticFilePath } from '../../utils/path'; -import { supabaseUpsert } from '../../utils/supabase'; - -export default async (patchParcel: PatchParcel) => { - const { entity, filename, placeholders, skeleton } = patchParcel; - const givenEntity = patchableEntityMapper[entity?.__typename!]; - const patches: Patches = givenEntity.patches(entity, placeholders); - const file = readFileSync(staticFilePath(skeleton)); - - try { - const patch = await patchDocument(file, { - patches, - }).then((patch) => patch); - - return IS_RUNNING_LOCALLY - ? patchLocal(patch, filename) - : await patchProduction(patch, filename); - } catch (error) { - console.error(error); - } - - return undefined; -}; - -const patchLocal = (patch: Uint8Array, filename: string) => { - const newFilePath = path.join(`public/${filename}.docx`); - writeFileSync(newFilePath, patch); - - try { - writeFileSync(newFilePath, patch); - return `${filename}.docx`; - } catch (error) { - console.error(error); - } - - return undefined; -}; - -const patchProduction = async (patch: Uint8Array, filename: string) => { - try { - const upload = await supabaseUpsert(filename, patch); - return upload?.path; - } catch (error) { - console.error(error); - } - - return undefined; -}; diff --git a/app/api/patch/hook.ts b/app/api/patch/hook.ts new file mode 100644 index 0000000..dce7191 --- /dev/null +++ b/app/api/patch/hook.ts @@ -0,0 +1,23 @@ +import useSWR from 'swr'; +import type { PatchBackendParcel } from './route'; + +const fetcher = async (...args: any[]) => { + const req = await fetch('/api/patch', { + method: 'POST', + body: JSON.stringify(args[0]), + }); + return await req.json(); +}; + +export const usePatchDocument = ( + file: PatchBackendParcel['file'], + placeholders: PatchBackendParcel['placeholders'] +) => { + const { data, error, isLoading } = useSWR({ file, placeholders }, fetcher); + + return { + document: data, + isLoading, + error, + }; +}; diff --git a/app/api/patch/route.ts b/app/api/patch/route.ts new file mode 100644 index 0000000..0a7e437 --- /dev/null +++ b/app/api/patch/route.ts @@ -0,0 +1,21 @@ +import type { FileQuery } from '@/tina/__generated__/types'; +import type { Placeholders } from '@/types/index'; +import { NextResponse } from 'next/server'; +import patchDocument from '../../../utils/patchDocument'; + +export type PatchBackendParcel = { + file: FileQuery; + placeholders: Placeholders; +}; + +export async function POST(request: Request) { + const patchBackendParcel: PatchBackendParcel = await request.json(); + + const patch = await patchDocument(patchBackendParcel); + + if (!patch) { + return NextResponse.json({ error: 'Could not patch document' }); + } + + return NextResponse.json({ data: patch }, { status: 200 }); +} diff --git a/tina/utils/index.ts b/app/api/tina/hook.ts similarity index 100% rename from tina/utils/index.ts rename to app/api/tina/hook.ts diff --git a/app/files/[slug]/page.tsx b/app/files/[slug]/page.tsx index cf7cb3e..d18fc2c 100644 --- a/app/files/[slug]/page.tsx +++ b/app/files/[slug]/page.tsx @@ -24,7 +24,9 @@ export default async function Page({ params }: Params) { return ( Loading...}> - + {result && placeholders && ( + + )} ); } diff --git a/components/EditorPanel.tsx b/components/EditorPanel.tsx index ac462af..8cab12b 100644 --- a/components/EditorPanel.tsx +++ b/components/EditorPanel.tsx @@ -1,4 +1,4 @@ -import downloadDocument from '@/app/actions/downloadDocument'; +import downloadDocument from '@/utils/downloadDocument'; import { DownloadIcon, ListBulletIcon } from '@radix-ui/react-icons'; import { Button, Card, Flex } from '@radix-ui/themes'; import { useRouter } from 'next/navigation'; diff --git a/components/File.tsx b/components/File.tsx index 9b054d5..b981044 100644 --- a/components/File.tsx +++ b/components/File.tsx @@ -1,16 +1,15 @@ 'use client'; -import patchDocument from '@/app/actions/patchDocument'; +import { usePatchDocument } from '@/app/api/patch/hook'; import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; -import type { Placeholders, Skeleton } from '@/types/index'; +import type { Placeholders } from '@/types/index'; import { uniqueUuid } from 'docx'; -import { useEffect, useState } from 'react'; import { useTina } from 'tinacms/dist/react'; import { FileQuery } from '../tina/__generated__/types'; import EditorPanel from './EditorPanel'; import { renderView } from './View'; type FileProps = { - placeholders?: Placeholders; + placeholders: Placeholders; result: { data: FileQuery; variables: { @@ -22,44 +21,14 @@ type FileProps = { export default ({ placeholders, result }: FileProps) => { const { data } = useTina(result); - const [patchedDocument, setPatchedDocument] = useState(); + const { document } = usePatchDocument(data, placeholders); const givenEntity = patchableEntityMapper[data.file.entity?.__typename!]; - useEffect( - () => { - const { - file: { entity, name, skeleton }, - } = data; - - if (placeholders) { - const patchDocumentOnServer = async () => { - try { - const patchedDocument = await patchDocument({ - entity, - filename: name, - placeholders, - skeleton: skeleton as Skeleton, - }); - setPatchedDocument(patchedDocument); - } catch (error) { - console.error('Error patching document:', error); - } - }; - - if (skeleton && entity && name) { - patchDocumentOnServer(); - } - } - }, - [data, placeholders] /* TODO Only trigger when "Save" button is clicked */ - ); - return ( - placeholders && - givenEntity && ( - <> - - {placeholders.map((placeholder) => ( + <> + + {givenEntity && + placeholders.map((placeholder) => (
{renderView({ placeholder, @@ -69,8 +38,7 @@ export default ({ placeholders, result }: FileProps) => { })}
))} - - ) + ); }; diff --git a/env.ts b/env.ts index 5d05abc..88e2882 100644 --- a/env.ts +++ b/env.ts @@ -4,18 +4,18 @@ import { z } from 'zod'; export const env = createEnv({ server: { + SUPABASE_TOKEN: z.string().min(1), + SUPABASE_URL: z.string().url(), TINA_TOKEN: z.string().min(1), }, client: { NEXT_PUBLIC_TINA_CLIENT_ID: z.string().min(1), - NEXT_PUBLIC_SUPABASE_URL: z.string().url(), - NEXT_PUBLIC_SUPABASE_KEY: z.string().min(1), }, runtimeEnv: { - TINA_TOKEN: process.env.TINA_TOKEN, NEXT_PUBLIC_TINA_CLIENT_ID: process.env.NEXT_PUBLIC_TINA_CLIENT_ID, - NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL, - NEXT_PUBLIC_SUPABASE_KEY: process.env.NEXT_PUBLIC_SUPABASE_KEY, + SUPABASE_TOKEN: process.env.SUPABASE_TOKEN, + SUPABASE_URL: process.env.SUPABASE_URL, + TINA_TOKEN: process.env.TINA_TOKEN, }, skipValidation: process.env.NODE_ENV === 'development', onValidationError: (error: ZodError) => { diff --git a/tina/collections/audits.tsx b/tina/collections/audits.tsx index 0dae36b..65e134c 100644 --- a/tina/collections/audits.tsx +++ b/tina/collections/audits.tsx @@ -1,6 +1,5 @@ -import React from 'react'; import { Collection } from 'tinacms'; -import { DURATIONS, LOCATIONS, TIMES } from '../../utils/constants/tina'; +import { DURATIONS, LOCATIONS, TIMES } from '../../utils/constants'; import { readableDateFromDatetime, readableFileNameFromEntity, diff --git a/tina/picker/Picker.tsx b/tina/picker/Picker.tsx index 6d381a2..7d2a277 100644 --- a/tina/picker/Picker.tsx +++ b/tina/picker/Picker.tsx @@ -3,9 +3,8 @@ import * as Checkbox from '@radix-ui/react-checkbox'; import { CheckIcon } from '@radix-ui/react-icons'; import { Card, Text } from '@radix-ui/themes'; import { uniqueUuid } from 'docx'; -import React from 'react'; import { wrapFieldsWithMeta } from 'tinacms'; -import { useTinaQuery } from '../utils'; +import { useTinaQuery } from '../../app/api/tina/hook'; import pickerMapper from './pickerMapper'; // TODO also use directly in audit diff --git a/utils/constants/tina.ts b/utils/constants.ts similarity index 74% rename from utils/constants/tina.ts rename to utils/constants.ts index 1540982..27eaaea 100644 --- a/utils/constants/tina.ts +++ b/utils/constants.ts @@ -1,3 +1,11 @@ +/** Regex for placeholder {{field_STRING-OR-NUMBER_STRING-OR-NUMBER_...}} */ +export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; +export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; + +export const IS_RUNNING_LOCALLY = + !!process && process.env.NODE_ENV === 'development'; + +// TODO get rid of this export const LOCATIONS = [ '1100 Wien, Am Hauptbahnhof 1', '1020 Wien, Lassallestraße 5', diff --git a/utils/constants/index.ts b/utils/constants/index.ts deleted file mode 100644 index 938ebc6..0000000 --- a/utils/constants/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { createClient } from '@supabase/supabase-js'; - -/** Regex for placeholder {{field_STRING-OR-NUMBER_STRING-OR-NUMBER_...}} */ -export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; -export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; - -export const IS_RUNNING_LOCALLY = - !!process && process.env.NODE_ENV === 'development'; - -export const SUPABASE_CLIENT = - process.env.NEXT_PUBLIC_SUPABASE_URL && process.env.NEXT_PUBLIC_SUPABASE_KEY - ? createClient( - process.env.NEXT_PUBLIC_SUPABASE_URL, - process.env.NEXT_PUBLIC_SUPABASE_KEY - ) - : undefined; \ No newline at end of file diff --git a/app/actions/downloadDocument.ts b/utils/downloadDocument.ts similarity index 78% rename from app/actions/downloadDocument.ts rename to utils/downloadDocument.ts index 574ecbc..1a35f55 100644 --- a/app/actions/downloadDocument.ts +++ b/utils/downloadDocument.ts @@ -1,5 +1,3 @@ -import { supabaseDownload } from 'utils/supabase'; - const downloadBlob = (blob: Blob, fileName: string): void => { const link = document.createElement('a'); link.href = URL.createObjectURL(blob); @@ -14,7 +12,9 @@ const downloadBlob = (blob: Blob, fileName: string): void => { }; export default async (patchedDocument: string) => { - const patchedDocumentBlob = await supabaseDownload(patchedDocument); + // TODO + const patchedDocumentBlob = new Blob(); + // const patchedDocumentBlob = await supabaseDownload(patchedDocument); if (patchedDocumentBlob) { downloadBlob(patchedDocumentBlob, patchedDocument); diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts new file mode 100644 index 0000000..46526ef --- /dev/null +++ b/utils/patchDocument.ts @@ -0,0 +1,68 @@ +'use server'; +import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; +import type { Patches, Skeleton } from '@/types/index'; +import { createClient } from '@supabase/supabase-js'; +import { patchDocument } from 'docx'; +import { readFileSync, writeFileSync } from 'fs'; +import path from 'path'; +import type { PatchBackendParcel } from '../app/api/patch/route'; +import { IS_RUNNING_LOCALLY } from './constants'; +import { staticFilePath } from './path'; + +export default async (patchParcel: PatchBackendParcel) => { + const { + file: { + file: { entity, skeleton, name }, + }, + placeholders, + } = patchParcel; + + const givenEntity = patchableEntityMapper[entity?.__typename!]; + const patches: Patches = givenEntity.patches(entity, placeholders); + const file = readFileSync(staticFilePath(skeleton as Skeleton)); + + try { + const patch = await patchDocument(file, { + patches, + }).then((patch) => patch); + + return IS_RUNNING_LOCALLY + ? patchLocalDocument(patch, name) + : await patchProductionDocument(patch, name); + } catch (error) { + console.error(error); + } + + return undefined; +}; + +const patchLocalDocument = (patch: Uint8Array, filename: string) => { + const newFilePath = path.join(`public/${filename}.docx`); + writeFileSync(newFilePath, patch); + + try { + writeFileSync(newFilePath, patch); + return `${filename}.docx`; + } catch (error) { + console.error(error); + } + + return undefined; +}; + +const patchProductionDocument = async (patch: Uint8Array, filename: string) => { + const supabaseClient = createClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_TOKEN! + ); + + const { data, error } = await supabaseClient.storage + .from('Documents') + .upload(`${filename}.docx`, patch, { + contentType: + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + upsert: true, + }); + + return data?.path ? data.path : undefined; +}; diff --git a/utils/supabase.ts b/utils/supabase.ts deleted file mode 100644 index a6c2b01..0000000 --- a/utils/supabase.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { SUPABASE_CLIENT } from './constants'; - -// TODO do on server - -export const supabaseDownload = async (filename: string) => { - if (!SUPABASE_CLIENT) { - return null - } - - try { - const { data, error } = await SUPABASE_CLIENT.storage - .from('Documents') - .download(`${filename}`); - - if (!data) { - console.error(error); - throw new Error(`${error}`); - } - - return data; - } catch (error) { - console.error(error); - } - - return null; -}; - -export const supabaseUpsert = async (filename: string, file: any) => { - if (!SUPABASE_CLIENT) { - return null; - } - - try { - const { data, error } = await SUPABASE_CLIENT.storage - .from('Documents') - .upload(`${filename}.docx`, file, { - contentType: - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - upsert: true, - }); - - if (!data) { - console.error(error); - throw new Error(`${error}`); - } - - return data; - } catch (error) { - console.error(error); - } - - return null; -}; From 7d8ec8048ce61c7782b8082352c66fa386adbc63 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 00:25:05 +0200 Subject: [PATCH 04/20] download file from server --- app/api/document/download/route.ts | 36 ++++++++++++++++++++++++++ app/api/{ => document}/patch/hook.ts | 2 +- app/api/{ => document}/patch/route.ts | 2 +- components/EditorPanel.tsx | 37 +++++++++++++++++++++++---- components/File.tsx | 2 +- utils/downloadDocument.ts | 22 ---------------- utils/patchDocument.ts | 2 +- 7 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 app/api/document/download/route.ts rename app/api/{ => document}/patch/hook.ts (90%) rename app/api/{ => document}/patch/route.ts (90%) delete mode 100644 utils/downloadDocument.ts diff --git a/app/api/document/download/route.ts b/app/api/document/download/route.ts new file mode 100644 index 0000000..090e7bb --- /dev/null +++ b/app/api/document/download/route.ts @@ -0,0 +1,36 @@ +import type { FileQuery } from '@/tina/__generated__/types'; +import type { Placeholders } from '@/types/index'; +import { createClient } from '@supabase/supabase-js'; +import { NextResponse } from 'next/server'; + +export type PatchBackendParcel = { + file: FileQuery; + placeholders: Placeholders; +}; + +export const downloadDocument = async (document: string) => { + const req = await fetch('/api/document/download', { + method: 'POST', + body: JSON.stringify(document), + }); + + return await req.json(); +}; + +export async function POST(request: Request) { + const document: string = await request.json(); + + const supabaseClient = createClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_TOKEN! + ); + + const { data, error } = await supabaseClient.storage + .from('Documents') + .download(`${document}`); + + return NextResponse.json( + { data: Array.from(new Uint8Array(await data!.arrayBuffer())) }, + { status: 200 } + ); +} diff --git a/app/api/patch/hook.ts b/app/api/document/patch/hook.ts similarity index 90% rename from app/api/patch/hook.ts rename to app/api/document/patch/hook.ts index dce7191..276d72a 100644 --- a/app/api/patch/hook.ts +++ b/app/api/document/patch/hook.ts @@ -2,7 +2,7 @@ import useSWR from 'swr'; import type { PatchBackendParcel } from './route'; const fetcher = async (...args: any[]) => { - const req = await fetch('/api/patch', { + const req = await fetch('/api/document/patch', { method: 'POST', body: JSON.stringify(args[0]), }); diff --git a/app/api/patch/route.ts b/app/api/document/patch/route.ts similarity index 90% rename from app/api/patch/route.ts rename to app/api/document/patch/route.ts index 0a7e437..1dfa526 100644 --- a/app/api/patch/route.ts +++ b/app/api/document/patch/route.ts @@ -1,7 +1,7 @@ import type { FileQuery } from '@/tina/__generated__/types'; import type { Placeholders } from '@/types/index'; import { NextResponse } from 'next/server'; -import patchDocument from '../../../utils/patchDocument'; +import patchDocument from '../../../../utils/patchDocument'; export type PatchBackendParcel = { file: FileQuery; diff --git a/components/EditorPanel.tsx b/components/EditorPanel.tsx index 8cab12b..46ac99d 100644 --- a/components/EditorPanel.tsx +++ b/components/EditorPanel.tsx @@ -1,13 +1,26 @@ -import downloadDocument from '@/utils/downloadDocument'; +import { IS_RUNNING_LOCALLY } from '@/utils/constants'; import { DownloadIcon, ListBulletIcon } from '@radix-ui/react-icons'; import { Button, Card, Flex } from '@radix-ui/themes'; import { useRouter } from 'next/navigation'; -import { IS_RUNNING_LOCALLY } from 'utils/constants'; +import { downloadDocument } from '../app/api/document/download/route'; type EditorPanelProps = { patchedDocument?: string; }; +const downloadBlob = (blob: Blob, fileName: string): void => { + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = fileName; + + document.body.appendChild(link); + + link.click(); + + document.body.removeChild(link); + URL.revokeObjectURL(link.href); +}; + export default ({ patchedDocument }: EditorPanelProps) => { const router = useRouter(); @@ -29,9 +42,23 @@ export default ({ patchedDocument }: EditorPanelProps) => { className='bg-[#0c6bff]' title={`Download file ${patchedDocument}`} onClick={async () => { - IS_RUNNING_LOCALLY - ? router.push(`/${patchedDocument}`) - : await downloadDocument(patchedDocument!); + if (IS_RUNNING_LOCALLY) { + router.push(`/${patchedDocument}`); + return; + } + + const documentAsUint8Array = await downloadDocument( + patchedDocument! + ).then((data: Uint8Array) => data); + + const blob = new Blob([documentAsUint8Array]); + + const downloadLink = document.createElement('a'); + downloadLink.href = URL.createObjectURL(blob); + downloadLink.download = patchedDocument!; + document.body.appendChild(downloadLink); + downloadLink.click(); + document.body.removeChild(downloadLink); }} > diff --git a/components/File.tsx b/components/File.tsx index b981044..023905b 100644 --- a/components/File.tsx +++ b/components/File.tsx @@ -1,5 +1,5 @@ 'use client'; -import { usePatchDocument } from '@/app/api/patch/hook'; +import { usePatchDocument } from '@/app/api/document/patch/hook'; import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; import type { Placeholders } from '@/types/index'; import { uniqueUuid } from 'docx'; diff --git a/utils/downloadDocument.ts b/utils/downloadDocument.ts deleted file mode 100644 index 1a35f55..0000000 --- a/utils/downloadDocument.ts +++ /dev/null @@ -1,22 +0,0 @@ -const downloadBlob = (blob: Blob, fileName: string): void => { - const link = document.createElement('a'); - link.href = URL.createObjectURL(blob); - link.download = fileName; - - document.body.appendChild(link); - - link.click(); - - document.body.removeChild(link); - URL.revokeObjectURL(link.href); -}; - -export default async (patchedDocument: string) => { - // TODO - const patchedDocumentBlob = new Blob(); - // const patchedDocumentBlob = await supabaseDownload(patchedDocument); - - if (patchedDocumentBlob) { - downloadBlob(patchedDocumentBlob, patchedDocument); - } -}; diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index 46526ef..f9eb7b6 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -5,7 +5,7 @@ import { createClient } from '@supabase/supabase-js'; import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; -import type { PatchBackendParcel } from '../app/api/patch/route'; +import type { PatchBackendParcel } from '../app/api/document/patch/route'; import { IS_RUNNING_LOCALLY } from './constants'; import { staticFilePath } from './path'; From 6d525e2e5213d17a08e064911274e062370d169a Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:15:27 +0200 Subject: [PATCH 05/20] move route handler into client --- app/api/document/download/route.ts | 16 ---------------- components/EditorPanel.tsx | 10 +++++++++- types/index.ts | 13 ++++++------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/app/api/document/download/route.ts b/app/api/document/download/route.ts index 090e7bb..251c654 100644 --- a/app/api/document/download/route.ts +++ b/app/api/document/download/route.ts @@ -1,22 +1,6 @@ -import type { FileQuery } from '@/tina/__generated__/types'; -import type { Placeholders } from '@/types/index'; import { createClient } from '@supabase/supabase-js'; import { NextResponse } from 'next/server'; -export type PatchBackendParcel = { - file: FileQuery; - placeholders: Placeholders; -}; - -export const downloadDocument = async (document: string) => { - const req = await fetch('/api/document/download', { - method: 'POST', - body: JSON.stringify(document), - }); - - return await req.json(); -}; - export async function POST(request: Request) { const document: string = await request.json(); diff --git a/components/EditorPanel.tsx b/components/EditorPanel.tsx index 46ac99d..4f2db1c 100644 --- a/components/EditorPanel.tsx +++ b/components/EditorPanel.tsx @@ -2,7 +2,6 @@ import { IS_RUNNING_LOCALLY } from '@/utils/constants'; import { DownloadIcon, ListBulletIcon } from '@radix-ui/react-icons'; import { Button, Card, Flex } from '@radix-ui/themes'; import { useRouter } from 'next/navigation'; -import { downloadDocument } from '../app/api/document/download/route'; type EditorPanelProps = { patchedDocument?: string; @@ -47,6 +46,15 @@ export default ({ patchedDocument }: EditorPanelProps) => { return; } + const downloadDocument = async (document: string) => { + const req = await fetch('/api/document/download', { + method: 'POST', + body: JSON.stringify(document), + }); + + return await req.json(); + }; + const documentAsUint8Array = await downloadDocument( patchedDocument! ).then((data: Uint8Array) => data); diff --git a/types/index.ts b/types/index.ts index 3580c47..da6e191 100644 --- a/types/index.ts +++ b/types/index.ts @@ -18,12 +18,6 @@ export type DocxStringConversionResult = { }[]; }; export type Patches = Record; -export type PatchParcel = { - entity: FileQuery['file']['entity']; - filename: string; - placeholders: Placeholders; - skeleton: Skeleton; -}; export interface PatchableEntity { placeholderTinaField: ( @@ -67,4 +61,9 @@ export interface PickerTypeSettings { query: TinaBackendParcel['query']; variables: TinaBackendParcel['variables']; variant: 'SingleValue' | 'MultiValue'; -} \ No newline at end of file +} + +export type PatchBackendParcel = { + file: FileQuery; + placeholders: Placeholders; +}; \ No newline at end of file From a916a968593d84c1907515d89a51cfc9ce4eafc4 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:27:13 +0200 Subject: [PATCH 06/20] get rid of process development checker --- components/EditorPanel.tsx | 4 ++-- utils/constants.ts | 6 ++++-- utils/patchDocument.ts | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/components/EditorPanel.tsx b/components/EditorPanel.tsx index 4f2db1c..e3c1090 100644 --- a/components/EditorPanel.tsx +++ b/components/EditorPanel.tsx @@ -1,4 +1,4 @@ -import { IS_RUNNING_LOCALLY } from '@/utils/constants'; +import { isDevelopment } from '@/utils/constants'; import { DownloadIcon, ListBulletIcon } from '@radix-ui/react-icons'; import { Button, Card, Flex } from '@radix-ui/themes'; import { useRouter } from 'next/navigation'; @@ -41,7 +41,7 @@ export default ({ patchedDocument }: EditorPanelProps) => { className='bg-[#0c6bff]' title={`Download file ${patchedDocument}`} onClick={async () => { - if (IS_RUNNING_LOCALLY) { + if (isDevelopment()) { router.push(`/${patchedDocument}`); return; } diff --git a/utils/constants.ts b/utils/constants.ts index 27eaaea..8b492a6 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -2,8 +2,10 @@ export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; -export const IS_RUNNING_LOCALLY = - !!process && process.env.NODE_ENV === 'development'; +export const isDevelopment = () => + window.location.hostname === 'localhost' || + window.location.hostname === '127.0.0.1' || + window.location.hostname.startsWith('192.168.'); // TODO get rid of this export const LOCATIONS = [ diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index f9eb7b6..6e8d80b 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -6,7 +6,7 @@ import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; import type { PatchBackendParcel } from '../app/api/document/patch/route'; -import { IS_RUNNING_LOCALLY } from './constants'; +import { isDevelopment } from './constants'; import { staticFilePath } from './path'; export default async (patchParcel: PatchBackendParcel) => { @@ -26,7 +26,7 @@ export default async (patchParcel: PatchBackendParcel) => { patches, }).then((patch) => patch); - return IS_RUNNING_LOCALLY + return isDevelopment() ? patchLocalDocument(patch, name) : await patchProductionDocument(patch, name); } catch (error) { From 6869b06be9e83916f739f8d0d4425ff3796c9517 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:31:22 +0200 Subject: [PATCH 07/20] development checker --- utils/constants.ts | 3 +++ utils/patchDocument.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/utils/constants.ts b/utils/constants.ts index 8b492a6..bf08d92 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -2,6 +2,9 @@ export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; +export const IS_RUNNING_LOCALLY = + !!process && process.env.NODE_ENV === 'development'; + export const isDevelopment = () => window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' || diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index 6e8d80b..f9eb7b6 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -6,7 +6,7 @@ import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; import type { PatchBackendParcel } from '../app/api/document/patch/route'; -import { isDevelopment } from './constants'; +import { IS_RUNNING_LOCALLY } from './constants'; import { staticFilePath } from './path'; export default async (patchParcel: PatchBackendParcel) => { @@ -26,7 +26,7 @@ export default async (patchParcel: PatchBackendParcel) => { patches, }).then((patch) => patch); - return isDevelopment() + return IS_RUNNING_LOCALLY ? patchLocalDocument(patch, name) : await patchProductionDocument(patch, name); } catch (error) { From ca589b50fd7a9bac553db2d1e984ca169e06ebc9 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:33:37 +0200 Subject: [PATCH 08/20] Revert "development checker" This reverts commit 6869b06be9e83916f739f8d0d4425ff3796c9517. --- utils/constants.ts | 3 --- utils/patchDocument.ts | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/utils/constants.ts b/utils/constants.ts index bf08d92..8b492a6 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -2,9 +2,6 @@ export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; -export const IS_RUNNING_LOCALLY = - !!process && process.env.NODE_ENV === 'development'; - export const isDevelopment = () => window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' || diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index f9eb7b6..6e8d80b 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -6,7 +6,7 @@ import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; import type { PatchBackendParcel } from '../app/api/document/patch/route'; -import { IS_RUNNING_LOCALLY } from './constants'; +import { isDevelopment } from './constants'; import { staticFilePath } from './path'; export default async (patchParcel: PatchBackendParcel) => { @@ -26,7 +26,7 @@ export default async (patchParcel: PatchBackendParcel) => { patches, }).then((patch) => patch); - return IS_RUNNING_LOCALLY + return isDevelopment() ? patchLocalDocument(patch, name) : await patchProductionDocument(patch, name); } catch (error) { From 6c5d5d2a47d0c12ffc93b08b86003bb6bd73bfbf Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:34:03 +0200 Subject: [PATCH 09/20] check for dev --- utils/patchDocument.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index 6e8d80b..db2809b 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -26,6 +26,8 @@ export default async (patchParcel: PatchBackendParcel) => { patches, }).then((patch) => patch); + console.log('Development: ', isDevelopment()); + return isDevelopment() ? patchLocalDocument(patch, name) : await patchProductionDocument(patch, name); From fd6686d1ee115d51d1af3cb7f5931905fcbd335a Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:41:21 +0200 Subject: [PATCH 10/20] add some info logs --- app/api/document/patch/route.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/api/document/patch/route.ts b/app/api/document/patch/route.ts index 1dfa526..f76b516 100644 --- a/app/api/document/patch/route.ts +++ b/app/api/document/patch/route.ts @@ -11,6 +11,8 @@ export type PatchBackendParcel = { export async function POST(request: Request) { const patchBackendParcel: PatchBackendParcel = await request.json(); + console.info('Bakend patch parcel: ', patchBackendParcel); + const patch = await patchDocument(patchBackendParcel); if (!patch) { From 1c9621e047eb33f04f754d28d503ba30f46b9482 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 11:41:26 +0200 Subject: [PATCH 11/20] add info logs --- utils/patchDocument.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index db2809b..539efb2 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -26,7 +26,7 @@ export default async (patchParcel: PatchBackendParcel) => { patches, }).then((patch) => patch); - console.log('Development: ', isDevelopment()); + console.info('Development: ', isDevelopment()); return isDevelopment() ? patchLocalDocument(patch, name) From eca4bf3338a7e53b7c31334bc3e1efbdf2d5b666 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:23:48 +0200 Subject: [PATCH 12/20] try to check both development via window and proces --- utils/constants.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils/constants.ts b/utils/constants.ts index 8b492a6..7847947 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -3,9 +3,11 @@ export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; export const isDevelopment = () => - window.location.hostname === 'localhost' || - window.location.hostname === '127.0.0.1' || - window.location.hostname.startsWith('192.168.'); + window + ? window.location.hostname === 'localhost' || + window.location.hostname === '127.0.0.1' || + window.location.hostname.startsWith('192.168.') + : process.env.NODE_ENV && process.env.NODE_ENV === 'development'; // TODO get rid of this export const LOCATIONS = [ From 4bc8292e34bc714eeecad946e68bf5aae0957bce Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:38:36 +0200 Subject: [PATCH 13/20] Revert "try to check both development via window and proces" This reverts commit eca4bf3338a7e53b7c31334bc3e1efbdf2d5b666. --- utils/constants.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/utils/constants.ts b/utils/constants.ts index 7847947..8b492a6 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -3,11 +3,9 @@ export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; export const isDevelopment = () => - window - ? window.location.hostname === 'localhost' || - window.location.hostname === '127.0.0.1' || - window.location.hostname.startsWith('192.168.') - : process.env.NODE_ENV && process.env.NODE_ENV === 'development'; + window.location.hostname === 'localhost' || + window.location.hostname === '127.0.0.1' || + window.location.hostname.startsWith('192.168.'); // TODO get rid of this export const LOCATIONS = [ From 88ff824c440d13123241650f2e257ddee2a62619 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:40:02 +0200 Subject: [PATCH 14/20] check dev directly --- components/EditorPanel.tsx | 3 +-- utils/constants.ts | 5 ----- utils/patchDocument.ts | 5 +---- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/components/EditorPanel.tsx b/components/EditorPanel.tsx index e3c1090..9a7bb73 100644 --- a/components/EditorPanel.tsx +++ b/components/EditorPanel.tsx @@ -1,4 +1,3 @@ -import { isDevelopment } from '@/utils/constants'; import { DownloadIcon, ListBulletIcon } from '@radix-ui/react-icons'; import { Button, Card, Flex } from '@radix-ui/themes'; import { useRouter } from 'next/navigation'; @@ -41,7 +40,7 @@ export default ({ patchedDocument }: EditorPanelProps) => { className='bg-[#0c6bff]' title={`Download file ${patchedDocument}`} onClick={async () => { - if (isDevelopment()) { + if (window.location.hostname === 'localhost') { router.push(`/${patchedDocument}`); return; } diff --git a/utils/constants.ts b/utils/constants.ts index 8b492a6..e2fdd92 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -2,11 +2,6 @@ export const PLACEHOLDER_REGEX = /{{field_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*}}/g; export const LETTERS_NUMBERS_HYPEN_BLANK_REGEX = /^[a-zA-Z0-9-\s]+$/; -export const isDevelopment = () => - window.location.hostname === 'localhost' || - window.location.hostname === '127.0.0.1' || - window.location.hostname.startsWith('192.168.'); - // TODO get rid of this export const LOCATIONS = [ '1100 Wien, Am Hauptbahnhof 1', diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index 539efb2..c8b8bfb 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -6,7 +6,6 @@ import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; import type { PatchBackendParcel } from '../app/api/document/patch/route'; -import { isDevelopment } from './constants'; import { staticFilePath } from './path'; export default async (patchParcel: PatchBackendParcel) => { @@ -26,9 +25,7 @@ export default async (patchParcel: PatchBackendParcel) => { patches, }).then((patch) => patch); - console.info('Development: ', isDevelopment()); - - return isDevelopment() + return process.env.NODE_ENV === 'development' ? patchLocalDocument(patch, name) : await patchProductionDocument(patch, name); } catch (error) { From 5a69ed611c71e563cc0af4d0d6093b78164fda65 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:49:46 +0200 Subject: [PATCH 15/20] move type, remove unused function --- app/api/document/patch/hook.ts | 2 +- app/api/document/patch/route.ts | 8 +------- components/EditorPanel.tsx | 13 ------------- utils/patchDocument.ts | 3 +-- 4 files changed, 3 insertions(+), 23 deletions(-) diff --git a/app/api/document/patch/hook.ts b/app/api/document/patch/hook.ts index 276d72a..1d14db3 100644 --- a/app/api/document/patch/hook.ts +++ b/app/api/document/patch/hook.ts @@ -1,5 +1,5 @@ +import type { PatchBackendParcel } from '@/types/index'; import useSWR from 'swr'; -import type { PatchBackendParcel } from './route'; const fetcher = async (...args: any[]) => { const req = await fetch('/api/document/patch', { diff --git a/app/api/document/patch/route.ts b/app/api/document/patch/route.ts index f76b516..02d1135 100644 --- a/app/api/document/patch/route.ts +++ b/app/api/document/patch/route.ts @@ -1,13 +1,7 @@ -import type { FileQuery } from '@/tina/__generated__/types'; -import type { Placeholders } from '@/types/index'; +import type { PatchBackendParcel } from '@/types/index'; import { NextResponse } from 'next/server'; import patchDocument from '../../../../utils/patchDocument'; -export type PatchBackendParcel = { - file: FileQuery; - placeholders: Placeholders; -}; - export async function POST(request: Request) { const patchBackendParcel: PatchBackendParcel = await request.json(); diff --git a/components/EditorPanel.tsx b/components/EditorPanel.tsx index 9a7bb73..614f074 100644 --- a/components/EditorPanel.tsx +++ b/components/EditorPanel.tsx @@ -6,19 +6,6 @@ type EditorPanelProps = { patchedDocument?: string; }; -const downloadBlob = (blob: Blob, fileName: string): void => { - const link = document.createElement('a'); - link.href = URL.createObjectURL(blob); - link.download = fileName; - - document.body.appendChild(link); - - link.click(); - - document.body.removeChild(link); - URL.revokeObjectURL(link.href); -}; - export default ({ patchedDocument }: EditorPanelProps) => { const router = useRouter(); diff --git a/utils/patchDocument.ts b/utils/patchDocument.ts index c8b8bfb..c97535a 100644 --- a/utils/patchDocument.ts +++ b/utils/patchDocument.ts @@ -1,11 +1,10 @@ 'use server'; import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; -import type { Patches, Skeleton } from '@/types/index'; +import type { PatchBackendParcel, Patches, Skeleton } from '@/types/index'; import { createClient } from '@supabase/supabase-js'; import { patchDocument } from 'docx'; import { readFileSync, writeFileSync } from 'fs'; import path from 'path'; -import type { PatchBackendParcel } from '../app/api/document/patch/route'; import { staticFilePath } from './path'; export default async (patchParcel: PatchBackendParcel) => { From cbc5255fa316d19ccc1f848c8301e023f10dd2be Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:50:44 +0200 Subject: [PATCH 16/20] update docs --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0979944..775012c 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ Prepare the project for a deployment (with Vercel). Just add some environment va TINA_TOKEN= NEXT_PUBLIC_TINA_CLIENT_ID= -NEXT_PUBLIC_SUPABASE_URL= -NEXT_PUBLIC_SUPABASE_KEY= +SUPABASE_URL= +SUPABASE_KEY= ``` More info here: [Going to Production with Tina Cloud](https://tina.io/docs/tina-cloud/overview/) and [Supabase Storage Quickstart](https://supabase.com/docs/guides/storage/quickstart) From df43f4a7e41ca150439dad6f314cfd581018be16 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:57:55 +0200 Subject: [PATCH 17/20] map paths in app directory --- app/api/document/patch/route.ts | 2 +- app/api/tina/route.ts | 2 +- app/files/[slug]/page.tsx | 6 +++--- app/files/page.tsx | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/api/document/patch/route.ts b/app/api/document/patch/route.ts index 02d1135..73b7648 100644 --- a/app/api/document/patch/route.ts +++ b/app/api/document/patch/route.ts @@ -1,6 +1,6 @@ import type { PatchBackendParcel } from '@/types/index'; +import patchDocument from '@/utils/patchDocument'; import { NextResponse } from 'next/server'; -import patchDocument from '../../../../utils/patchDocument'; export async function POST(request: Request) { const patchBackendParcel: PatchBackendParcel = await request.json(); diff --git a/app/api/tina/route.ts b/app/api/tina/route.ts index dc86ae2..0ab7608 100644 --- a/app/api/tina/route.ts +++ b/app/api/tina/route.ts @@ -1,6 +1,6 @@ +import client from '@/tina/__generated__/client'; import type { TinaBackendParcel } from '@/types/index'; import { NextResponse } from 'next/server'; -import client from '../../../tina/__generated__/client'; export async function POST(request: Request) { const tinaBackendParcel: TinaBackendParcel = await request.json(); diff --git a/app/files/[slug]/page.tsx b/app/files/[slug]/page.tsx index d18fc2c..790eea4 100644 --- a/app/files/[slug]/page.tsx +++ b/app/files/[slug]/page.tsx @@ -1,9 +1,9 @@ +import File from '@/components/File'; +import client from '@/tina/__generated__/client'; import type { Skeleton } from '@/types/index'; +import extractPlaceholders from '@/utils/extractPlaceholders'; import { Text } from '@radix-ui/themes'; import { Suspense } from 'react'; -import File from '../../../components/File'; -import client from '../../../tina/__generated__/client'; -import extractPlaceholders from '../../../utils/extractPlaceholders'; export type Params = { params: { diff --git a/app/files/page.tsx b/app/files/page.tsx index 9a8b2ab..ee12fbb 100644 --- a/app/files/page.tsx +++ b/app/files/page.tsx @@ -1,6 +1,6 @@ import Files from '@/components/Files'; +import client from '@/tina/__generated__/client'; import type { FileLinkInfo } from '@/types/index'; -import client from '../../tina/__generated__/client'; export default async function Page() { const result = await client.queries.fileConnection(); From 49467f31ac4436ecbf7b8480f4f5200f52c89eae Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Mon, 1 Apr 2024 23:59:33 +0200 Subject: [PATCH 18/20] map paths in components directory --- components/Card/NewFileCard.tsx | 3 +-- components/File.tsx | 2 +- components/Files.tsx | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/components/Card/NewFileCard.tsx b/components/Card/NewFileCard.tsx index 9eb92e4..eee0fa6 100644 --- a/components/Card/NewFileCard.tsx +++ b/components/Card/NewFileCard.tsx @@ -1,11 +1,10 @@ 'use client'; +import { LETTERS_NUMBERS_HYPEN_BLANK_REGEX } from '@/utils/constants'; import { AccessibleIcon } from '@radix-ui/react-accessible-icon'; import * as Form from '@radix-ui/react-form'; import { FilePlusIcon } from '@radix-ui/react-icons'; import { Button, Card, Flex, Text } from '@radix-ui/themes'; -import { revalidatePath } from 'next/cache'; import { useRouter } from 'next/navigation'; -import { LETTERS_NUMBERS_HYPEN_BLANK_REGEX } from '../../utils/constants'; /** Card component that includes a form to create new files */ export default () => { diff --git a/components/File.tsx b/components/File.tsx index 023905b..6c4df11 100644 --- a/components/File.tsx +++ b/components/File.tsx @@ -1,10 +1,10 @@ 'use client'; import { usePatchDocument } from '@/app/api/document/patch/hook'; +import { FileQuery } from '@/tina/__generated__/types'; import patchableEntityMapper from '@/tina/patchable-entity/patchableEntityMapper'; import type { Placeholders } from '@/types/index'; import { uniqueUuid } from 'docx'; import { useTina } from 'tinacms/dist/react'; -import { FileQuery } from '../tina/__generated__/types'; import EditorPanel from './EditorPanel'; import { renderView } from './View'; diff --git a/components/Files.tsx b/components/Files.tsx index 7c46ee4..803e7c3 100644 --- a/components/Files.tsx +++ b/components/Files.tsx @@ -1,8 +1,8 @@ 'use client'; import type { FileLinkInfo } from '@/types/index'; +import { fileInEditMode } from '@/utils/path'; import { Grid, Link } from '@radix-ui/themes'; import { uniqueUuid } from 'docx'; -import { fileInEditMode } from '../utils/path'; import ContextCard from './Card/ContextCard'; import NewFileCard from './Card/NewFileCard'; From 72ef100bfb9949d1c129d842cb3e35c4e9d68003 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Tue, 2 Apr 2024 00:03:54 +0200 Subject: [PATCH 19/20] map paths in types directory --- types/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/types/index.ts b/types/index.ts index da6e191..a24781f 100644 --- a/types/index.ts +++ b/types/index.ts @@ -1,6 +1,6 @@ +import type client from '@/tina/__generated__/client'; +import { FileQuery } from '@/tina/__generated__/types'; import type { IPatch } from 'docx'; -import { FileQuery } from 'tina/__generated__/types'; -import type client from '../tina/__generated__/client'; export type Skeleton = `/uploads/skeletons/${string}.docx`; export type Placeholders = `{{field_${string}}}`[]; @@ -66,4 +66,4 @@ export interface PickerTypeSettings { export type PatchBackendParcel = { file: FileQuery; placeholders: Placeholders; -}; \ No newline at end of file +}; From 8d04a7fc977a4c6672d5b0bbffc1f8c8a8d90f31 Mon Sep 17 00:00:00 2001 From: Focke Adrian Date: Tue, 2 Apr 2024 00:08:38 +0200 Subject: [PATCH 20/20] edit logs --- app/api/document/patch/route.ts | 2 -- utils/extractPlaceholders.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/api/document/patch/route.ts b/app/api/document/patch/route.ts index 73b7648..2a61746 100644 --- a/app/api/document/patch/route.ts +++ b/app/api/document/patch/route.ts @@ -5,8 +5,6 @@ import { NextResponse } from 'next/server'; export async function POST(request: Request) { const patchBackendParcel: PatchBackendParcel = await request.json(); - console.info('Bakend patch parcel: ', patchBackendParcel); - const patch = await patchDocument(patchBackendParcel); if (!patch) { diff --git a/utils/extractPlaceholders.ts b/utils/extractPlaceholders.ts index 17601c6..05ac99d 100644 --- a/utils/extractPlaceholders.ts +++ b/utils/extractPlaceholders.ts @@ -29,7 +29,7 @@ export const createHtmlStringFromDocx = async (skeleton: Skeleton) => { }); return result.value; } catch (error) { - console.error('Error in createHtmlStringFromDocx: ', error); + console.error(error); } };