feat: 添加每日签到功能,新增帖子排序与社区面板优化
本次提交完成了多个核心功能迭代: 1. 新增用户每日签到系统,包含签到状态查询、连续天数统计、积分累计逻辑 2. 新增"新帖子"排序选项,替换原有的latest排序为新评论排序 3. 重构首页信息流布局,优化移动端与桌面端展示样式 4. 新增最新评论、最新注册用户模块,完善社区面板数据展示 5. 新增静态友情链接配置模块 6. 提取通用时间格式化工具函数,统一全站相对时间展示 7. 补充数据库签到模型与后端API接口,完善前后端交互链路
This commit is contained in:
@@ -1,25 +1,11 @@
|
||||
import Link from "next/link";
|
||||
import { ArrowLeft } from "lucide-react";
|
||||
import type { PostListItem } from "@/lib/api";
|
||||
import { formatRelative } from "@/lib/format";
|
||||
import LikeButton from "./LikeButton";
|
||||
import Avatar from "./Avatar";
|
||||
import { IconComment, IconEye } from "./Icons";
|
||||
|
||||
/** 发帖/回复时间统一为相对时间:刚刚 / N分钟前 / N小时前 / N天前 / N个月前 / N年前 */
|
||||
function formatRelative(dateStr: string) {
|
||||
const t = new Date(dateStr).getTime();
|
||||
const diff = Date.now() - t;
|
||||
const min = 60_000,
|
||||
hour = 60 * min,
|
||||
day = 24 * hour;
|
||||
if (diff < min) return "刚刚";
|
||||
if (diff < hour) return `${Math.floor(diff / min)}分钟前`;
|
||||
if (diff < day) return `${Math.floor(diff / hour)}小时前`;
|
||||
if (diff < 30 * day) return `${Math.floor(diff / day)}天前`;
|
||||
if (diff < 365 * day) return `${Math.floor(diff / (30 * day))}个月前`;
|
||||
return `${Math.floor(diff / (365 * day))}年前`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 帖子列表行(参考社区信息流样式):
|
||||
* 大头像 + 加粗标题(徽章内联)+ 第二行「板块 · 作者 · 发布时间 ← 最后回复」+
|
||||
@@ -45,11 +31,13 @@ export default function PostRow({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="group relative flex items-center gap-3.5 sm:gap-4 px-4 sm:px-5 border-t transition-colors hover:bg-[var(--panel-2)] j13-fade-up"
|
||||
className={`group relative flex items-center px-4 sm:px-5 border-t transition-colors hover:bg-[var(--panel-2)] j13-fade-up ${
|
||||
compact ? "gap-2.5 sm:gap-3" : "gap-3.5 sm:gap-4"
|
||||
}`}
|
||||
style={{
|
||||
borderColor: "var(--line)",
|
||||
paddingTop: compact ? 15 : 18,
|
||||
paddingBottom: compact ? 15 : 18,
|
||||
paddingTop: compact ? 11 : 18,
|
||||
paddingBottom: compact ? 11 : 18,
|
||||
animationDelay: `${Math.min(index, 9) * 35}ms`,
|
||||
}}
|
||||
>
|
||||
@@ -59,7 +47,7 @@ export default function PostRow({
|
||||
aria-label={post.user.nickname}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<Avatar name={post.user.nickname || post.user.username} size={compact ? 44 : 46} />
|
||||
<Avatar name={post.user.nickname || post.user.username} size={compact ? 38 : 46} />
|
||||
</Link>
|
||||
|
||||
<div className="flex-1 min-w-0">
|
||||
@@ -72,14 +60,20 @@ export default function PostRow({
|
||||
aria-label={post.title}
|
||||
>
|
||||
<h3
|
||||
className="font-bold text-[16px] sm:text-[17px] leading-snug truncate transition-colors group-hover:text-[var(--accent)]"
|
||||
className={`font-bold leading-snug truncate transition-colors group-hover:text-[var(--accent)] ${
|
||||
compact ? "text-[15px]" : "text-[16px] sm:text-[17px]"
|
||||
}`}
|
||||
style={{ color: "var(--ink)" }}
|
||||
>
|
||||
{post.title}
|
||||
</h3>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="meta relative z-[2] flex items-center gap-x-2 gap-y-1 mt-1.5 flex-wrap text-[13px]">
|
||||
<div
|
||||
className={`meta relative z-[2] flex items-center gap-x-2 gap-y-1 flex-wrap ${
|
||||
compact ? "mt-1 text-[12.5px]" : "mt-1.5 text-[13px]"
|
||||
}`}
|
||||
>
|
||||
{boardHref && (
|
||||
<Link
|
||||
href={`/board/${post.board.id}`}
|
||||
@@ -109,6 +103,11 @@ export default function PostRow({
|
||||
<span className="tabular-nums shrink-0">{formatRelative(lastReply!.created_at)}</span>
|
||||
</span>
|
||||
)}
|
||||
{!replied && post.comment_count === 0 && (
|
||||
<span className="hidden sm:inline" aria-hidden>
|
||||
· 暂无回复
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user