Skip to content
Snippets Groups Projects
Hero.tsx 9.41 KiB
Newer Older
Toavina's avatar
Toavina committed
import React from "react"
Julien MARGAIL's avatar
Julien MARGAIL committed
import {
    Button,
    Card,
    Carousel,
    Search,
} from "@onegeo-suite/gatsby-theme-onegeo"
import Image from "./core/Image"
import { twMerge } from "tailwind-merge"

Julien MARGAIL's avatar
Julien MARGAIL committed
import { merge } from "../utils"

interface Service {
    name: string
    description: string
    image: string
    url: string
interface Action {
    name: string
    url: string
interface Bg {
    src: string
}
interface Props {
    title?: string
    subtitle?: string
    content?: string
    action?: Action
    services?: Array<Service>
    bgImage?: Array<Bg>
}

const Hero = (props: Props) => {
Toavina's avatar
Toavina committed
    // Data structure (default value)
    const {
        title = "Onegeo Suite Portal",
Toavina's avatar
Toavina committed
        subtitle = "Hub géospatial collaboratif",
        content = "Solution Open Source sur-mesure pour communiquer et valoriser les données disponibles sur votre territoire ou vos infrastructures.",
        action = {},
        services = [],
        bgImage = [
            {
                src: "https://picsum.photos/1920/600?random=1",
                src: "https://picsum.photos/1920/600?random=2",
                src: "https://picsum.photos/1920/600?random=3",
Toavina's avatar
Toavina committed
    } = props
    const options = props.options ?? {}
    const oClass = options.class || {}
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
    let imageFondList, imageFond

    if (bgImage.length > 1) {
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        imageFondList = bgImage
        imageFond = [
            imageFondList.map((image: any) => {
                return image
            }),
        ]
    } else {
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
        imageFond = bgImage![0]
    }

    const layoutClass = {
        xs: {
            main: "h-xl",
            image: "h-xl",
            services: "-bottom-12",
        },
        base: {
            main: "h-2xl",
            image: "h-2xl",
            services: "-bottom-12",
        },
        xl: {
            main: "h-3xl",
            image: "h-3xl",
            services: "bottom-12",
        },
    }

    const lClass = layoutClass[options.size || "base"] || layoutClass["base"]
    const layout = options.layout || "card"

Toavina's avatar
Toavina committed
    return (
Julien MARGAIL's avatar
Julien MARGAIL committed
        <div
            className={twMerge(
                "relative z-0 mb-20 flex flex-col",
                lClass.main,
                oClass.main
            )}
Julien MARGAIL's avatar
Julien MARGAIL committed
            {options.search !== false && (
                <Search
                    options={merge(
                        {
                            class: {
                                main: "z-50 absolute w-full md:mt-8 ",
                                combobox:
                                    "md:rounded-md md:shadow-2xl max-w-3xl md:p-2",
                                input: "md:text-xl md:pl-14",
                                icon: "md:w-6 md:h-6",
                            },
                        },
                        options?.search
                    )}
Manoa Harinjo's avatar
Manoa Harinjo committed
                    {...options?.search}
Julien MARGAIL's avatar
Julien MARGAIL committed
                />
            )}

Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
            {bgImage!.length > 1 && (
                <Carousel
Toavina Rasoatamindrainy's avatar
Toavina Rasoatamindrainy committed
                    images={imageFond[0]}
                    animation="fade"
                    delay={3000}
                    {...options.carousel}
            {bgImage!.length === 1 && (
                <Image
                    image={bgImage[0].src}
                    className={twMerge("w-full", lClass.image, oClass.main)}
                    {...options.image}
            <div
                className={twMerge(
                    "absolute top-0 z-10 h-full w-full bg-gradient-to-r from-slate-500 opacity-80",
                    oClass.mask
                )}
            ></div>
                <div
                    className={twMerge(
                        "absolute top-0 z-20 mb-5 w-full text-center",
                        oClass.body
                    )}
                >
                    <div
                        className={twMerge(
                            "mx-auto mt-28 max-w-4xl",
                            oClass.bodydiv
                        )}
                    >
                        <h1
                            className={twMerge(
                                "text-primary-content mb-5 text-3xl font-extrabold tracking-tight lg:text-6xl",
                                oClass.title
                            )}
                        >
                            <div
                                className={twMerge(
                                    "text-secondary mt-2",
                                    oClass.subtitle
                                )}
                            >
                                {subtitle}
                            </div>
                        <p className={twMerge("mb-5", oClass.content)}>
                            {content}
                        </p>
                        {action && action.name !== "" ? (
                            <Button
                                className={twMerge(
                                    "btn-primary text-primary-content ",
                                    oClass.action
                                )}
Toavina's avatar
Toavina committed
                </div>
            ) : (
                <></>
            )}
            {layout === "card" ? (
                <div
                    className={twMerge(
                        "absolute z-10 flex w-full flex-row flex-wrap justify-center gap-6",
                        lClass.services,
                        oClass.services
                    )}
                >
                    {services &&
                        services.map((service, idx) => {
                            return (
                                <Card
                                    key={idx}
                                    layout="left"
                                    size="xs"
                                    {...service}
                                    options={merge(
                                        {
                                            class: {
                                                main: "w-96",
                                                body: "place-content-center",
                                                figure: "basis-20",
                                                image: "m-auto h-16",
                                                imageComponent:
                                                    "object-scale-down",
                                            },
                                        },
                                        merge(options?.card, service?.options)
                                    )}
                                />
                            )
                        })}
                </div>
            ) : (
                <div
                    className={twMerge(
                        "absolute z-10 grid h-full w-full grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
                        oClass.services
                    )}
                >
                    {services &&
                        services.map((service, idx) => {
                            return (
                                <Card
                                    key={idx}
                                    layout="top"
                                    size="full"
                                    anime={false}
                                    {...service}
                                    options={merge(
                                        {
                                            class: {
                                                main: "card-side sm:flex-col shadow-none bg-transparent opacity-90 sm:pt-10 lg:pt-40 group/card transition duration-200 ease-out hover:bg-base-100 ",
                                                body: "self-center text-base-100 group-hover/card:text-base-content lg:transition lg:duration-200 ease-in-out lg:group-hover/card:-translate-y-6",
                                                figure: "lg:transition lg:duration-200 ease-in-out lg:group-hover/card:-translate-y-6",
                                                image: "m-auto w-40 h-24 md:h-32 lg:h-40 ",
                                                imageComponent:
                                                    "object-scale-down",
                                                title: "sm:justify-center text-xl lg:text-2xl",
                                                description:
                                                    " hidden lg:block text-xl text-center opacity-0 lg:transition lg:duration-200 ease-out lg:group-hover/card:opacity-100",
                                                __for_inline_svg:
                                                    "h-full w-full fill-slate-50 group-hover/card:fill-sky-700",
                                            },
                                        },
                                        merge(options?.card, service?.options)
                                    )}
                                />
                            )
                        })}
                </div>
            )}
Toavina's avatar
Toavina committed
export default Hero