From a82b35d298bc3cbc71e7efbadceb0520f6e7459c Mon Sep 17 00:00:00 2001 From: MichalC <103170279+wSBMichalee@users.noreply.github.com> Date: Thu, 17 Sep 2026 23:22:01 +0200 Subject: [PATCH] fix(testimonials): group dots by pages on desktop and scroll by two items --- scripts/add_more_testimonials.ts | 67 ++++++++++++++++++++++++++++ scripts/check_testimonials.ts | 30 +++++++++++++ src/blocks/Testimonials/Carousel.tsx | 41 ++++++++++++++--- 3 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 scripts/add_more_testimonials.ts create mode 100644 scripts/check_testimonials.ts diff --git a/scripts/add_more_testimonials.ts b/scripts/add_more_testimonials.ts new file mode 100644 index 0000000..9bd5c65 --- /dev/null +++ b/scripts/add_more_testimonials.ts @@ -0,0 +1,67 @@ +import { getPayload } from 'payload' +import configPromise from '../src/payload.config' + +async function run() { + const payload = await getPayload({ config: configPromise }) + const locales = ['pl', 'de'] + + const additionalPL = [ + { + quote: "Pełen profesjonalizm! Odzyskałem zwrot, o którym nawet nie wiedziałem, że mi przysługuje.", + author: "Marek, Hamburg" + }, + { + quote: "Świetny kontakt, bezproblemowe załatwienie sprawy od początku do końca. Zdecydowanie polecam każdemu.", + author: "Katarzyna, Frankfurt" + }, + { + quote: "Sprawa z Finanzamt załatwiona szybko i bez nerwów. Dziękuję za pomoc i zaangażowanie.", + author: "Tomasz, Stuttgart" + } + ] + + const additionalDE = [ + { + quote: "Volle Professionalität! Ich habe eine Rückerstattung erhalten, von der ich gar nicht wusste, dass sie mir zusteht.", + author: "Marek, Hamburg" + }, + { + quote: "Toller Kontakt, reibungslose Abwicklung von Anfang bis Ende. Ich kann es jedem wärmstens empfehlen.", + author: "Katarzyna, Frankfurt" + }, + { + quote: "Die Angelegenheit mit dem Finanzamt wurde schnell und ohne Stress geklärt. Vielen Dank für die Hilfe.", + author: "Tomasz, Stuttgart" + } + ] + + for (const locale of locales) { + const pages = await payload.find({ collection: 'pages', locale: locale as any, where: { slug: { equals: locale === 'pl' ? 'home' : 'home' } } }) + if (pages.docs.length > 0) { + const doc = pages.docs[0] + let changed = false + const newLayout = doc.layout?.map((block: any) => { + if (block.blockType === 'testimonials') { + // ensure we have 6 items + if (block.testimonials && block.testimonials.length < 6) { + const additions = locale === 'pl' ? additionalPL : additionalDE + block.testimonials = [...block.testimonials, ...additions.slice(0, 6 - block.testimonials.length)] + changed = true + } + } + return block + }) + if (changed) { + await payload.update({ + collection: 'pages', + id: doc.id, + locale: locale as any, + data: { layout: newLayout } + }) + console.log(`Added 3 more testimonials to ${locale} home page.`) + } + } + } + process.exit(0) +} +run().catch(console.error) diff --git a/scripts/check_testimonials.ts b/scripts/check_testimonials.ts new file mode 100644 index 0000000..3d686ab --- /dev/null +++ b/scripts/check_testimonials.ts @@ -0,0 +1,30 @@ +import { getPayload } from 'payload' +import configPromise from '../src/payload.config' + +async function run() { + const payload = await getPayload({ config: configPromise }) + const pages = await payload.find({ collection: 'pages', limit: 100 }) // fetch all locales? + + const plPages = await payload.find({ collection: 'pages', locale: 'pl', limit: 100 }) + const dePages = await payload.find({ collection: 'pages', locale: 'de', limit: 100 }) + + console.log("=== PL ===") + plPages.docs.forEach(page => { + page.layout?.forEach(block => { + if (block.blockType === 'testimonials' || block.blockType === 'testimonialsGrid') { + console.log(`Page: ${page.slug}, Block: ${block.blockType}, Items: ${block.testimonials?.length || 0}`) + } + }) + }) + + console.log("=== DE ===") + dePages.docs.forEach(page => { + page.layout?.forEach(block => { + if (block.blockType === 'testimonials' || block.blockType === 'testimonialsGrid') { + console.log(`Page: ${page.slug}, Block: ${block.blockType}, Items: ${block.testimonials?.length || 0}`) + } + }) + }) + process.exit(0) +} +run() diff --git a/src/blocks/Testimonials/Carousel.tsx b/src/blocks/Testimonials/Carousel.tsx index 4b62f02..f49b9ae 100644 --- a/src/blocks/Testimonials/Carousel.tsx +++ b/src/blocks/Testimonials/Carousel.tsx @@ -46,7 +46,8 @@ export const TestimonialsCarousel: React.FC = ({ title, items }) let minDiff = Infinity children.forEach((child, index) => { - const diff = Math.abs(child.offsetLeft - scrollLeft) + const childRelativeLeft = child.offsetLeft - containerRef.current!.offsetLeft + const diff = Math.abs(childRelativeLeft - scrollLeft) if (diff < minDiff) { minDiff = diff closestIndex = index @@ -76,23 +77,29 @@ export const TestimonialsCarousel: React.FC = ({ title, items }) const child = children[index] as HTMLElement const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches + const targetLeft = child.offsetLeft - containerRef.current.offsetLeft + containerRef.current.scrollTo({ - left: child.offsetLeft, + left: targetLeft, behavior: prefersReducedMotion ? 'auto' : 'smooth' }) } } const scrollPrev = () => { - scrollTo(Math.max(activeIndex - 1, 0)) + const step = window.innerWidth >= 768 ? 2 : 1 + scrollTo(Math.max(activeIndex - step, 0)) } const scrollNext = () => { - scrollTo(Math.min(activeIndex + 1, items.length - 1)) + const step = window.innerWidth >= 768 ? 2 : 1 + scrollTo(Math.min(activeIndex + step, items.length - 1)) } if (!items || items.length === 0) return null + const desktopPages = Math.ceil(items.length / 2) + return (
@@ -117,7 +124,7 @@ export const TestimonialsCarousel: React.FC = ({ title, items })
- {/* Kropki nawigacji (Mobile + Desktop) */} -
+ {/* Kropki nawigacji (Mobile - pojedyncze karty) */} +
{items.map((_, index) => (
+ + {/* Kropki nawigacji (Desktop - grupowane po 2 karty) */} +
+ {Array.from({ length: desktopPages }).map((_, pageIndex) => { + const isActive = Math.floor(activeIndex / 2) === pageIndex + return ( +
)