import React, { useState, useEffect } from 'react'; import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; import { arrayMove, SortableContext, sortableKeyboardCoordinates, useSortable, rectSortingStrategy } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { X, Plus, Save, Upload, Trash2 } from 'lucide-react'; // Main App Component export default function TierListTuesday() { // Define tiers with their colors and labels const tierDefinitions = [ { id: 'S', label: 'S', color: 'bg-rose-600' }, { id: 'A', label: 'A', color: 'bg-amber-500' }, { id: 'B', label: 'B', color: 'bg-emerald-500' }, { id: 'C', label: 'C', color: 'bg-sky-500' }, { id: 'D', label: 'D', color: 'bg-indigo-500' }, { id: 'F', label: 'F', color: 'bg-slate-500' }, { id: 'unranked', label: 'Unranked', color: 'bg-gray-300' } ]; // State for the tier list title const [title, setTitle] = useState('Tier List Tuesday'); // State for items in each tier const [tiers, setTiers] = useState(() => { const savedTiers = localStorage.getItem('tierListItems'); return savedTiers ? JSON.parse(savedTiers) : tierDefinitions.reduce((acc, tier) => { acc[tier.id] = []; return acc; }, {}); }); // State for new item form const [newItem, setNewItem] = useState({ name: '', image: '' }); const [showForm, setShowForm] = useState(false); // Save to localStorage whenever tiers change useEffect(() => { localStorage.setItem('tierListItems', JSON.stringify(tiers)); }, [tiers]); // DnD sensors setup const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }) ); // Handle DnD end event const handleDragEnd = (event) => { const { active, over } = event; if (!over) return; const activeId = active.id; const overId = over.id; // Extract tier and item info from the IDs const [activeItemId, activeTier] = activeId.split('-item-'); const [overItemId, overTier] = overId.split('-item-'); // If dropping on a different tier if (activeTier !== overTier) { setTiers(prev => { const activeItem = prev[activeTier].find(item => `${item.id}-item-${activeTier}` === activeId); return { ...prev, [activeTier]: prev[activeTier].filter(item => `${item.id}-item-${activeTier}` !== activeId), [overTier]: [...prev[overTier], { ...activeItem, id: Date.now() }] }; }); } // If reordering within the same tier else if (activeId !== overId) { setTiers(prev => { const activeIndex = prev[activeTier].findIndex(item => `${item.id}-item-${activeTier}` === activeId); const overIndex = prev[activeTier].findIndex(item => `${item.id}-item-${activeTier}` === overId); return { ...prev, [activeTier]: arrayMove(prev[activeTier], activeIndex, overIndex) }; }); } }; // Add a new item to the unranked tier const handleAddItem = (e) => { e.preventDefault(); if (newItem.name.trim()) { setTiers(prev => ({ ...prev, unranked: [...prev.unranked, { id: Date.now(), name: newItem.name, image: newItem.image }] })); setNewItem({ name: '', image: '' }); setShowForm(false); } }; // Delete an item const handleDeleteItem = (tierId, itemId) => { setTiers(prev => ({ ...prev, [tierId]: prev[tierId].filter(item => `${item.id}-item-${tierId}` !== itemId) })); }; // Reset the tier list const handleReset = () => { if (window.confirm('Are you sure you want to reset the tier list? This will remove all items.')) { setTiers(tierDefinitions.reduce((acc, tier) => { acc[tier.id] = []; return acc; }, {})); } }; // Export tier list as JSON const handleExport = () => { const dataStr = JSON.stringify({ title, tiers }); const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr); const exportFileDefaultName = `${title.replace(/\s+/g, '-').toLowerCase()}.json`; const linkElement = document.createElement('a'); linkElement.setAttribute('href', dataUri); linkElement.setAttribute('download', exportFileDefaultName); linkElement.click(); }; // Import tier list from JSON const handleImport = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { try { const { title: importedTitle, tiers: importedTiers } = JSON.parse(e.target.result); setTitle(importedTitle); setTiers(importedTiers); } catch (error) { alert('Error importing file. Please make sure it\'s a valid tier list JSON file.'); } }; reader.readAsText(file); } }; return (