"use client" import type React from "react" import { useState, useEffect } from "react" import Link from "next/link" import { useRouter } from "next/navigation" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { Checkbox } from "@/components/ui/checkbox" import { Alert, AlertDescription } from "@/components/ui/alert" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog" import { Sparkles, ArrowLeft, Send, BarChart3, Eye, EyeOff, Shield, Info, Mail, ImageIcon, Lightbulb, HelpCircle } from "lucide-react" import { useToast } from "@/hooks/use-toast" import { soundManager } from "@/lib/sound-effects" import HeaderMusicControl from "@/components/header-music-control" import { moderateWishForm, type ModerationResult } from "@/lib/content-moderation" import ContentModerationFeedback from "@/components/content-moderation-feedback" import ImageUpload from "@/components/image-upload" import type { ImageFile } from "@/lib/image-utils" import { WishService } from "@/lib/supabase-service" import { categorizeWish, type Wish } from "@/lib/categorization" import { driver } from "driver.js" import "driver.js/dist/driver.css" export default function SubmitPage() { const [formData, setFormData] = useState({ title: "", currentPain: "", expectedSolution: "", expectedEffect: "", isPublic: true, email: "", }) const [images, setImages] = useState([]) const [isSubmitting, setIsSubmitting] = useState(false) const { toast } = useToast() const router = useRouter() const [moderationResult, setModerationResult] = useState(null) const [showModerationFeedback, setShowModerationFeedback] = useState(false) const [currentCategory, setCurrentCategory] = useState(null) const [showCategoryHint, setShowCategoryHint] = useState(false) const [showConfirmDialog, setShowConfirmDialog] = useState(false) // 初始化音效系統 useEffect(() => { const initSound = async () => { // 用戶首次點擊時啟動音頻上下文 const handleFirstInteraction = async () => { await soundManager.play("hover") // 測試音效 document.removeEventListener("click", handleFirstInteraction) } document.addEventListener("click", handleFirstInteraction) } initSound() }, []) // 實時檢測分類並顯示提示 useEffect(() => { // 只有當用戶輸入了一定內容才進行分類檢測 const hasMinimumContent = formData.title.trim().length > 3 || formData.currentPain.trim().length > 10 if (hasMinimumContent) { // 創建模擬的 Wish 物件進行分類 const mockWish: Wish = { id: 0, title: formData.title, currentPain: formData.currentPain, expectedSolution: formData.expectedSolution, expectedEffect: formData.expectedEffect, createdAt: new Date().toISOString() } const category = categorizeWish(mockWish) setCurrentCategory(category.name) // 如果分類為"其他問題"且內容不夠詳細,顯示提示(只對公開分享) const isOtherCategory = category.name === "其他問題" const contentLength = formData.title.trim().length + formData.currentPain.trim().length + formData.expectedSolution.trim().length setShowCategoryHint(isOtherCategory && contentLength < 50 && formData.isPublic) } else { setCurrentCategory(null) setShowCategoryHint(false) } }, [formData.title, formData.currentPain, formData.expectedSolution, formData.expectedEffect, formData.isPublic]) // 教学指引配置 const startTutorial = () => { const driverObj = driver({ showProgress: true, progressText: "步驟 {{current}} / {{total}}", nextBtnText: "下一步", prevBtnText: "上一步", doneBtnText: "完成教學", popoverClass: "driverjs-theme", steps: [ { element: "#tutorial-welcome", popover: { title: "歡迎來到心願星河 ✨", description: "這是一個讓您分享工作困擾並獲得專業建議的平台。讓我們一起了解如何使用吧!", side: "bottom", align: "center" } }, { element: "#wish-title", popover: { title: "困擾標題 📝", description: "請用簡潔的文字描述您遇到的主要問題,這樣其他人能快速了解您的困擾。", side: "bottom", align: "start" } }, { element: "#current-pain", popover: { title: "具體困擾描述 📋", description: "詳細說明您在工作中遇到的困難,包括具體情況、影響程度等。越詳細越能幫助管理者理解問題。", side: "bottom", align: "start" } }, { element: "#expected-solution", popover: { title: "期望的解決方式 💡", description: "分享您對解決這個問題的想法或建議,這有助於找到最適合的解決方案。", side: "bottom", align: "start" } }, { element: "#expected-effect", popover: { title: "預期改善效果 🎯", description: "描述問題解決後您期望的工作效率或環境改善,這能幫助評估解決方案的價值。", side: "bottom", align: "start" } }, { element: "#image-upload", popover: { title: "相關圖片上傳 📸", description: "您可以上傳與困擾相關的截圖、照片或文件圖片,視覺化的資料能幫助更好地理解問題。", side: "top", align: "start" } }, { element: "#privacy-settings", popover: { title: "隱私設定 🔐", description: "選擇是否公開分享您的困擾。公開分享能讓其他人看到並產生共鳴,私密分享只會用於數據分析。", side: "top", align: "start" } }, { element: "#submit-button", popover: { title: "提交困擾 🚀", description: "完成填寫後點擊這裡提交。系統會智能分析您的困擾類型,並為您準備專業的建議!", side: "top", align: "center" } } ] }) driverObj.drive() } // 实际的提交逻辑 const performSubmit = async () => { setIsSubmitting(true) setShowModerationFeedback(false) // 播放提交音效 await soundManager.play("submit") try { // 創建困擾案例到 Supabase 數據庫 await WishService.createWish({ title: formData.title, currentPain: formData.currentPain, expectedSolution: formData.expectedSolution, expectedEffect: formData.expectedEffect, isPublic: formData.isPublic, email: formData.email, images: images, // 直接傳遞 ImageFile 數組 }) // 播放成功音效 await soundManager.play("success") toast({ title: "你的困擾已成功提交", description: formData.isPublic ? "正在為你準備專業的回饋,其他人也能看到你的分享..." : "正在為你準備專業的回饋,你的分享將保持私密...", }) // 重置表单 setFormData({ title: "", currentPain: "", expectedSolution: "", expectedEffect: "", isPublic: true, email: "", }) setImages([]) setIsSubmitting(false) setModerationResult(null) // 跳轉到感謝頁面 setTimeout(() => { router.push("/thank-you") }, 1000) } catch (error) { console.error("提交困擾失敗:", error) // 播放錯誤音效 await soundManager.play("click") toast({ title: "提交失敗", description: "請稍後再試或檢查網路連接", variant: "destructive", }) setIsSubmitting(false) } } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() // 先進行內容審核 const moderation = moderateWishForm(formData) setModerationResult(moderation) if (!moderation.isAppropriate) { setShowModerationFeedback(true) await soundManager.play("click") // 播放提示音效 toast({ title: "內容需要修改", description: "請根據建議修改內容後再次提交", variant: "destructive", }) return } // 检查是否为"其他问题"分类且内容较少,需要确认 if (currentCategory === "其他問題" && formData.isPublic) { const contentLength = formData.title.trim().length + formData.currentPain.trim().length + formData.expectedSolution.trim().length if (contentLength < 50) { setShowConfirmDialog(true) return } } // 直接提交 await performSubmit() } const handleChange = (field: string, value: string | boolean) => { setFormData((prev) => ({ ...prev, [field]: value })) } const handleButtonClick = async () => { await soundManager.play("click") } return (
{/* 星空背景 - 手機優化 */}
{[...Array(25)].map((_, i) => (
))}
{/* Header - 修復跑版問題 */}
{/* Logo 區域 - 防止文字換行 */}

強茂.心願星河

{/* 導航區域 */}
{/* Main Content - 手機優化 */}
{/* 小許願瓶 - 添加呼吸動畫 */}
{/* 小星光粒子 */}
{/* 呼吸光暈 */}

分享你的工作困擾

每一個困擾都是改善的起點,我們會用專業的角度為你分析和建議

困擾分享
請詳細描述你的工作困擾,我們會認真分析並提供專業建議
handleChange("title", e.target.value)} required className="bg-slate-700/50 border-blue-600/50 text-white placeholder:text-blue-300 focus:border-cyan-400 text-sm md:text-base" />