Merged in feat/SW-1443-card-gallery-destination-overview (pull request #1362)

feat(SW-1443): added cardGallery block to destination overview page instead of carousel functionality

* feat(SW-1443): added cardGallery block to destination overview page instead of carousel functionality


Approved-by: Fredrik Thorsson
This commit is contained in:
Erik Tiekstra
2025-02-18 14:42:36 +00:00
parent f14eb05262
commit 2781a41110
16 changed files with 337 additions and 102 deletions

View File

@@ -0,0 +1,25 @@
.cardsList {
list-style: none;
display: none;
gap: var(--Spacing-x4) var(--Spacing-x1);
}
.navigationButton {
top: 30%;
}
@media screen and (min-width: 768px) {
.carousel {
display: none;
}
.cardsList {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (min-width: 1024px) {
.cardsList {
grid-template-columns: repeat(3, 1fr);
}
}

View File

@@ -0,0 +1,67 @@
"use client"
import { useState } from "react"
import { Carousel } from "@/components/Carousel"
import ContentCard from "@/components/ContentCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import TabFilters from "@/components/TabFilters"
import styles from "./cardGallery.module.css"
import type { CardGalleryProps } from "@/types/components/blocks/cardGallery"
export default function CardGallery({ card_gallery }: CardGalleryProps) {
const { heading, defaultFilter, filterCategories, cards, link } = card_gallery
const [activeFilter, setActiveFilter] = useState(defaultFilter)
const filteredCards = cards.filter((card) => card.filterId === activeFilter)
return (
<SectionContainer>
<SectionHeader title={heading} link={link} />
{filterCategories.length > 0 && activeFilter && (
<TabFilters
categories={filterCategories}
selectedFilter={activeFilter}
onFilterSelect={setActiveFilter}
/>
)}
<ul className={styles.cardsList}>
{filteredCards.map((card, index) => (
<li key={`${card.heading}-${index}`}>
<ContentCard
heading={card.heading}
image={card.image}
bodyText={card.bodyText}
promoText={card.promoText}
link={card.link}
/>
</li>
))}
</ul>
<Carousel className={styles.carousel}>
<Carousel.Content>
{filteredCards.map((card, index) => (
<Carousel.Item key={`${card.heading}-${index}`}>
<ContentCard
heading={card.heading}
image={card.image}
bodyText={card.bodyText}
promoText={card.promoText}
link={card.link}
/>
</Carousel.Item>
))}
</Carousel.Content>
<Carousel.Previous className={styles.navigationButton} />
<Carousel.Next className={styles.navigationButton} />
<Carousel.Dots />
</Carousel>
<SectionLink link={link} variant="mobile" />
</SectionContainer>
)
}

View File

@@ -7,8 +7,7 @@ import ContentCard from "@/components/ContentCard"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import Filters from "./Filters"
import TabFilters from "@/components/TabFilters"
import styles from "./carouselCards.module.css"
@@ -43,7 +42,7 @@ export default function CarouselCards({ carousel_cards }: CarouselCardsProps) {
link={link}
/>
{filterCategories.length > 0 && activeFilter && (
<Filters
<TabFilters
categories={filterCategories}
selectedFilter={activeFilter}
onFilterSelect={setActiveFilter}

View File

@@ -9,6 +9,7 @@ import UspGrid from "@/components/Blocks/UspGrid"
import JsonToHtml from "@/components/JsonToHtml"
import AccordionSection from "./Accordion"
import CardGallery from "./CardGallery"
import FullWidthCampaign from "./FullWidthCampaign"
import HotelListing from "./HotelListing"
import JoinScandicFriends from "./JoinScandicFriends"
@@ -61,6 +62,13 @@ export default function Blocks({ blocks }: BlocksProps) {
key={`${block.carousel_cards.heading}-${idx}`}
/>
)
case BlocksEnums.block.CardGallery:
return (
<CardGallery
card_gallery={block.card_gallery}
key={`${block.card_gallery.heading}-${idx}`}
/>
)
case BlocksEnums.block.HotelListing:
const { heading, contentType, locationFilter, hotelsToInclude } =
block.hotel_listing

View File

@@ -1,20 +1,26 @@
"use client"
import styles from "./filters.module.css"
import styles from "./tabFilters.module.css"
import type { CardGalleryFilter } from "@/types/enums/cardGallery"
import type { CarouselCardFilter } from "@/types/enums/carouselCards"
interface FiltersProps {
categories: Array<{ identifier: CarouselCardFilter; label: string }>
selectedFilter: CarouselCardFilter
onFilterSelect: (filter: CarouselCardFilter) => void
interface Filter {
identifier: CarouselCardFilter | CardGalleryFilter
label: string
}
export default function Filters({
interface TabFiltersProps {
categories: Array<Filter>
selectedFilter: Filter["identifier"]
onFilterSelect: (filter: Filter["identifier"]) => void
}
export default function TabFilters({
categories,
selectedFilter,
onFilterSelect,
}: FiltersProps) {
}: TabFiltersProps) {
return (
<div className={styles.container}>
{categories.map((category) => (