Spaces:
Running
Running
| document.addEventListener('DOMContentLoaded', () => { | |
| // DOM Elements | |
| const personInput = document.getElementById('personInput'); | |
| const addPersonBtn = document.getElementById('addPersonBtn'); | |
| const peopleList = document.getElementById('peopleList'); | |
| const clearListBtn = document.getElementById('clearListBtn'); | |
| const importBtn = document.getElementById('importBtn'); | |
| const exportBtn = document.getElementById('exportBtn'); | |
| const groupSize = document.getElementById('groupSize'); | |
| const shuffleMethod = document.getElementById('shuffleMethod'); | |
| const generateBtn = document.getElementById('generateBtn'); | |
| const resultsSection = document.getElementById('resultsSection'); | |
| const groupsContainer = document.getElementById('groupsContainer'); | |
| const copyResultsBtn = document.getElementById('copyResultsBtn'); | |
| // Load people from localStorage | |
| let people = JSON.parse(localStorage.getItem('groupGeniePeople')) || []; | |
| // Render people list | |
| function renderPeopleList() { | |
| peopleList.innerHTML = ''; | |
| people.forEach((person, index) => { | |
| const li = document.createElement('li'); | |
| li.className = 'flex justify-between items-center bg-gray-50 p-2 rounded'; | |
| li.innerHTML = ` | |
| <span>${person}</span> | |
| <button data-index="${index}" class="text-red-500 hover:text-red-700"> | |
| <i data-feather="x"></i> | |
| </button> | |
| `; | |
| peopleList.appendChild(li); | |
| }); | |
| feather.replace(); | |
| } | |
| // Add person(s) to list | |
| function addPerson() { | |
| const input = personInput.value.trim(); | |
| if (input.includes(',') || input.includes(' ') || input.includes('\n')) { | |
| addMultiplePeople(input); | |
| } else if (input && !people.includes(input)) { | |
| people.push(input); | |
| localStorage.setItem('groupGeniePeople', JSON.stringify(people)); | |
| } | |
| personInput.value = ''; | |
| renderPeopleList(); | |
| } | |
| // Remove person from list | |
| function removePerson(index) { | |
| people.splice(index, 1); | |
| localStorage.setItem('groupGeniePeople', JSON.stringify(people)); | |
| renderPeopleList(); | |
| } | |
| // Clear all people | |
| function clearPeople() { | |
| if (confirm('Are you sure you want to clear all people?')) { | |
| people = []; | |
| localStorage.removeItem('groupGeniePeople'); | |
| renderPeopleList(); | |
| } | |
| } | |
| // Import people from text with multiple separators (comma, space, or newline) | |
| function importPeople() { | |
| const text = prompt('Enter names separated by commas, spaces, or new lines:'); | |
| if (text) { | |
| const newPeople = text.split(/[\n,\s]+/) // Split by comma, space, or newline | |
| .map(name => name.trim()) | |
| .filter(name => name); | |
| people = [...new Set([...people, ...newPeople])]; | |
| localStorage.setItem('groupGeniePeople', JSON.stringify(people)); | |
| renderPeopleList(); | |
| } | |
| } | |
| // Add multiple people from input | |
| function addMultiplePeople(names) { | |
| const newPeople = names.split(/[\n,\s]+/) | |
| .map(name => name.trim()) | |
| .filter(name => name); | |
| newPeople.forEach(name => { | |
| if (name && !people.includes(name)) { | |
| people.push(name); | |
| } | |
| }); | |
| localStorage.setItem('groupGeniePeople', JSON.stringify(people)); | |
| renderPeopleList(); | |
| } | |
| // Export people to clipboard | |
| function exportPeople() { | |
| navigator.clipboard.writeText(people.join('\n')) | |
| .then(() => alert('People list copied to clipboard!')) | |
| .catch(err => console.error('Failed to copy:', err)); | |
| } | |
| // Fisher-Yates shuffle algorithm | |
| function fisherYatesShuffle(array) { | |
| for (let i = array.length - 1; i > 0; i--) { | |
| const j = Math.floor(Math.random() * (i + 1)); | |
| [array[i], array[j]] = [array[j], array[i]]; | |
| } | |
| return array; | |
| } | |
| // Random sort shuffle (less reliable) | |
| function randomSortShuffle(array) { | |
| return array.sort(() => Math.random() - 0.5); | |
| } | |
| // Generate groups | |
| function generateGroups() { | |
| if (people.length === 0) { | |
| alert('Please add some people first!'); | |
| return; | |
| } | |
| const membersPerGroup = parseInt(groupSize.value) || 3; | |
| if (membersPerGroup < 1) { | |
| alert('Members per group must be at least 1'); | |
| return; | |
| } | |
| // Shuffle based on selected method | |
| const shuffledPeople = shuffleMethod.value === 'fisher-yates' | |
| ? fisherYatesShuffle([...people]) | |
| : randomSortShuffle([...people]); | |
| // Create groups | |
| const groups = []; | |
| for (let i = 0; i < shuffledPeople.length; i += membersPerGroup) { | |
| groups.push(shuffledPeople.slice(i, i + membersPerGroup)); | |
| } | |
| // Display groups | |
| displayGroups(groups); | |
| } | |
| // Display groups in UI | |
| function displayGroups(groups) { | |
| groupsContainer.innerHTML = ''; | |
| groups.forEach((group, index) => { | |
| const groupCard = document.createElement('div'); | |
| groupCard.className = `group-card bg-group-${(index % 6) + 1} p-4 rounded-lg shadow-sm`; | |
| groupCard.innerHTML = ` | |
| <h3 class="font-bold text-lg mb-3">Group ${index + 1}</h3> | |
| <ul class="space-y-2"> | |
| ${group.map(member => `<li class="flex items-center gap-2"><i data-feather="user" class="w-4 h-4"></i> ${member}</li>`).join('')} | |
| </ul> | |
| `; | |
| groupsContainer.appendChild(groupCard); | |
| }); | |
| resultsSection.classList.remove('hidden'); | |
| feather.replace(); | |
| } | |
| // Copy results to clipboard | |
| function copyResults() { | |
| const groupElements = document.querySelectorAll('#groupsContainer > div'); | |
| let text = ''; | |
| groupElements.forEach((group, index) => { | |
| text += `Group ${index + 1}:\n`; | |
| const members = group.querySelectorAll('li'); | |
| members.forEach(member => { | |
| text += `- ${member.textContent.trim()}\n`; | |
| }); | |
| text += '\n'; | |
| }); | |
| navigator.clipboard.writeText(text.trim()) | |
| .then(() => alert('Groups copied to clipboard!')) | |
| .catch(err => console.error('Failed to copy:', err)); | |
| } | |
| // Event listeners | |
| addPersonBtn.addEventListener('click', (e) => { | |
| addPerson(); | |
| e.preventDefault(); // Prevent form submission if in a form | |
| }); | |
| personInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| addPerson(); | |
| e.preventDefault(); // Prevent form submission if in a form | |
| } | |
| }); | |
| peopleList.addEventListener('click', (e) => { | |
| if (e.target.closest('button')) { | |
| const index = e.target.closest('button').dataset.index; | |
| removePerson(index); | |
| } | |
| }); | |
| clearListBtn.addEventListener('click', clearPeople); | |
| importBtn.addEventListener('click', importPeople); | |
| exportBtn.addEventListener('click', exportPeople); | |
| generateBtn.addEventListener('click', generateGroups); | |
| copyResultsBtn.addEventListener('click', copyResults); | |
| // Initial render | |
| renderPeopleList(); | |
| }); |