update(VolCard): 样式

mack-mac
mackt 7 months ago
parent 123f7465e3
commit 6b1e8aff1c

@ -10,5 +10,5 @@
width: 60px; width: 60px;
height: 3px; height: 3px;
margin: 12px auto 0; margin: 12px auto 0;
background-color: rgba(0, 0, 0, 0.95); background-color: #c43737;
} }

@ -2,7 +2,7 @@
import Link from 'next/link'; import Link from 'next/link';
import { notFound } from 'next/navigation'; import { notFound } from 'next/navigation';
import { JournalCard, SongCardList, JournalRecommendList, Comment, ButtonCollect } from '@/components'; import { SongCardList, JournalRecommendList, Comment, ButtonCollect, VolDetailCoverCard } from '@/components';
import { apiGetJournalInfoById, apiGetSongsByJournalNo, apiGetJournalRecommendById } from '@/services'; import { apiGetJournalInfoById, apiGetSongsByJournalNo, apiGetJournalRecommendById } from '@/services';
export async function generateMetadata({ params: { journalId } }: { params: { journalId: string } }) { export async function generateMetadata({ params: { journalId } }: { params: { journalId: string } }) {
@ -28,7 +28,7 @@ export default async function JournalDetail({ params: { journalId } }: { params:
<main className="w-[1200px] mx-auto flex flex-row justify-between items-left pt-[145px] pb-[104px] "> <main className="w-[1200px] mx-auto flex flex-row justify-between items-left pt-[145px] pb-[104px] ">
<div className="w-[712px]"> <div className="w-[712px]">
{/* 封面 */} {/* 封面 */}
<JournalCard image={journalInfo.image} journalNo={journalInfo.journalNo} /> <VolDetailCoverCard journalInfo={journalInfo} />
{/* 期刊号 & 标签 */} {/* 期刊号 & 标签 */}
<div className="flex flex-row items-center gap-[9px] w-full h-auto mt-[30px]"> <div className="flex flex-row items-center gap-[9px] w-full h-auto mt-[30px]">
<p className="text-[rgba(0,0,0,0.7)] text-[14px] leading-[19.6px]">{`VOL·${journalInfo?.journalNo}`}</p> <p className="text-[rgba(0,0,0,0.7)] text-[14px] leading-[19.6px]">{`VOL·${journalInfo?.journalNo}`}</p>

@ -1,6 +1,7 @@
import Image from 'next/image'; import Image from 'next/image';
import styles from './index.module.css'; import styles from './index.module.css';
import { Children } from 'react';
function VolNo({ text }: { text: string }) { function VolNo({ text }: { text: string }) {
return ( return (
@ -14,27 +15,37 @@ function VolNo({ text }: { text: string }) {
); );
} }
export default function JournalCard({ image, title, journalNo }: { image: string; title?: string; journalNo: string }) { export default function JournalCard({
image,
title,
journalNo,
showPlay = false,
children,
className,
}: {
image: string;
title?: string;
journalNo: string;
showPlay?: boolean;
children?: React.ReactNode;
className?: string;
}) {
return ( return (
/* banner container */ /* banner container */
<div className={`relative w-[712px] h-[420px] rounded-[6px] overflow-hidden bg-[url(${image})] group`}> <div className={`relative w-[712px] h-[420px] rounded-[6px] overflow-hidden bg-[url(${image})] group ${className}`}>
{/* 左上方 角标 */} {/* 左上方 角标 */}
<VolNo text={journalNo} /> <VolNo text={journalNo} />
{/* banner */} {/* banner */}
<Image <Image width={712} height={420} src={image} unoptimized alt={`Vol${journalNo}`} className="absolute bottom-0" />
width={712}
height={420}
src={image}
unoptimized
alt={`Vol${journalNo}`}
className="absolute bottom-0 cursor-pointer"
/>
{/* 标题 */} {/* 标题 */}
<div className={`absolute bottom-0 w-full h-[126px] ${styles.title_background}`}> <div className={`absolute bottom-0 w-full h-[126px] ${styles.title_background}`}>
<p className="absolute bottom-[23px] left-[23px] text-[#fff] text-[24px] leading-[33.6px]">{title}</p> <p className="absolute bottom-[23px] left-[23px] text-[#fff] text-[24px] leading-[33.6px]">{title}</p>
</div> </div>
{/* 遮罩层 */} {/* 播放按钮 */}
{showPlay && (
<div className="absolute bottom-[24px] right-[24px] w-[46px] h-[32px] bg-[url(/img/icon/play-journal-card.svg)] bg-no-repeat z-2 opacity-0 group-hover:opacity-100 transition-opacity-500" /> <div className="absolute bottom-[24px] right-[24px] w-[46px] h-[32px] bg-[url(/img/icon/play-journal-card.svg)] bg-no-repeat z-2 opacity-0 group-hover:opacity-100 transition-opacity-500" />
)}
{children}
</div> </div>
); );
} }

@ -0,0 +1,16 @@
import VolPlayButton from '../VolPlayButton';
import { JournalCard } from '@/components';
export default function CoverCard({ journalInfo }: { journalInfo: JournalInfo }) {
const { image, journalNo } = journalInfo;
return (
<div className="relative">
<JournalCard image={image} journalNo={journalNo}>
{/* 播放/暂停 */}
</JournalCard>
<VolPlayButton className="absolute right-[30px] bottom-[-26px] z-2" no={journalNo} />
</div>
);
}

@ -16,7 +16,7 @@ export default function JournalItem({
return ( return (
<div className="flex flex-col w-[712px] rounded-[6px] bg-base "> <div className="flex flex-col w-[712px] rounded-[6px] bg-base ">
<Link href={`/vol/${journalNo}`}> <Link href={`/vol/${journalNo}`}>
<JournalCard image={image} title={title} journalNo={journalNo} /> <JournalCard showPlay image={image} title={title} journalNo={journalNo} className="cursor-pointer" />
</Link> </Link>
{/* 摘要 */} {/* 摘要 */}
<p className="w-full mt-[15px] mb-[12px] text-[17px] leading-[23.8px] text-base cursor-pointer overflow-hidden whitespace-nowrap truncate"> <p className="w-full mt-[15px] mb-[12px] text-[17px] leading-[23.8px] text-base cursor-pointer overflow-hidden whitespace-nowrap truncate">

@ -0,0 +1,28 @@
import { JournalCard, PlayerButton } from '@/components';
export default function CoverCard({
img,
no,
playStatus,
onPlay,
}: {
img: string;
no: string;
playStatus: boolean;
onPlay: () => void;
}) {
return (
<JournalCard image={img} journalNo={no}>
<JournalCard image={img} journalNo={no}>
{/* 播放/暂停 */}
<PlayerButton
size={54}
img={playStatus ? '/img/audio-player/pause.svg' : '/img/audio-player/play.svg'}
text={playStatus ? '暂停' : '播放'}
onClick={onPlay}
className="mx-[31.5px]"
/>
</JournalCard>
</JournalCard>
);
}

@ -0,0 +1,31 @@
'use client';
import { useShallow } from 'zustand/react/shallow';
import { PlayerButton } from '@/components';
import useAudioStore from '@/store/audio';
export default function VolPlayButton({ no, className }: { no: string; className: string }) {
const { playState, setPlayState } = useAudioStore(
useShallow((state) => {
return {
playState: state.playState,
setPlayState: state.setPlayState,
};
}),
);
const handlePlay = () => {
setPlayState(!playState);
};
return (
<PlayerButton
size={60}
img={playState ? '/img/audio-player/pause.svg' : '/img/audio-player/play.svg'}
text={playState ? '暂停' : '播放'}
onClick={handlePlay}
className={className}
/>
);
}

@ -26,7 +26,7 @@ export default function JournalItem({
}: Props) { }: Props) {
return ( return (
<div <div
className="flex flex-row items-center justify-between w-full h-[72px] my-[3px] py-[12px] px-[18px] rounded-[3px] hover:bg-[#f2f3f7] group cursor-pointer" className="flex flex-row items-center justify-between w-[calc(100%_+_18px)] h-[72px] ml-[-18px] my-[3px] py-[12px] px-[18px] rounded-[3px] hover:bg-[#f2f3f7] group cursor-pointer"
onClick={() => onPlay(id)} onClick={() => onPlay(id)}
> >
{/* left */} {/* left */}

@ -21,6 +21,8 @@ export { default as JournalCard } from './Journal/JournalCard';
export { default as JournalList } from './Journal/JournalList'; export { default as JournalList } from './Journal/JournalList';
export { default as JournalRecommendCard } from './Journal/JournalRecommendCard'; export { default as JournalRecommendCard } from './Journal/JournalRecommendCard';
export { default as JournalRecommendList } from './Journal/JournalRecommendList'; export { default as JournalRecommendList } from './Journal/JournalRecommendList';
export { default as VolDetailCoverCard } from './Journal/JournalDetail/VolDetailCoverCard';
export { default as VolListCoverCard } from './Journal/JournalList/VolListCoverCard';
// Common // Common
export { default as Input } from './common/Input'; export { default as Input } from './common/Input';

Loading…
Cancel
Save