training_data/apps/web/src/app/main/home/components/HeroSection.tsx

146 lines
4.9 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useRef, useCallback, useEffect } from "react";
import { Button, Carousel, Typography } from "antd";
import {
TeamOutlined,
BookOutlined,
StarOutlined,
ClockCircleOutlined,
LeftOutlined,
RightOutlined,
EyeOutlined,
} from "@ant-design/icons";
import type { CarouselRef } from "antd/es/carousel";
import { useAppConfig } from "@nice/client";
const { Title, Text } = Typography;
interface CarouselItem {
title: string;
desc: string;
image: string;
action: string;
color: string;
}
interface PlatformStat {
icon: React.ReactNode;
value: string;
label: string;
}
const carouselItems: CarouselItem[] = [
{
title: "探索编程世界",
desc: "从零开始学习编程,开启你的技术之旅",
image: "/images/banner1.jpg",
action: "立即开始",
color: "from-blue-600/90",
},
{
title: "人工智能课程",
desc: "掌握AI技术引领未来发展",
image: "/images/banner2.jpg",
action: "了解更多",
color: "from-purple-600/90",
},
];
const HeroSection = () => {
const carouselRef = useRef<CarouselRef>(null);
const { statistics, baseSetting } = useAppConfig();
const platformStats: PlatformStat[] = [
{ icon: <TeamOutlined />, value: "50,000+", label: "注册学员" },
{ icon: <BookOutlined />, value: "1,000+", label: "精品课程" },
// { icon: <StarOutlined />, value: '98%', label: '好评度' },
{ icon: <EyeOutlined />, value: "4552", label: "观看次数" },
];
const handlePrev = useCallback(() => {
carouselRef.current?.prev();
}, []);
const handleNext = useCallback(() => {
carouselRef.current?.next();
}, []);
const { slides } = useAppConfig()
useEffect(() => {
//slides.push(('https://s.cn.bing.net/th?id=OHR.GiantCuttlefish_ZH-CN0670915878_1920x1080.webp&qlt=50'))
//console.log(slides)
}, [])
return (
<section className="relative ">
<div className="group">
<Carousel
ref={carouselRef}
autoplay
effect="fade"
className="h-[600px] mb-24"
dots={{
className: "carousel-dots !bottom-32 !z-20",
}}>
{Array.isArray(slides)?
(slides.map((item, index) => (
<div key={index} className="relative h-[600px]">
<div
className="absolute inset-0 bg-cover bg-center transform transition-[transform,filter] duration-[2000ms] group-hover:scale-105 group-hover:brightness-110 will-change-[transform,filter]"
style={{
//backgroundImage: `url(https://s.cn.bing.net/th?id=OHR.GiantCuttlefish_ZH-CN0670915878_1920x1080.webp&qlt=50)`,
backgroundImage: `url(${item})`,
backfaceVisibility: "hidden",
}}
/>
{/* <div
className={`absolute inset-0 bg-gradient-to-r ${item.color} to-transparent opacity-90 mix-blend-overlay transition-opacity duration-500`}
/> */}
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
{/* Content Container */}
<div className="relative h-full max-w-7xl mx-auto px-6 lg:px-8"></div>
</div>
))
) : (
<div></div>
)}
</Carousel>
{/* Navigation Buttons */}
<button
onClick={handlePrev}
className="absolute left-4 md:left-8 top-1/2 -translate-y-1/2 z-10 opacity-0 group-hover:opacity-100 transition-all duration-300 bg-black/20 hover:bg-black/30 w-12 h-12 flex items-center justify-center rounded-full transform hover:scale-110 hover:shadow-lg"
aria-label="Previous slide">
<LeftOutlined className="text-white text-xl" />
</button>
<button
onClick={handleNext}
className="absolute right-4 md:right-8 top-1/2 -translate-y-1/2 z-10 opacity-0 group-hover:opacity-100 transition-all duration-300 bg-black/20 hover:bg-black/30 w-12 h-12 flex items-center justify-center rounded-full transform hover:scale-110 hover:shadow-lg"
aria-label="Next slide">
<RightOutlined className="text-white text-xl" />
</button>
</div>
{/* Stats Container */}
<div className="absolute -bottom-24 left-1/2 -translate-x-1/2 w-1/2 max-w-6xl px-4">
<div className="rounded-2xl grid grid-cols-2 md:grid-cols-3 gap-4 md:gap-8 p-6 md:p-8 bg-white border shadow-xl hover:shadow-2xl transition-shadow duration-500 will-change-[transform,box-shadow]">
{platformStats.map((stat, index) => (
<div
key={index}
className="text-center transform hover:-translate-y-1 hover:scale-105 transition-transform duration-300 ease-out">
<div className="inline-flex items-center justify-center w-16 h-16 mb-4 rounded-full bg-primary-50 text-primary-600 text-3xl transition-colors duration-300 group-hover:text-primary-700">
{stat.icon}
</div>
<div className="text-2xl font-bold bg-gradient-to-r from-gray-800 to-gray-600 bg-clip-text text-transparent mb-1.5">
{stat.value}
</div>
<div className="text-gray-600 font-medium">
{stat.label}
</div>
</div>
))}
</div>
</div>
</section>
);
};
export default HeroSection;