feat: add community sorting/filtering and quote post input
This commit is contained in:
@@ -1,13 +1,33 @@
|
||||
"use client"
|
||||
|
||||
import { ClipboardList, Heart, MessageCircle, PenSquare, Pin } from "lucide-react"
|
||||
import Link from "next/link"
|
||||
import { useState } from "react"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
|
||||
import { roleLabels } from "@/lib/constants"
|
||||
import { mockPosts } from "@/lib/mock-data"
|
||||
import { mockGames, mockPosts } from "@/lib/mock-data"
|
||||
|
||||
export default function CommunityPage() {
|
||||
const [sortMode, setSortMode] = useState<"latest" | "hot">("latest")
|
||||
const [selectedGame, setSelectedGame] = useState<string | null>(null)
|
||||
|
||||
const filteredPosts = mockPosts
|
||||
.filter((post) => {
|
||||
if (!selectedGame) return true
|
||||
return post.tags.includes(selectedGame)
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (sortMode === "latest") {
|
||||
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
||||
}
|
||||
const scoreA = a.likeCount + a.commentCount
|
||||
const scoreB = b.likeCount + b.commentCount
|
||||
return scoreB - scoreA
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="container mx-auto py-8 px-4 max-w-2xl">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
@@ -20,8 +40,41 @@ export default function CommunityPage() {
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 mb-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
variant={sortMode === "latest" ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => setSortMode("latest")}
|
||||
className="h-8"
|
||||
>
|
||||
最新
|
||||
</Button>
|
||||
<Button
|
||||
variant={sortMode === "hot" ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => setSortMode("hot")}
|
||||
className="h-8"
|
||||
>
|
||||
最热
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{mockGames.map((game) => (
|
||||
<Badge
|
||||
key={game.id}
|
||||
variant={selectedGame === game.name ? "default" : "outline"}
|
||||
className="cursor-pointer hover:bg-primary/80 transition-colors px-3 py-1"
|
||||
onClick={() => setSelectedGame(selectedGame === game.name ? null : game.name)}
|
||||
>
|
||||
{game.name}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{mockPosts.map((post) => (
|
||||
{filteredPosts.map((post) => (
|
||||
<Link key={post.id} href={`/post/${post.id}`}>
|
||||
<Card className="hover:shadow-md transition-shadow">
|
||||
<CardHeader className="pb-3">
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
import { Textarea } from "@/components/ui/textarea"
|
||||
import { mockPosts } from "@/lib/mock-data"
|
||||
import { useRequireAuth } from "@/lib/use-require-auth"
|
||||
|
||||
const postSchema = z.object({
|
||||
@@ -35,6 +36,7 @@ export default function NewPostPage() {
|
||||
const [postType, setPostType] = useState("normal")
|
||||
const [selectedTags, setSelectedTags] = useState<string[]>([])
|
||||
const [imageCount, setImageCount] = useState(0)
|
||||
const [selectedQuotePostId, setSelectedQuotePostId] = useState<string | undefined>(undefined)
|
||||
|
||||
const {
|
||||
register,
|
||||
@@ -104,6 +106,28 @@ export default function NewPostPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{postType === "quote" && (
|
||||
<div className="space-y-2">
|
||||
<Label>引用帖子</Label>
|
||||
<Select>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择要引用的帖子" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{mockPosts.map((post) => (
|
||||
<SelectItem key={post.id} value={post.id}>
|
||||
{post.title}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="mt-2 rounded-md border bg-muted/50 p-3 text-sm text-muted-foreground">
|
||||
<p className="font-medium text-foreground">预览:</p>
|
||||
<p className="mt-1">选择一个帖子以查看预览...</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="title">标题</Label>
|
||||
<Input id="title" placeholder="请输入帖子标题" {...register("title")} />
|
||||
|
||||
Reference in New Issue
Block a user