From 76798e4704c6c5ef3f5628a8bb9963f80bf3f012 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Tue, 23 Jun 2026 13:32:43 +0200 Subject: [PATCH] refactor(ui): replace dragging carousel with centered grid layout --- components/blocks/ReferencesSlider.test.tsx | 9 +- components/blocks/ReferencesSlider.tsx | 119 ++++++-------------- 2 files changed, 39 insertions(+), 89 deletions(-) diff --git a/components/blocks/ReferencesSlider.test.tsx b/components/blocks/ReferencesSlider.test.tsx index 4a8cd039c..d18b97d14 100644 --- a/components/blocks/ReferencesSlider.test.tsx +++ b/components/blocks/ReferencesSlider.test.tsx @@ -51,14 +51,15 @@ describe('ReferencesSlider TDD', () => { expect(screen.getByText('Referenz Projekt Zwei')).toBeTruthy(); }); - it('renders each tile as a static block and NOT wrapped in a link', () => { + it('renders each tile as a link to the reference detail page', () => { render(); - - const links = screen.queryAllByTestId('reference-tile-link'); - expect(links).toHaveLength(0); const tiles = screen.getAllByTestId('reference-tile'); expect(tiles).toHaveLength(2); + + // Check if they have href attributes + expect(tiles[0].getAttribute('href')).toContain('/en/referenzen#referenz-projekt-eins'); + expect(tiles[1].getAttribute('href')).toContain('/en/referenzen#referenz-projekt-zwei'); }); }); diff --git a/components/blocks/ReferencesSlider.tsx b/components/blocks/ReferencesSlider.tsx index 547366146..45eddad5e 100644 --- a/components/blocks/ReferencesSlider.tsx +++ b/components/blocks/ReferencesSlider.tsx @@ -40,12 +40,6 @@ export function ReferencesSlider(props: ReferencesSliderProps) { const { data } = props; const references = props.references || []; - const containerRef = React.useRef(null); - const dragDistanceRef = React.useRef(0); - const startXRef = React.useRef(0); - const scrollLeftRef = React.useRef(0); - const isDraggingRef = React.useRef(false); - const [isDragging, setIsDragging] = React.useState(false); const badge = props.badge || data?.badge || t('badge'); const title = props.title || data?.title || t('title'); @@ -63,36 +57,6 @@ export function ReferencesSlider(props: ReferencesSliderProps) { '/assets/photos/DSC00010.JPG', ]; - const onMouseDown = (e: React.MouseEvent) => { - if (!containerRef.current) return; - setIsDragging(true); - isDraggingRef.current = true; - const startXVal = e.clientX - (containerRef.current.offsetLeft || 0); - startXRef.current = startXVal; - scrollLeftRef.current = containerRef.current.scrollLeft || 0; - dragDistanceRef.current = 0; - }; - - const onMouseLeave = () => { - setIsDragging(false); - isDraggingRef.current = false; - }; - - const onMouseUp = () => { - setIsDragging(false); - isDraggingRef.current = false; - }; - - const onMouseMove = (e: React.MouseEvent) => { - if (!isDraggingRef.current || !containerRef.current) return; - e.preventDefault(); - const x = e.clientX - (containerRef.current.offsetLeft || 0); - const walk = (x - startXRef.current) * 2; // Scroll-fast - containerRef.current.scrollLeft = scrollLeftRef.current - walk; - dragDistanceRef.current = Math.abs(x - startXRef.current); - }; - - return (
@@ -102,24 +66,13 @@ export function ReferencesSlider(props: ReferencesSliderProps) {

{badge}

{title}

-
+
{description}
-
-
-
- - {/* Carousel: breaks viewport edge on both sides but initial padding aligns with container */} -
+
+
{references.map((ref, i) => { const imgSrc = ref.image ? (typeof ref.image === 'string' ? ref.image : ref.image.url) @@ -128,51 +81,47 @@ export function ReferencesSlider(props: ReferencesSliderProps) { return ( { - if (dragDistanceRef.current > 5) { - e.preventDefault(); - } - }} - data-testid="reference-tile" - className="block relative select-none aspect-[16/10] bg-neutral-800 rounded-2xl overflow-hidden mb-5 border border-white/5 shadow-2xl cursor-pointer" - > - {ref.title} -
- - - -
- - {ref.category} - -

{ref.title}

-
- + href={`/${locale}/referenzen#${ref.slug}`} + data-testid="reference-tile" + className="block relative h-[250px] md:h-[300px] w-full rounded-2xl overflow-hidden shadow-xl shadow-black/20" + > + {ref.title} + +
+ + + +
+
+ {ref.category} +
+

+ {ref.title} +

+
+ ); })} - {/* Right padding spacer so last card doesn't clip at viewport edge */} -
-
+