"use client"
import { useState, useEffect } from "react"
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import {
Sparkles,
ArrowLeft,
Search,
Plus,
Filter,
X,
BarChart3,
Eye,
Users,
ChevronLeft,
ChevronRight,
HelpCircle
} from "lucide-react"
import WishCard from "@/components/wish-card"
import HeaderMusicControl from "@/components/header-music-control"
import { categories, categorizeWishMultiple, getCategoryStats, type Wish } from "@/lib/categorization"
import { WishService } from "@/lib/supabase-service"
import { driver } from "driver.js"
import "driver.js/dist/driver.css"
// 分頁組件
interface PaginationProps {
currentPage: number
totalPages: number
onPageChange: (page: number) => void
}
function PaginationComponent({ currentPage, totalPages, onPageChange }: PaginationProps) {
// 根據螢幕尺寸調整顯示策略
const getMobilePageNumbers = () => {
const pages = []
if (totalPages <= 3) {
// 小於等於3頁,全部顯示
for (let i = 1; i <= totalPages; i++) {
pages.push(i)
}
} else {
// 手機端簡化邏輯:只顯示當前頁和相鄰頁
if (currentPage === 1) {
pages.push(1, 2, '...', totalPages)
} else if (currentPage === totalPages) {
pages.push(1, '...', totalPages - 1, totalPages)
} else {
if (currentPage === 2) {
pages.push(1, 2, 3, '...', totalPages)
} else if (currentPage === totalPages - 1) {
pages.push(1, '...', totalPages - 2, totalPages - 1, totalPages)
} else {
pages.push(1, '...', currentPage, '...', totalPages)
}
}
}
return pages
}
const getDesktopPageNumbers = () => {
const pages = []
const maxVisiblePages = 5
if (totalPages <= maxVisiblePages) {
for (let i = 1; i <= totalPages; i++) {
pages.push(i)
}
} else {
if (currentPage <= 3) {
for (let i = 1; i <= 4; i++) {
pages.push(i)
}
pages.push('...')
pages.push(totalPages)
} else if (currentPage >= totalPages - 2) {
pages.push(1)
pages.push('...')
for (let i = totalPages - 3; i <= totalPages; i++) {
pages.push(i)
}
} else {
pages.push(1)
pages.push('...')
for (let i = currentPage - 1; i <= currentPage + 1; i++) {
pages.push(i)
}
pages.push('...')
pages.push(totalPages)
}
}
return pages
}
return (
{/* 上一頁按鈕 */}
{/* 桌面端頁數按鈕 */}
{getDesktopPageNumbers().map((page, index) => {
if (page === '...') {
return (
...
)
}
const pageNumber = page as number
const isActive = pageNumber === currentPage
return (
)
})}
{/* 手機端頁數按鈕 */}
{getMobilePageNumbers().map((page, index) => {
if (page === '...') {
return (
...
)
}
const pageNumber = page as number
const isActive = pageNumber === currentPage
return (
)
})}
{/* 下一頁按鈕 */}
)
}
export default function WishesPage() {
const [wishes, setWishes] = useState([])
const [publicWishes, setPublicWishes] = useState([])
const [searchTerm, setSearchTerm] = useState("")
const [selectedCategories, setSelectedCategories] = useState([])
const [filteredWishes, setFilteredWishes] = useState([])
const [categoryStats, setCategoryStats] = useState<{ [key: string]: number }>({})
const [showFilters, setShowFilters] = useState(false)
const [totalWishes, setTotalWishes] = useState(0)
const [privateCount, setPrivateCount] = useState(0)
// 分頁相關狀態
const [currentPage, setCurrentPage] = useState(1)
const [itemsPerPage] = useState(3)
const [paginatedWishes, setPaginatedWishes] = useState([])
const [totalPages, setTotalPages] = useState(0)
// 教學功能
const startTutorial = () => {
const driverObj = driver({
showProgress: true,
progressText: "步驟 {{current}} / {{total}}",
nextBtnText: "下一步",
prevBtnText: "上一步",
doneBtnText: "完成教學",
steps: [
{
element: "#wishes-title",
popover: {
title: "💬 聆聽心聲首頁",
description: "這裡收集了員工願意公開分享的真實困擾和經驗,讓您了解團隊面臨的挑戰,也讓員工知道他們並不孤單。",
side: "bottom",
align: "center"
}
},
{
element: "#search-section",
popover: {
title: "🔍 搜尋功能",
description: "在搜索框中輸入關鍵字,快速找到相似的工作困擾。支援搜尋標題、問題描述和期望解決方案。",
side: "bottom",
align: "center"
}
},
{
element: "#filter-button",
popover: {
title: "🏷️ 篩選器",
description: "點擊篩選按鈕可按問題類型篩選案例。支援多標籤選擇,幫助您聚焦特定領域的問題。",
side: "bottom",
align: "center"
}
},
{
element: "#stats-info",
popover: {
title: "📊 統計資訊",
description: "顯示公開案例數量和私密案例數量。私密案例不會在此顯示,但會用於整體分析。",
side: "bottom",
align: "center"
}
},
{
element: "#wishes-grid",
popover: {
title: "📋 案例展示",
description: "這裡顯示所有公開分享的困擾案例。每個案例包含問題描述、期望解決方案和分類標籤。",
side: "top",
align: "center"
}
},
{
element: "#pagination-section",
popover: {
title: "📄 分頁導覽",
description: "當案例較多時,使用分頁功能瀏覽所有內容。每頁顯示3個案例,避免頁面過長。",
side: "top",
align: "center"
}
}
],
onDestroyStarted: () => {
driverObj.destroy();
},
});
driverObj.drive();
};
useEffect(() => {
const fetchWishes = async () => {
try {
// 獲取所有困擾(用於統計)
const allWishesData = await WishService.getAllWishes()
// 獲取公開困擾(用於顯示)
const publicWishesData = await WishService.getPublicWishes()
// 轉換數據格式以匹配 categorization.ts 的 Wish 接口
const convertWish = (wish: any) => ({
id: wish.id,
title: wish.title,
currentPain: wish.current_pain,
expectedSolution: wish.expected_solution,
expectedEffect: wish.expected_effect || "",
createdAt: wish.created_at,
isPublic: wish.is_public,
email: wish.email,
images: wish.images,
like_count: wish.like_count || 0, // 包含點讚數
})
const allWishes = allWishesData.map(convertWish)
const publicWishes = publicWishesData.map(convertWish)
// 計算私密困擾數量
const privateCount = allWishes.length - publicWishes.length
setWishes(allWishes)
setPublicWishes(publicWishes)
setTotalWishes(allWishes.length)
setPrivateCount(privateCount)
setCategoryStats(getCategoryStats(publicWishes))
} catch (error) {
console.error("獲取困擾數據失敗:", error)
// 如果 Supabase 連接失敗,回退到 localStorage
const savedWishes = JSON.parse(localStorage.getItem("wishes") || "[]")
const publicOnly = savedWishes.filter((wish: Wish & { isPublic?: boolean }) => wish.isPublic !== false)
const privateOnly = savedWishes.filter((wish: Wish & { isPublic?: boolean }) => wish.isPublic === false)
setWishes(savedWishes)
setPublicWishes(publicOnly.reverse())
setTotalWishes(savedWishes.length)
setPrivateCount(privateOnly.length)
setCategoryStats(getCategoryStats(publicOnly))
}
}
fetchWishes()
}, [])
useEffect(() => {
let filtered = publicWishes
// 按搜尋詞篩選
if (searchTerm) {
filtered = filtered.filter(
(wish) =>
wish.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
wish.currentPain.toLowerCase().includes(searchTerm.toLowerCase()) ||
wish.expectedSolution.toLowerCase().includes(searchTerm.toLowerCase()),
)
}
// 按分類篩選(支持多標籤)
if (selectedCategories.length > 0) {
filtered = filtered.filter((wish) => {
const wishCategories = categorizeWishMultiple(wish)
return selectedCategories.some((selectedCategory) =>
wishCategories.some((wishCategory) => wishCategory.name === selectedCategory),
)
})
}
setFilteredWishes(filtered)
}, [publicWishes, searchTerm, selectedCategories])
// 分頁計算 useEffect
useEffect(() => {
const startIndex = (currentPage - 1) * itemsPerPage
const endIndex = startIndex + itemsPerPage
const wishesToPaginate = filteredWishes.length > 0 ? filteredWishes : publicWishes
setPaginatedWishes(wishesToPaginate.slice(startIndex, endIndex))
setTotalPages(Math.ceil(wishesToPaginate.length / itemsPerPage))
}, [filteredWishes, publicWishes, currentPage, itemsPerPage])
// 重置分頁當篩選條件改變時
useEffect(() => {
setCurrentPage(1)
}, [searchTerm, selectedCategories])
const toggleCategory = (categoryName: string) => {
setSelectedCategories((prev) =>
prev.includes(categoryName) ? prev.filter((cat) => cat !== categoryName) : [...prev, categoryName],
)
}
const clearAllFilters = () => {
setSelectedCategories([])
setSearchTerm("")
}
const hasActiveFilters = selectedCategories.length > 0 || searchTerm.length > 0
return (
{/* 星空背景 - 手機優化 */}
{[...Array(25)].map((_, i) => (
))}
{/* Header - 修復跑版問題 */}
{/* Logo 區域 - 防止文字換行 */}
資訊部.心願星河
{/* 導航區域 */}
{/* Main Content - 手機優化 */}
聆聽每一份真實經歷
這裡收集了許多職場工作者願意公開分享的真實困擾和經驗
{/* Search Bar and Filter Button - 並排布局 */}
{/* Search Input */}
setSearchTerm(e.target.value)}
className="pl-10 bg-slate-700/50 border-blue-600/50 text-white placeholder:text-blue-300 focus:border-cyan-400 text-sm md:text-base"
/>
{/* Filter Button */}
{/* Category Filters */}
{showFilters && (
{/* 手機端優化:改為上下布局避免擠壓 */}
{/* 第一行:標題和Badge */}
按問題類型篩選
支持多標籤
{/* 第二行:手機端顯示Badge和清除按鈕 */}
支持多標籤
{hasActiveFilters && (
)}
{/* 手機端優化:調整網格間距和卡片布局 */}
{categories.map((category) => {
const count = categoryStats[category.name] || 0
const isSelected = selectedCategories.includes(category.name)
return (
)
})}
{/* Active Filters Display */}
{selectedCategories.length > 0 && (
正在查看:
{selectedCategories.map((categoryName) => {
const category = categories.find((cat) => cat.name === categoryName)
return (
toggleCategory(categoryName)}
>
{category?.icon}
{categoryName}
)
})}
)}
)}
{/* Stats - 手機優化,增加隱私說明 */}
{hasActiveFilters ? (
<>找到 {filteredWishes.length} / {publicWishes.length} 個相關案例>
) : (
<>公開分享 {publicWishes.length} 個案例>
)}
{totalPages > 1 && (
<> · 第 {currentPage}/{totalPages} 頁>
)}
{hasActiveFilters ? `${filteredWishes.length}/${publicWishes.length}` : `${publicWishes.length} 個案例`}
{totalPages > 1 && ` (${currentPage}/${totalPages})`}
{privateCount > 0 && (
另有 {privateCount} 個私密案例用於分析
{privateCount} 個私密案例
)}
{privateCount > 0 && (
私密案例不會顯示在此頁面,但會納入問題洞察分析,幫助了解整體趨勢
)}
{/* Wishes Grid - 手機優化 */}
{paginatedWishes.length > 0 ? (
<>
{paginatedWishes.map((wish) => (
))}
{/* 分頁組件 */}
{totalPages > 1 && (
)}
>
) : publicWishes.length === 0 ? (
{totalWishes > 0 ? "還沒有人公開分享經歷" : "還沒有人分享經歷"}
{totalWishes > 0
? `目前有 ${totalWishes} 個案例,但都選擇保持私密。成為第一個公開分享的人吧!`
: "成為第一個分享工作困擾的人,幫助更多人找到解決方案"}
) : (
沒有找到相關案例
{hasActiveFilters ? "試試調整篩選條件,或分享你的獨特經歷" : "試試其他關鍵字,或分享你的困擾"}
{hasActiveFilters && (
)}
)}
{/* 固定在右下角的教学按钮 */}
{/* Driver.js 自定义样式 */}
)
}