mirror of
https://github.com/LiuYuYang01/ThriveX-Blog.git
synced 2026-09-03 06:24:24 +08:00
refactor(fishpond, tags): 引入 PageHeroHeader 和 PageHeroGrid 组件,优化页面布局
- 在 FishpondPage 和 TagsPageClient 中添加了 PageHeroHeader 和 PageHeroGrid 组件,提升页面结构和可读性。 - 更新了 FishpondPage 的背景样式,简化了布局。 - 调整了 VirtualizedTagList 的样式,确保一致的间距和视觉效果。
This commit is contained in:
@@ -13,7 +13,7 @@ import { dayFormat } from '@/utils';
|
||||
|
||||
// 引入图标
|
||||
import { HiOutlineClock, HiOutlineHashtag, HiOutlineArrowTopRightOnSquare } from 'react-icons/hi2';
|
||||
import { TbRipple } from 'react-icons/tb';
|
||||
import PageHeroHeader, { PageHeroGrid } from '@/components/PageHeroHeader';
|
||||
|
||||
// 瀑布流断点配置
|
||||
const breakpointColumnsObj = {
|
||||
@@ -75,17 +75,13 @@ export default function FishpondPage() {
|
||||
<title>🐟 鱼塘 | Rss Feed</title>
|
||||
<meta name="description" content="汇聚好友与订阅的动态鱼塘" />
|
||||
|
||||
<div className="min-h-screen bg-[linear-gradient(110deg,#fbfbfc_0%,#f7f8fa_58%,#fbfbfc_100%)] dark:bg-[linear-gradient(to_right,#232931_0%,#232931_100%)] pt-24 pb-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="w-full max-w-[1920px] mx-auto">
|
||||
<div className="relative mb-14 flex flex-col items-center select-none pt-6 md:pt-12">
|
||||
<div className="inline-flex items-center justify-center gap-3 mb-4">
|
||||
<TbRipple className="text-4xl text-blue-500 animate-pulse" />
|
||||
<h2 className="text-4xl md:text-5xl font-extrabold tracking-tight text-[#161a22] dark:text-slate-100">鱼 塘</h2>
|
||||
</div>
|
||||
<p className="text-[#788190] dark:text-slate-400 text-sm md:text-base">潜入信息的海洋,捕获最新鲜的动态</p>
|
||||
</div>
|
||||
<div className="relative min-h-screen bg-[linear-gradient(110deg,#fbfbfc_0%,#f7f8fa_58%,#fbfbfc_100%)] dark:bg-[linear-gradient(to_right,#232931_0%,#232931_100%)] pb-12 px-4 sm:px-6 lg:px-8">
|
||||
<PageHeroGrid />
|
||||
|
||||
<div className="mt-10">
|
||||
<div className="relative w-full max-w-[1920px] mx-auto">
|
||||
<PageHeroHeader title="鱼塘" subtitle="潜入信息的海洋,捕获最新鲜的动态" className="mb-8" />
|
||||
|
||||
<div className="relative z-10">
|
||||
{rssData && rssData.length > 0 ? (
|
||||
<Masonry breakpointCols={breakpointColumnsObj} className="flex w-auto -ml-5" columnClassName="pl-5 bg-clip-padding flex flex-col gap-5">
|
||||
{rssData.map((item, index) => {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Tag } from '@/types/app/tag';
|
||||
import TagCloudBackground from '@/app/tags/components/TagCloudBackground';
|
||||
import PageHeroHeader, { PageHeroGrid } from '@/components/PageHeroHeader';
|
||||
import VirtualizedTagList from './VirtualizedTagList';
|
||||
|
||||
interface TagsPageClientProps {
|
||||
@@ -16,11 +17,11 @@ export default function TagsPageClient({ tags }: TagsPageClientProps) {
|
||||
}, [tags]);
|
||||
|
||||
return (
|
||||
<div className="py-[50px] mt-[60px] min-h-screen relative hide_sliding">
|
||||
<h1 className="relative z-20 text-4xl font-bold text-center mb-5">标签墙</h1>
|
||||
<div className="relative min-h-screen hide_sliding">
|
||||
<PageHeroGrid />
|
||||
<PageHeroHeader title="标签墙" subtitle="拾取标签,发现更多感兴趣的内容" className="z-20" />
|
||||
|
||||
{/* 标签列表 */}
|
||||
<div className="relative z-20 w-11/12 mx-auto">
|
||||
<div className="relative z-20 w-11/12 mx-auto mt-4">
|
||||
<VirtualizedTagList tags={tags} initialBatchSize={30} batchSize={30} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ const VirtualizedTagList: React.FC<VirtualizedTagListProps> = ({
|
||||
className="w-full"
|
||||
>
|
||||
<div
|
||||
className="flex flex-wrap justify-center w-full py-10 px-0 sm:px-10"
|
||||
className="flex flex-wrap justify-center w-full pb-10 px-0 sm:px-10"
|
||||
style={{
|
||||
contain: 'layout', // 隔离布局影响
|
||||
}}
|
||||
|
||||
21
src/components/PageHeroHeader/hero.css
Normal file
21
src/components/PageHeroHeader/hero.css
Normal file
@@ -0,0 +1,21 @@
|
||||
@keyframes wall-shimmer {
|
||||
0%,
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes wall-float-dot {
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-14px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
57
src/components/PageHeroHeader/index.tsx
Normal file
57
src/components/PageHeroHeader/index.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
'use client';
|
||||
|
||||
import { ZCOOL_KuaiLe } from 'next/font/google';
|
||||
import './hero.css';
|
||||
|
||||
const zcoolKuaiLe = ZCOOL_KuaiLe({ weight: '400', subsets: ['latin'] });
|
||||
|
||||
const floatDots = [
|
||||
{ size: 'w-2 h-2', color: 'bg-rose-400/70', delay: '0s' },
|
||||
{ size: 'w-1.5 h-1.5', color: 'bg-amber-400/70', delay: '0.5s' },
|
||||
{ size: 'w-2.5 h-2.5', color: 'bg-violet-400/70', delay: '1s' },
|
||||
{ size: 'w-1.5 h-1.5', color: 'bg-cyan-400/70', delay: '1.5s' },
|
||||
{ size: 'w-2 h-2', color: 'bg-emerald-400/70', delay: '2s' },
|
||||
];
|
||||
|
||||
interface PageHeroHeaderProps {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function PageHeroGrid() {
|
||||
return (
|
||||
<div className="pointer-events-none fixed inset-0 overflow-hidden" aria-hidden="true">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(rgba(148,163,184,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(148,163,184,0.06)_1px,transparent_1px)] bg-size-[64px_64px]" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function PageHeroHeader({ title, subtitle, className = '' }: PageHeroHeaderProps) {
|
||||
return (
|
||||
<header className={`relative z-10 pt-20 pb-4 mt-10 text-center select-none ${className}`}>
|
||||
<div className="flex justify-center gap-3 mb-6">
|
||||
{floatDots.map((dot, i) => (
|
||||
<span
|
||||
key={i}
|
||||
className={`animate-[wall-float-dot_3s_ease-in-out_infinite] rounded-full ${dot.size} ${dot.color}`}
|
||||
style={{ animationDelay: dot.delay }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h1 className={`text-6xl sm:text-7xl font-bold tracking-tight mb-5 ${zcoolKuaiLe.className}`}>
|
||||
<span className="bg-size-[200%_auto] bg-linear-to-r from-amber-500 via-rose-500 to-violet-500 bg-clip-text text-transparent animate-[wall-shimmer_5s_ease_infinite] dark:from-amber-300 dark:via-rose-300 dark:to-violet-400">
|
||||
{title}
|
||||
</span>
|
||||
</h1>
|
||||
<p className="text-neutral-500 dark:text-neutral-400 text-base sm:text-lg tracking-[0.2em] font-light">{subtitle}</p>
|
||||
|
||||
<div className="mt-8 flex items-center justify-center gap-3">
|
||||
<div className="w-20 h-px bg-linear-to-r from-transparent to-neutral-300 dark:to-neutral-700" />
|
||||
<div className="w-2 h-2 rounded-full bg-amber-400/80 shadow-lg shadow-amber-400/20" />
|
||||
<div className="w-20 h-px bg-linear-to-l from-transparent to-neutral-300 dark:to-neutral-700" />
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user