JSFiddle - React, Tailwind, and code Playground

by dshilkret

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tournament Bracket Survey</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>Tournament Bracket Survey</h1>
    <div id="survey-form">
        <h2>Enter your favorite bands or politicians</h2>
        <form id="input-form">
            <div id="input-fields">
                <input type="text" name="entry" placeholder="Entry 1">
                <input type="text" name="entry" placeholder="Entry 2">
                <input type="text" name="entry" placeholder="Entry 3">
                <input type="text" name="entry" placeholder="Entry 4">
                <input type="text" name="entry" placeholder="Entry 5">
                <input type="text" name="entry" placeholder="Entry 6">
                <input type="text" name="entry" placeholder="Entry 7">
                <input type="text" name="entry" placeholder="Entry 8">
            </div>
            <button type="button" onclick="generateBracket()">Generate Bracket</button>
        </form>
    </div>
    <div id="bracket-container"></div>

    <script src="script.js"></script>
</body>
</html>

CSS

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

#survey-form, #bracket-container {
    margin: 20px;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 8px;
    width: 80%;
    max-width: 600px;
}

#input-fields input {
    display: block;
    margin: 10px 0;
    padding: 10px;
    width: 100%;
}

.bracket {
    display: flex;
    justify-content: space-between;
    margin: 20px 0;
}

.round {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.match {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 10px 0;
    padding: 10px;
    border: 1px solid #000;
    border-radius: 4px;
}

.entry {
    cursor: pointer;
    padding: 5px;
    margin: 5px 0;
    border: 1px solid #ccc;
    border-radius: 4px;
}

.winner {
    background-color: #cfc;
}

.loser {
    background-color: #fcc;
}

JavaScript

function generateBracket() {
    const form = document.getElementById('input-form');
    const entries = Array.from(form.elements)
        .filter(el => el.name === 'entry' && el.value.trim() !== '')
        .map(el => el.value.trim());

    if (entries.length < 2 || (entries.length & (entries.length - 1)) !== 0) {
        alert('Please enter a number of entries that is a power of 2 (e.g., 4, 8, 16, etc.).');
        return;
    }

    const shuffledEntries = shuffleArray(entries);
    const bracketContainer = document.getElementById('bracket-container');
    bracketContainer.innerHTML = '';
    createBracket(shuffledEntries, bracketContainer);
}

function shuffleArray(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;
}

function createBracket(entries, container) {
    const rounds = Math.log2(entries.length);
    let roundEntries = [...entries];

    for (let i = 0; i < rounds; i++) {
        const roundContainer = document.createElement('div');
        roundContainer.className = 'round';
        for (let j = 0; j < roundEntries.length; j += 2) {
            const matchContainer = document.createElement('div');
            matchContainer.className = 'match';
            const entry1 = createDraggableEntry(roundEntries[j]);
            const entry2 = createDraggableEntry(roundEntries[j + 1]);
            matchContainer.appendChild(entry1);
            matchContainer.appendChild(entry2);
            roundContainer.appendChild(matchContainer);
        }
        container.appendChild(roundContainer);
        roundEntries = roundEntries.filter((_, index) => index % 2 === 0);
    }
}

function createDraggableEntry(name) {
    const entry = document.createElement('div');
    entry.textContent = name;
    entry.className = 'entry';
    entry.draggable = true;
    entry.addEventListener('dragstart', dragStart);
   ...