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 { ClipboardList, Heart, MessageCircle, PenSquare, Pin } from "lucide-react"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
|
import { useState } from "react"
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
|
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
|
||||||
import { roleLabels } from "@/lib/constants"
|
import { roleLabels } from "@/lib/constants"
|
||||||
import { mockPosts } from "@/lib/mock-data"
|
import { mockGames, mockPosts } from "@/lib/mock-data"
|
||||||
|
|
||||||
export default function CommunityPage() {
|
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 (
|
return (
|
||||||
<div className="container mx-auto py-8 px-4 max-w-2xl">
|
<div className="container mx-auto py-8 px-4 max-w-2xl">
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-between mb-6">
|
||||||
@@ -20,8 +40,41 @@ export default function CommunityPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</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">
|
<div className="space-y-4">
|
||||||
{mockPosts.map((post) => (
|
{filteredPosts.map((post) => (
|
||||||
<Link key={post.id} href={`/post/${post.id}`}>
|
<Link key={post.id} href={`/post/${post.id}`}>
|
||||||
<Card className="hover:shadow-md transition-shadow">
|
<Card className="hover:shadow-md transition-shadow">
|
||||||
<CardHeader className="pb-3">
|
<CardHeader className="pb-3">
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select"
|
} from "@/components/ui/select"
|
||||||
import { Textarea } from "@/components/ui/textarea"
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
|
import { mockPosts } from "@/lib/mock-data"
|
||||||
import { useRequireAuth } from "@/lib/use-require-auth"
|
import { useRequireAuth } from "@/lib/use-require-auth"
|
||||||
|
|
||||||
const postSchema = z.object({
|
const postSchema = z.object({
|
||||||
@@ -35,6 +36,7 @@ export default function NewPostPage() {
|
|||||||
const [postType, setPostType] = useState("normal")
|
const [postType, setPostType] = useState("normal")
|
||||||
const [selectedTags, setSelectedTags] = useState<string[]>([])
|
const [selectedTags, setSelectedTags] = useState<string[]>([])
|
||||||
const [imageCount, setImageCount] = useState(0)
|
const [imageCount, setImageCount] = useState(0)
|
||||||
|
const [selectedQuotePostId, setSelectedQuotePostId] = useState<string | undefined>(undefined)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@@ -104,6 +106,28 @@ export default function NewPostPage() {
|
|||||||
</div>
|
</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">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="title">标题</Label>
|
<Label htmlFor="title">标题</Label>
|
||||||
<Input id="title" placeholder="请输入帖子标题" {...register("title")} />
|
<Input id="title" placeholder="请输入帖子标题" {...register("title")} />
|
||||||
|
|||||||
Reference in New Issue
Block a user