合同初步可以访问

This commit is contained in:
2025-05-29 17:42:35 +08:00
parent 9200654c35
commit b92d87a3b4
16 changed files with 2239 additions and 0 deletions
@@ -0,0 +1,118 @@
import { useState } from 'react';
import { useNavigate } from '@remix-run/react';
interface Template {
id: string;
title: string;
type: string;
description: string;
updateTime: string;
useCount: number;
rating: number;
category: string;
}
interface TemplateCardProps {
template: Template;
onClick: () => void;
}
export function TemplateCard({ template, onClick }: TemplateCardProps) {
const [isFavorited, setIsFavorited] = useState(false);
const navigate = useNavigate();
const handleFavoriteClick = (e: React.MouseEvent) => {
e.stopPropagation();
setIsFavorited(!isFavorited);
};
const handleActionClick = (e: React.MouseEvent, action: string) => {
e.stopPropagation();
switch (action) {
case '立即使用':
console.log('下载并使用模板:', template.id);
// 这里应该触发下载逻辑
break;
case '预览':
// 导航到模板详情页面
navigate(`/contract-template/detail/${template.id}`);
break;
default:
console.log(`执行操作: ${action}`, template.id);
}
};
const renderStars = (rating: number) => {
const stars = [];
const fullStars = Math.floor(rating);
const hasHalfStar = rating % 1 !== 0;
for (let i = 0; i < 5; i++) {
if (i < fullStars) {
stars.push(<i key={i} className="ri-star-fill text-xs"></i>);
} else if (i === fullStars && hasHalfStar) {
stars.push(<i key={i} className="ri-star-half-fill text-xs"></i>);
} else {
stars.push(<i key={i} className="ri-star-line text-xs"></i>);
}
}
return stars;
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onClick();
}
};
return (
<div
className="template-card"
onClick={onClick}
onKeyDown={handleKeyDown}
role="button"
tabIndex={0}
aria-label={`查看${template.title}详情`}
>
<div className="template-header">
<div className="template-type">{template.type}</div>
<div className="flex items-center gap-1 text-yellow-500">
{renderStars(template.rating)}
<span className="text-xs ml-1">{template.rating}</span>
</div>
</div>
<h3 className="template-title">{template.title}</h3>
<p className="template-desc">{template.description}</p>
<div className="template-meta">
<span>{template.updateTime}</span>
<span>使{template.useCount.toLocaleString()}</span>
</div>
<div className="template-actions">
<button
className="action-btn primary"
onClick={(e) => handleActionClick(e, '立即使用')}
>
使
</button>
<button
className="action-btn"
onClick={(e) => handleActionClick(e, '预览')}
>
</button>
<button
className="action-btn"
onClick={handleFavoriteClick}
title={isFavorited ? '取消收藏' : '收藏'}
>
<i className={isFavorited ? 'ri-star-fill text-yellow-500' : 'ri-star-line'}></i>
</button>
</div>
</div>
);
}