新增getComponentName.js工具函数,新增Hero15组件
@ -1,4 +1,4 @@
|
||||
import Hero from "@/components/homes/home-15/Hero";
|
||||
import Hero15 from "@/components/homes/home-15/Hero15";
|
||||
import SwiperItems from "@/components/homes/home-15/SwiperItems";
|
||||
import React from "react";
|
||||
import { getSiteSettings } from "@/utils/data";
|
||||
@ -33,7 +33,7 @@ export default function Page() {
|
||||
<div className="">
|
||||
<>
|
||||
<section className="wrapper">
|
||||
<Hero />
|
||||
<Hero15 />
|
||||
</section>
|
||||
<section className="w-full xl:w-10/12 xl:mx-auto overflow-x-hidden">
|
||||
<SwiperItems />
|
||||
|
||||
124
components/homes/home-15/Hero15/UI.jsx
Normal file
@ -0,0 +1,124 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import ModalVideo from "@/components/common/ModalVideo";
|
||||
import Link from "next/link";
|
||||
import { Autoplay, Navigation, Pagination } from "swiper/modules";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
|
||||
export default function HeroUI({ data, showNavButtons = false }) {
|
||||
const [isOpen, setIsOpen] = useState("");
|
||||
|
||||
if (!data) return null;
|
||||
|
||||
// 处理items
|
||||
const items = data.items || [];
|
||||
// 处理图片
|
||||
const bgImages = [data.image, data.image_1, data.image_2].filter(Boolean);
|
||||
// 处理标题和副标题
|
||||
const titles = [data.title, ...(items.map(i => i.item_title))].filter(Boolean);
|
||||
const subtitles = [data.subtitle, ...(items.map(i => i.item_subtitle))].filter(Boolean);
|
||||
const descs = [data.description, ...(items.map(i => i.item_description))].filter(Boolean);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="swiper-container swiper-hero dots-over relative z-10">
|
||||
<Swiper
|
||||
className="swiper h-full"
|
||||
modules={[Navigation, Pagination, Autoplay]}
|
||||
pagination={{
|
||||
clickable: true,
|
||||
el: ".spd7",
|
||||
}}
|
||||
spaceBetween={0}
|
||||
speed={3000}
|
||||
navigation={showNavButtons ? {
|
||||
prevEl: ".snbp7",
|
||||
nextEl: ".snbn7",
|
||||
} : false}
|
||||
>
|
||||
{items.map((item, idx) => {
|
||||
let alignClass = "";
|
||||
switch ((item.content_align || "").toLowerCase()) {
|
||||
case "center":
|
||||
alignClass = "md:w-11/12 lg:w-8/12 xl:w-7/12 xxl:w-6/12 w-full !mx-auto text-center";
|
||||
break;
|
||||
case "right":
|
||||
alignClass = "md:w-10/12 lg:w-7/12 xl:w-6/12 w-full max-w-full text-center lg:text-right xl:text-right lg:!ml-[41.666667%] xl:!ml-[50%] xxl:!ml-[50%]";
|
||||
break;
|
||||
case "left":
|
||||
default:
|
||||
alignClass = "md:w-10/12 md:!ml-[8.33333333%] lg:w-7/12 lg:!ml-0 xl:w-6/12 xxl:w-5/12 w-full max-w-full text-center lg:text-left xl:text-left";
|
||||
break;
|
||||
}
|
||||
return (
|
||||
<SwiperSlide
|
||||
key={idx}
|
||||
className="swiper-slide max-h-full bg-overlay bg-overlay-400 bg-[#21262c] opacity-100 bg-image !bg-cover !bg-[center_center] !h-[750px] before:content-[''] before:block before:absolute before:z-[1] before:w-full before:h-full before:left-0 before:top-0 before:bg-[rgba(30,34,40,.4)]"
|
||||
style={{ backgroundImage: `url(${item.item_image || bgImages[idx] || bgImages[0] || "/assets/img/photos/bg7.jpg"})` }}
|
||||
>
|
||||
<div className="container !h-full">
|
||||
<div className="flex flex-wrap !h-full items-center">
|
||||
<div className={alignClass + " relative z-10"}>
|
||||
<h2 className="xl:!text-[2.8rem] !leading-[1.2] font-bold !text-[calc(1.405rem_+_1.86vw)] !mb-4 !text-white animate__animated animate__slideInDown animate__delay-1s">
|
||||
{item.item_title || data.title}
|
||||
</h2>
|
||||
<p className="lead text-[1.15rem] leading-normal !mb-7 !text-white animate__animated animate__slideInRight animate__delay-2s">
|
||||
{item.item_subtitle || data.subtitle}
|
||||
</p>
|
||||
<div className="animate__animated animate__slideInUp animate__delay-3s">
|
||||
{item.item_video_src ? (
|
||||
<a
|
||||
onClick={() => setIsOpen(item.item_video_src)}
|
||||
className="btn btn-circle btn-white btn-play ripple !mx-auto !mb-5 !relative z-[2] xl:!text-[2.3rem] !w-[3.5rem] !h-[3.5rem] !text-[calc(1.355rem_+_1.26vw)] hover:translate-y-0 inline-flex items-center justify-center leading-none p-0 !rounded-[100%] before:content-[''] before:block before:absolute before:opacity-80 before:animate-[ripple-1_2s_infinite_ease-in-out] before:z-[-1] before:rounded-[50%] before:inset-0 before:bg-[#ffffff] after:content-[''] after:block after:absolute after:opacity-60 after:animate-[ripple-2_2s_infinite_ease-in-out] after:z-[-1] after:rounded-[50%] before:inset-0 after:bg-[#ffffff]"
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<i className="icn-caret-right !ml-[0.15rem] !relative z-[2] before:content-['\\e900'] !text-[calc(1.355rem_+_1.26vw)]" />
|
||||
</a>
|
||||
) : (
|
||||
item.item_button_text && item.item_button_link && (
|
||||
item.item_button_link.startsWith("http") ? (
|
||||
<a
|
||||
href={item.item_button_link}
|
||||
className="btn btn-outline-white !text-white bg-[#ffffff] !border-white !border-[2px] hover:!text-[#343f52] hover:bg-[#ffffff] hover:border-white focus:shadow-[rgba(255,255,255,1)] active:!text-[#343f52] active:bg-[#ffffff] active:border-white disabled:text-white disabled:bg-transparent disabled:border-white !rounded-[50rem]"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{item.item_button_text}
|
||||
</a>
|
||||
) : (
|
||||
<Link
|
||||
href={item.item_button_link}
|
||||
className="btn btn-outline-white !text-white bg-[#ffffff] !border-white !border-[2px] hover:!text-[#343f52] hover:bg-[#ffffff] hover:border-white focus:shadow-[rgba(255,255,255,1)] active:!text-[#343f52] active:bg-[#ffffff] active:border-white disabled:text-white disabled:bg-transparent disabled:border-white !rounded-[50rem]"
|
||||
>
|
||||
{item.item_button_text}
|
||||
</Link>
|
||||
)
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
);
|
||||
})}
|
||||
</Swiper>
|
||||
<div className="swiper-controls">
|
||||
{showNavButtons && (
|
||||
<div className="swiper-navigation">
|
||||
<div className="swiper-button swiper-button-prev snbp7"></div>
|
||||
<div className="swiper-button swiper-button-next snbn7"></div>
|
||||
</div>
|
||||
)}
|
||||
<div className="swiper-pagination spd7"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ModalVideo
|
||||
isOpen={!!isOpen}
|
||||
setIsOpen={() => setIsOpen("")}
|
||||
src={isOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
16
components/homes/home-15/Hero15/index.jsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { getComponentName } from "@/utils/getComponentName";
|
||||
import { fetchComponentData } from "@/utils/data";
|
||||
import UI from "./UI";
|
||||
|
||||
const componentName = getComponentName(import.meta.url);
|
||||
|
||||
export default async function Component() {
|
||||
const result = await fetchComponentData(componentName);
|
||||
|
||||
if (result.error || !result.data) {
|
||||
if (result.error) console.error(`Failed to fetch ${componentName} data:`, result.error);
|
||||
return null;
|
||||
}
|
||||
|
||||
return <UI data={result.data} />;
|
||||
}
|
||||
BIN
public/files/4f1be9vdh1_c399d4a7.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/4f4dth9h8o_2f658f40.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/files/4f6h671vh8_2e9b0231.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/4f9koe2v5n_c478425b.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/4fc8nc4ldb_d6a1aa02.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
public/files/4ffcdr62c8_5ce711c5.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/files/4fimj0t7nu_b9f3fee8.png
Normal file
|
After Width: | Height: | Size: 698 KiB |
BIN
public/files/4fldpdggv0_05795d2c.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/files/4fo5hsu9j6_5a0c376b.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/4fqpfshkot_930c3d07.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
public/files/atrg7omggg_50271250.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/atv13e9hdg_9a160391.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/au2bm01ul0_28963fdc.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/files/au6d5h54r6_afea8ae4.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/files/auabk9ilft_99cda3c7.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
public/files/brou63ehu6_e4353faa.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
8
utils/getComponentName.js
Normal file
@ -0,0 +1,8 @@
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
export function getComponentName(metaUrl) {
|
||||
const __filename = fileURLToPath(metaUrl);
|
||||
const __dirname = path.dirname(__filename);
|
||||
return path.basename(__dirname);
|
||||
}
|
||||