"use client"; import type React from "react"; import Link from "next/link"; import { ChevronLeft, Search, Trash2, MoreVertical, Edit, ArrowUpDown, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Progress } from "@/components/ui/progress"; import { useUser } from "@/context/user-context"; import { useState, useEffect } from "react"; import { AddQuestForm } from "@/components/add-quest-form"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter, } from "@/components/ui/dialog"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Quest } from "@/interface/quest.interface"; export default function QuestsPage() { const { userStats, completeQuest, updateQuestProgress, deleteQuest, updateQuest, } = useUser(); const [searchTerm, setSearchTerm] = useState(""); const [sortBy, setSortBy] = useState<"latest" | "priority">("latest"); // Load sorting preference from localStorage on component mount useEffect(() => { const savedSortBy = localStorage.getItem("questsSortBy"); if ( savedSortBy && (savedSortBy === "latest" || savedSortBy === "priority") ) { setSortBy(savedSortBy); } }, []); // Save sorting preference to localStorage whenever it changes const handleSortChange = (value: "latest" | "priority") => { setSortBy(value); localStorage.setItem("questsSortBy", value); }; // Sort function const sortQuests = (quests: Quest[], isCompleted = false) => { return quests.sort((a, b) => { if (sortBy === "priority") { // Sort by priority: High > Medium > Low (descending) const priorityOrder = { High: 3, Medium: 2, Low: 1 }; const priorityA = priorityOrder[a.priority] || 0; const priorityB = priorityOrder[b.priority] || 0; // If priorities are the same, sort by creation time (newest first) if (priorityA === priorityB) { const timeA = a.createdAt || 0; const timeB = b.createdAt || 0; return timeB - timeA; } return priorityB - priorityA; } else { // Sort by time (newest first) if (isCompleted) { // For completed quests, sort by completion time const timeA = a.completedAt || 0; const timeB = b.completedAt || 0; return timeB - timeA; } else { // For active quests, sort by creation time const timeA = a.createdAt || 0; const timeB = b.createdAt || 0; return timeB - timeA; } } }); }; // Filter and sort quests based on search term and status const activeQuests = sortQuests( userStats.quests.filter( (quest) => !quest.completed && (quest.title.toLowerCase().includes(searchTerm.toLowerCase()) || quest.description.toLowerCase().includes(searchTerm.toLowerCase())) ), false ); const completedQuests = sortQuests( userStats.quests.filter( (quest) => quest.completed && (quest.title.toLowerCase().includes(searchTerm.toLowerCase()) || quest.description.toLowerCase().includes(searchTerm.toLowerCase())) ), true ); const handleDeleteQuest = (questId: string) => { deleteQuest(questId); }; return (
{/* Header */}

Quests

{" "} {/* Search and Filter */}
setSearchTerm(e.target.value)} />
{/* Sorting Controls */}
Sort by:{" "}
{/* Quests Tabs */} Active Completed {/* Active Quests */}
{activeQuests.length > 0 ? ( activeQuests.map((quest) => ( completeQuest(quest.id)} onProgress={(progress) => updateQuestProgress(quest.id, progress) } onDelete={() => handleDeleteQuest(quest.id)} /> )) ) : (
{searchTerm ? "No active quests match your search." : "No active quests available."}
)}
{/* Completed Quests */}
{completedQuests.length > 0 ? ( completedQuests.map((quest) => ( handleDeleteQuest(quest.id)} /> )) ) : (
{searchTerm ? "No completed quests match your search." : "No completed quests yet."}
)}
); } function QuestCard({ quest, onComplete, onProgress, onDelete, }: { quest: Quest; onComplete?: () => void; onProgress?: (progress: number) => void; onDelete?: () => void; }) { const { updateQuest } = useUser(); const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); const [editForm, setEditForm] = useState({ title: quest.title, description: quest.description, reward: quest.reward, difficulty: quest.difficulty, priority: quest.priority || "Medium", expiry: quest.expiry, expReward: quest.expReward, statPointsReward: quest.statPointsReward, }); // Format date from timestamp const formatDate = (timestamp?: number) => { if (!timestamp) return ""; const date = new Date(timestamp); return date.toLocaleString("en-US", { month: "short", day: "numeric", year: "2-digit", hour: "numeric", minute: "2-digit", }); }; const timeDisplay = quest.completed ? formatDate(quest.completedAt) : formatDate(quest.createdAt); const handleEditSubmit = (e: React.FormEvent) => { e.preventDefault(); updateQuest(quest.id, editForm); setIsEditDialogOpen(false); }; const difficultyColors = { S: "bg-red-500", A: "bg-orange-500", B: "bg-yellow-500", C: "bg-green-500", D: "bg-blue-500", E: "bg-purple-500", }; const handleButtonClick = () => { if (quest.completed) return; if (quest.progress === 100 && onComplete) { onComplete(); } else if (quest.progress < 100 && onProgress) { // Increment progress by 25% each time const newProgress = Math.min(100, quest.progress + 25); onProgress(newProgress); } }; return (
{/* Action bar with difficulty, priority and menu - positioned above the title */}
{quest.difficulty}
{quest.priority && (
{quest.priority}
)}
{/* Dropdown menu for actions */} {onDelete && ( {quest.isCustom && !quest.completed && ( { e.preventDefault(); setIsEditDialogOpen(true); }} > Edit Quest )} e.preventDefault()} > Delete Quest Delete Quest Are you sure you want to delete this quest? This action cannot be undone. Cancel Delete )} {/* Edit Dialog */} Edit Quest
setEditForm({ ...editForm, title: e.target.value }) } className="bg-[#0a0e14] border-[#1e2a3a]" />