hts/apps/blogai/components/article/card.tsx

296 lines
8.2 KiB
TypeScript

import { useState } from "react";
import { ArticleData, QAData, TagItem } from "./article";
import { useRouter } from "next/navigation";
import { Portal } from '@radix-ui/react-portal';
import Image from 'next/image';
import aImage from '../../components/images/a.png'
import qImage from '../../components/images/q.png';
import userImage from '../../components/images/user.png';
import React from "react";
import { FadeIn, FadeInStagger } from "../landing/fade-in";
import { useTranslation } from "react-i18next";
import { truncateString } from "@/lib/utils";
interface CardProps {
image: string;
title: string;
time: string;
summary: string;
}
export const Card: React.FC<ArticleData> = (articleData) => {
const [open, setOpen] = useState(false);
const router = useRouter();
const handleToggle = () => {
setOpen(!open);
};
const defaultImage = "https://gimg3.baidu.com/search/src=http%3A%2F%2Fpics3.baidu.com%2Ffeed%2F4ec2d5628535e5dd7c7cdc23847e08e2cc1b62c4.jpeg%40f_auto%3Ftoken%3D38327d5cbefb2cd45af58f8d47c0a0b5&refer=http%3A%2F%2Fwww.baidu.com&app=2021&size=f360,240&n=0&g=0n&q=75&fmt=auto?sec=1710435600&t=eafc0a27ff3295bb5b0b9065fc33a523"
return (
<article style={{ width: '100%', padding: '0px', border: '1px solid #fff', backgroundColor: '#f6f6f6', }}
onClick={() => {
router.push(`/details/${articleData.id}`, { scroll: false })
}}
className="cursor-pointer rounded border border-[#243c5a] overflow-hidden"
>
<figure
style={{ width: '100%', minHeight: "246px" }}
>
<img src={
(
articleData.image_url.includes("http")
? articleData.image_url
: process.env.NEXT_PUBLIC_CLIENT_IMAGE_URL + articleData.image_url
) || defaultImage
} alt={articleData.main_title} style={{ width: '100%', marginBottom: '8px' }} />
</figure>
<div className='px-2 lg:px-6' style={{ height: '214px' }} >
<h3
className='text-left font-bold text-[#333333] text-[1.125rem] leading-[1.5rem]'
style={{
// lineHeight: "24px",
// fontSize: "24px", color: "#333333",
margin: "16px 0",
overflow: "hidden",
textOverflow: "ellipsis",
display: "-webkit-box",
WebkitLineClamp: 2,
WebkitBoxOrient: "vertical",
}}>{truncateString(articleData.main_title)}</h3>
<p style={{ padding: "6px 0", lineHeight: "24px", fontSize: "14px", color: "#808080" }}>{articleData.updated_time}</p>
<p style={{
lineHeight: "24px", fontSize: "16px", color: "#4c4c4c",
overflow: "hidden",
// whiteSpace: "nowrap",
textOverflow: "ellipsis",
display: "-webkit-box",
WebkitLineClamp: 3,
WebkitBoxOrient: "vertical",
}}>{truncateString(articleData.sub_title || articleData.summary)}</p>
{/* <button onClick={handleToggle}>查看详情</button> */}
</div>
{open && (
<Portal>
<div
style={{
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
background: '#fff',
padding: '16px',
border: '2px solid #333',
}}
>
{/* 内容详情 */}
{/* <button onClick={handleToggle}>关闭</button> */}
</div>
</Portal>
)}
</article>
);
};
interface QACardProps {
question: string;
questionAvatar: string;
answer: string;
answerAvatar: string;
timestamp: string;
author: string;
}
export const QACard: React.FC<QAData> = (item) => {
const [open, setOpen] = useState(false);
const router = useRouter();
const handleToggle = () => {
setOpen(!open);
};
return (
// bg-secondary
<div className="qa-card pt-10 lg:pr-16 mb-0 cursor-pointer"
onClick={() => {
router.push(`/qa/${item.id}`)
}}
>
<div className=" h-20 mb-[1.5rem]">
{/* <img src={questionAvatar} alt="Questioner Avatar" className="avatar" /> */}
<figure className='float-left w-[56px] h-full' >
<Image src={qImage} width={36} alt="Questioner Avatar" className="avatar" />
</figure>
<h3
className='ml-0 line-clamp-2 lg:line-clamp-3 leading-[1.7rem] text-[16px] lg:text-[20px] font-bold'
style={{
// fontSize: "20px",
// fontWeight: "bold",
// overflow: "hidden",
// textOverflow: "ellipsis",
// display: "-webkit-box",
// WebkitLineClamp: 2,
// WebkitBoxOrient: "vertical",
}}
>{truncateString(item.question)}</h3>
</div>
<div className=" h-20 mb-[1.875rem]">
{/* <img src={answerAvatar} alt="Answerer Avatar" className="avatar" /> */}
<figure className='float-left w-[3.5rem] h-full ' >
<Image src={aImage} width={36} alt="Answer Avatar" className="" />
</figure>
<p
className='ml-0 pl-0 line-clamp-2 lg:line-clamp-3 text-[14px] lg:text-[18px] text-[#4D4D4D] '
// style={{
// fontSize: "18px",
// color: "#4D4D4D",
// overflow: "hidden",
// textOverflow: "ellipsis",
// display: "-webkit-box",
// WebkitLineClamp: 3,
// WebkitBoxOrient: "vertical",
// }}
>{truncateString(item.answer)}</p>
</div>
<div className="details flex justify-between pb-[2.25rem]" style={{ borderBottom: '1px solid #EBEBEB' }}>
<div className='px-0 flex items-center justify-start'>
<figure className='w-[3.5rem]' >
<Image src={userImage} width={36} alt="admin Author" className="" />
</figure>
<h5
className='text-[14px] lg:text-[16px] text-[#1A1A1A] font-bold'
// style={{
// fontSize: '16px',
// fontWeight: 'bold',
// color: '#1A1A1A'
// }}
>{item.id}</h5>
</div>
<div
className="timestamp text-[14px] lg:text-[16px]"
style={{
color: "#999999",
}}
>{item.updated_time}</div>
</div>
</div>
);
};
export interface TagsViewsProps {
isQA: boolean
selectedCategory: string
categoriesRef: React.MutableRefObject<TagItem[]>
onChange: (category: string) => any
onClickQA: () => any
}
export const TagsViews: React.FC<TagsViewsProps> = React.memo(({
isQA,
selectedCategory,
categoriesRef,
onChange,
onClickQA
}) => {
// console.log('ChildComponent 渲染');
const activeColor = '#1A1A1A'
const activeStyle = {
}
const defStyle = {
}
const { t } = useTranslation();
return (
<FadeIn>
<div
style={{
display: 'flex',
gap: '16px',
justifyContent: 'center',
flexWrap: 'wrap',
marginBottom: '32px',
}}
>
{categoriesRef.current
.map((item, index) => (
<button
key={index}
onClick={() => {
onChange(item.value)
}}
style={{
// fontSize: "20px",
// padding: '8px',
// background: selectedCategory === category ? '#007BFF' : '#fff',
color: !isQA && selectedCategory === item.value ? activeColor : '#666666',
// ...activeStyle,
marginBottom: '8px',
}}
className={`text-[#666666] text-[0.875rem] lg:text-[1.25rem] p-[0.2rem] lg:p-[0.5rem]`}
>
{item.name}
</button>
))}
<div>
<button
onClick={() => {
onClickQA()
}}
style={{
// fontSize: "20px",
// padding: '8px',
// background: selectedCategory === category ? '#007BFF' : '#fff',
// color: selectedCategory === category ? '#666666' : '#1A1A1A',
marginBottom: '8px',
color: isQA ? activeColor : '#666666',
}}
className="text-[#666666] text-[0.875rem] lg:text-[1.25rem] p-[0.2rem] lg:p-[0.5rem]"
>
{t("article.qa")}
</button>
</div>
</div>
</FadeIn>
);
});