134 lines
4.9 KiB
TypeScript
134 lines
4.9 KiB
TypeScript
import Banner from "@/components/Banner";
|
|
import YearPicker from "@/components/YearPicker";
|
|
import styles from "./History.module.css";
|
|
import { useState, useRef, useLayoutEffect } from "react";
|
|
|
|
type TimelineItem = { year: number; description: string };
|
|
|
|
const TIMELINE_DATA: TimelineItem[] = [
|
|
{ year: 2025, description: "银泰集团持续深化战略布局,推动高质量发展。" },
|
|
{ year: 2024, description: "银泰集团创新发展模式,拓展业务新领域。" },
|
|
{ year: 2023, description: "银泰集团核心业务稳健增长,品牌影响力持续提升。" },
|
|
{ year: 2022, description: "银泰集团深化数字化转型,提升运营效率。" },
|
|
{ year: 2018, description: "银泰集团推进战略转型升级,开启新篇章。" },
|
|
{ year: 2016, description: "银泰集团拓展多元化业务,夯实发展基础。" },
|
|
{ year: 2015, description: "银泰集团完善产业布局,增强核心竞争力。" },
|
|
{ year: 2014, description: "银泰集团加速全国化扩张,品牌影响力扩大。" },
|
|
{ year: 2013, description: "银泰集团稳健发展,主营业务持续向好。" },
|
|
{ year: 2010, description: "银泰集团抓住市场机遇,实现跨越式发展。" },
|
|
{ year: 2009, description: "银泰集团应对金融危机,保持稳健经营。" },
|
|
{ year: 2008, description: "银泰集团完善管理体系,提升运营水平。" },
|
|
{ year: 2007, description: "银泰集团上市,开启资本化发展新征程。" },
|
|
{ year: 1998, description: "银泰集团快速成长,确立行业领先地位。" },
|
|
{ year: 1997, description: "银泰集团成立,迈出创业第一步。" },
|
|
];
|
|
|
|
export default function AboutHistory() {
|
|
const [year, setYear] = useState<number | null>(null);
|
|
|
|
const handleYearChange = (year: number | null) => {
|
|
setYear(year);
|
|
// 滚动到对应的年份
|
|
const yearEl = document.querySelector(`#year-${year}`);
|
|
if (yearEl) {
|
|
yearEl.scrollIntoView({ behavior: "smooth" });
|
|
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Banner title="发展历程" desc="银泰集团的发展历程" showBreadcrumb={true} backgroundImage={'/images/bg-overview.png'}></Banner>
|
|
|
|
<section className={styles.section}>
|
|
<div className={styles.headRow}>
|
|
<YearPicker placeholder="年份" value={year} onChange={handleYearChange} />
|
|
</div>
|
|
<HistoryTimeline data={TIMELINE_DATA} selectedYear={year} onYearChange={setYear} />
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
type HistoryTimelineProps = {
|
|
data: TimelineItem[];
|
|
selectedYear: number | null;
|
|
onYearChange: (year: number | null) => void;
|
|
};
|
|
|
|
function TimelineItemRow({
|
|
item,
|
|
index,
|
|
isSelected,
|
|
onMouseEnter,
|
|
}: {
|
|
item: TimelineItem;
|
|
index: number;
|
|
isSelected: boolean;
|
|
onMouseEnter: () => void;
|
|
}) {
|
|
const isRight = index % 2 === 0;
|
|
const contentSideRef = useRef<HTMLDivElement>(null);
|
|
const dotLineRef = useRef<HTMLDivElement>(null);
|
|
|
|
useLayoutEffect(() => {
|
|
const contentEl = contentSideRef.current;
|
|
if (!contentEl) return;
|
|
const updateHeight = () => {
|
|
if (!contentSideRef.current || !dotLineRef.current || !isSelected) return;
|
|
dotLineRef.current.style.height = `${contentSideRef.current.offsetHeight}px`;
|
|
};
|
|
updateHeight();
|
|
const observer = new ResizeObserver(updateHeight);
|
|
observer.observe(contentEl);
|
|
return () => observer.disconnect();
|
|
}, [isSelected]);
|
|
|
|
return (
|
|
<div
|
|
className={`${styles.timelineItem} ${isRight ? styles.right : styles.left}`}
|
|
id={`year-${item.year}`}
|
|
>
|
|
<div ref={!isRight ? contentSideRef : undefined} className={styles.side}>
|
|
{!isRight && (
|
|
<div onMouseEnter={onMouseEnter}>
|
|
<span className={styles.year}>{item.year}</span>
|
|
<p className={styles.desc}>{item.description}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className={`${styles.dotWrapper} ${isSelected ? styles.selected : ""}`}>
|
|
<div className={styles.dot} />
|
|
{isSelected && <div ref={dotLineRef} className={styles.dotLine} />}
|
|
</div>
|
|
<div ref={isRight ? contentSideRef : undefined} className={styles.side}>
|
|
{isRight && (
|
|
<div onMouseEnter={onMouseEnter}>
|
|
<span className={styles.year}>{item.year}</span>
|
|
<p className={styles.desc}>{item.description}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function HistoryTimeline({ data, selectedYear, onYearChange }: HistoryTimelineProps) {
|
|
return (
|
|
<div className={styles.timelineWrapper}>
|
|
<div className={styles.timelineLine} />
|
|
<div className={styles.timelineContent}>
|
|
{data.map((item, index) => (
|
|
<TimelineItemRow
|
|
key={item.year}
|
|
item={item}
|
|
index={index}
|
|
isSelected={selectedYear === item.year}
|
|
onMouseEnter={() => onYearChange(item.year)}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|