Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useState } from 'react'

import { GalleryImage } from './GalleryImage'
import { GalleryImage, NoImages } from './GalleryImage'
import { GalleryModal } from './GalleryModal'

type GalleryGridProps = {
Expand All @@ -12,10 +12,15 @@ type GalleryGridProps = {
export function GalleryGrid({ images }: GalleryGridProps) {
const [selectedIndex, setSelectedIndex] = useState<number | null>(null)

if (images.length === 0) {
return <NoImages />
}

return (
<>
<div
className="grid grid-cols-2 justify-items-center md:grid-cols-3 lg:grid-cols-4"
data-testid="gallery-grid"
className="grid justify-items-center sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4"
style={{ gap: 'clamp(0.5rem, 1.5vw, 1.5rem)' }}
>
{images.map((image, index) => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Image from 'next/image'

export const NO_IMAGES_EMPTY_STATE_COPY =
'There are no images available at this moment.'

type GalleryImageProps = {
src: string
alt: string
Expand All @@ -25,8 +28,11 @@ export function GalleryImage({ src, alt, onClick }: GalleryImageProps) {

export function NoImages() {
return (
<div className="flex h-full w-full items-center justify-center text-white">
There are no images available at this moment.
<div
data-testid="gallery-empty-state"
className="flex h-full w-full items-center justify-center text-white"
>
{NO_IMAGES_EMPTY_STATE_COPY}
</div>
)
}
59 changes: 59 additions & 0 deletions src/app/(frontend)/gallery/tests/GalleryGrid.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { render, screen } from '@testing-library/react'
import { describe, expect, it } from 'vitest'

import { GalleryGrid } from '../_components/gallery-images/GalleryGrid'
import { NO_IMAGES_EMPTY_STATE_COPY } from '../_components/gallery-images/GalleryImage'

describe('GalleryGrid', () => {
it('renders the correct number of GalleryImage children for a given images prop', () => {
const images = [
{ src: '/image1.jpg', alt: 'Image 1' },
{ src: '/image2.jpg', alt: 'Image 2' },
{ src: '/image3.jpg', alt: 'Image 3' },
]

render(<GalleryGrid images={images} />)

const galleryImages = screen.getAllByRole('img')
expect(galleryImages).toHaveLength(images.length)
})

it('renders an empty state when images={[]}', () => {
render(<GalleryGrid images={[]} />)

expect(screen.getByTestId('gallery-empty-state')).not.toBeNull()
})
Comment thread
vvd61 marked this conversation as resolved.

it('renders the empty-state copy', () => {
render(<GalleryGrid images={[]} />)

expect(screen.getByText(NO_IMAGES_EMPTY_STATE_COPY)).not.toBeNull()
})

it('does not render the empty state when images are present', () => {
const images = [
{ src: '/image1.jpg', alt: 'Image 1' },
{ src: '/image2.jpg', alt: 'Image 2' },
]

render(<GalleryGrid images={images} />)

const noImagesText = screen.queryByTestId('gallery-empty-state')
expect(noImagesText).toBeNull()
})
Comment thread
vvd61 marked this conversation as resolved.
it(' has the expected responsive Tailwind class names', () => {
const images = [
{ src: '/image1.jpg', alt: 'Image 1' },
{ src: '/image2.jpg', alt: 'Image 2' },
]
Comment thread
vvd61 marked this conversation as resolved.

render(<GalleryGrid images={images} />)

const gridContainer = screen.getByTestId('gallery-grid')
expect(gridContainer.className).toContain('grid')
expect(gridContainer.className).toContain('justify-items-center')
expect(gridContainer.className).toContain('sm:grid-cols-2')
expect(gridContainer.className).toContain('md:grid-cols-3')
expect(gridContainer.className).toContain('lg:grid-cols-4')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`GalleryGrid > matches the snapshot 1`] = `
<DocumentFragment>
<div
class="grid justify-items-center sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4"
data-testid="gallery-grid"
style="gap: clamp(0.5rem, 1.5vw, 1.5rem);"
>
<div
class="aspect-square w-full overflow-hidden"
>
<img
alt="Image 1"
class="h-full w-full object-cover"
src="image1.jpg"
/>
</div>
<div
class="aspect-square w-full overflow-hidden"
>
<img
alt="Image 2"
class="h-full w-full object-cover"
src="image2.jpg"
/>
</div>
</div>
</DocumentFragment>
`;
Loading