diff --git a/proto/.gitignore b/proto/.gitignore index 5ef6a52..7f376ea 100755 --- a/proto/.gitignore +++ b/proto/.gitignore @@ -39,3 +39,9 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# Payload CMS — local upload storage (MITHOME-89). Runtime data, not source; +# needs a persistent Docker volume in staging/production (see MITHOME-97). +/media +# Payload CMS — generated TS types (payload.config.ts typescript.outputFile) +src/payload-types.ts diff --git a/proto/scripts/migrate-content-to-payload.ts b/proto/scripts/migrate-content-to-payload.ts index 8c12c3c..384c755 100644 --- a/proto/scripts/migrate-content-to-payload.ts +++ b/proto/scripts/migrate-content-to-payload.ts @@ -12,6 +12,8 @@ * írja a Payload-ban lévő korábbi állapotot. NEM törli/nem érinti a JSON * fájlokat. */ +import path from 'path' +import { fileURLToPath } from 'url' import { getPayload, type Payload } from 'payload' import config from '../src/payload.config' @@ -23,6 +25,9 @@ import commonJson from '../src/content/common.json' import adatvedelemJson from '../src/content/pages/adatvedelem.json' import hasznalatiFeltetelekJson from '../src/content/pages/hasznalati-feltetelek.json' +const scriptDir = path.dirname(fileURLToPath(import.meta.url)) +const publicDir = path.resolve(scriptDir, '../public') + /** string[] -> [{ value: string }] — lásd src/globals/fields/stringArray.ts */ function toStringArray(items: readonly string[]): { value: string }[] { return items.map((value) => ({ value })) @@ -109,6 +114,54 @@ async function upsertLegalPage(payload: Payload, slug: string, json: LegalPageJs } } +type PartnerJson = { name: string; url: string; logo: string } + +/** + * MITHOME-89 (MVP): a home.json partners.items publikus /partners/*.png + * útvonalait tölti fel Media collection dokumentumként, majd Partner + * rekordot hoz létre/frissít rá hivatkozva. Idempotens: a Media dokumentumot + * `alt` (== partner név) alapján, a Partnert `name` alapján keresi. + */ +async function upsertPartner(payload: Payload, partner: PartnerJson) { + const existingMedia = await payload.find({ + collection: 'media', + where: { alt: { equals: partner.name } }, + limit: 1, + }) + + let mediaId: string | number + if (existingMedia.docs.length > 0) { + mediaId = existingMedia.docs[0].id + } else { + const filePath = path.resolve(publicDir, partner.logo.replace(/^\//, '')) + const created = await payload.create({ + collection: 'media', + data: { alt: partner.name }, + filePath, + }) + mediaId = created.id + } + + const existingPartner = await payload.find({ + collection: 'partners', + where: { name: { equals: partner.name } }, + limit: 1, + }) + + if (existingPartner.docs.length > 0) { + await payload.update({ + collection: 'partners', + id: existingPartner.docs[0].id, + data: { name: partner.name, url: partner.url, logo: mediaId }, + }) + } else { + await payload.create({ + collection: 'partners', + data: { name: partner.name, url: partner.url, logo: mediaId }, + }) + } +} + async function run() { const payload = await getPayload({ config }) @@ -133,7 +186,12 @@ async function run() { await upsertLegalPage(payload, 'hasznalati-feltetelek', hasznalatiFeltetelekJson) payload.logger.info('LegalPages/hasznalati-feltetelek migrálva') - payload.logger.info('MITHOME-87/88 migráció kész.') + for (const partner of homeJson.partners.items) { + await upsertPartner(payload, partner) + payload.logger.info(`Partners/${partner.name} migrálva`) + } + + payload.logger.info('MITHOME-87/88/89 migráció kész.') process.exit(0) } diff --git a/proto/src/collections/Media.ts b/proto/src/collections/Media.ts new file mode 100644 index 0000000..55f1d68 --- /dev/null +++ b/proto/src/collections/Media.ts @@ -0,0 +1,33 @@ +import type { CollectionConfig } from 'payload' + +/** + * MITHOME-89 (MVP scope) — Payload beépített upload collection. + * + * WHY nincs saját `staticDir` a `proto/public/`-ba mutatva: a fájlokat a + * Payload a saját REST route-jain (src/app/(payload)/api/[...slug]/route.ts) + * szolgálja ki, nem közvetlen statikus mappából — így nem ütközik a régi + * content-editor.js-féle /public/partners/*.png fájlokkal, amik MITHOME-93 + * leépítéséig még élnek. + * + * A tényleges vágás/forgatás/áttetszővé tétel szerkesztő NEM ide tartozik — + * lásd MITHOME-118 (külön, egyedi admin field component). + */ +export const Media: CollectionConfig = { + slug: 'media', + admin: { + group: 'Média', + }, + upload: { + mimeTypes: ['image/*'], + }, + fields: [ + { + name: 'alt', + type: 'text', + required: true, + admin: { + description: 'Alternatív szöveg (accessibility) — pl. "Angele Pihenőház logó".', + }, + }, + ], +} diff --git a/proto/src/collections/Partners.ts b/proto/src/collections/Partners.ts new file mode 100644 index 0000000..d469a80 --- /dev/null +++ b/proto/src/collections/Partners.ts @@ -0,0 +1,25 @@ +import type { CollectionConfig } from 'payload' + +/** + * Mirrors home.json `partners.items` (proto/src/content/pages/home.json) — + * MITHOME-89 (MVP). Korábban a Home Global szándékosan NEM tartalmazta ezt + * a listát (lásd src/globals/Home.ts megjegyzése) — itt lesz az önálló + * collection, logo = Media upload reference. + */ +export const Partners: CollectionConfig = { + slug: 'partners', + admin: { + useAsTitle: 'name', + group: 'Oldalak', + }, + fields: [ + { name: 'name', type: 'text', required: true }, + { name: 'url', type: 'text', required: true }, + { + name: 'logo', + type: 'upload', + relationTo: 'media', + required: true, + }, + ], +} diff --git a/proto/src/payload.config.ts b/proto/src/payload.config.ts index 9211fe1..628abcc 100644 --- a/proto/src/payload.config.ts +++ b/proto/src/payload.config.ts @@ -8,7 +8,9 @@ * MITHOME-87: Home/About/Services/Contact/Common Globals hozzáadva — ezek * tükrözik a proto/src/content/pages/*.json + common.json struktúráját. * MITHOME-88: LegalPages collection hozzáadva (adatvedelem, hasznalati- - * feltetelek). A Partners/Media collectionök a MITHOME-89-ben kerülnek be. + * feltetelek). + * MITHOME-89: Partners + Media collection (MVP — feltöltés, a vágás/ + * áttetszővé tétel szerkesztő külön, MITHOME-118). */ import path from 'path' import { fileURLToPath } from 'url' @@ -19,6 +21,8 @@ import sharp from 'sharp' import { Users } from './collections/Users' import { LegalPages } from './collections/LegalPages' +import { Media } from './collections/Media' +import { Partners } from './collections/Partners' import { Home } from './globals/Home' import { About } from './globals/About' import { Services } from './globals/Services' @@ -37,7 +41,7 @@ export default buildConfig({ editor: lexicalEditor(), - collections: [Users, LegalPages], + collections: [Users, LegalPages, Media, Partners], globals: [Home, About, Services, Contact, Common],