DEV Community

Cover image for 🚨 Made a LIVE 2024 election counter! Enjoy
Asadbek Karimov
Asadbek Karimov

Posted on

🚨 Made a LIVE 2024 election counter! Enjoy

Live2024

Built a quick live 2024 Trump vs. Harrison counter. Pulling data from CNN’s live tracker into a simple, clean card. Most live trackers I found were cluttered with unnecessary components and text, so I created a streamlined version in just 5-10 minutes. Feel free to grab the code!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2024 US Election Counter</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .card {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            padding: 20px;
            text-align: center;
            max-width: 400px;
            width: 100%;
        }
        h1 {
            color: #333;
            font-size: 24px;
            margin-bottom: 10px;
        }
        p {
            color: #666;
            font-size: 14px;
            margin-bottom: 20px;
        }
        .counter-container {
            display: flex;
            justify-content: space-around;
        }
        .counter {
            text-align: center;
        }
        .counter h2 {
            font-size: 18px;
            margin-bottom: 10px;
        }
        .count {
            font-size: 36px;
            font-weight: bold;
            transition: all 0.5s ease;
        }
        .democrats {
            color: #0015bc;
        }
        .republicans {
            color: #ff0000;
        }
        .loading, .error {
            text-align: center;
            font-size: 18px;
            color: #666;
        }
        .error {
            color: #ff0000;
        }
        .vote-info {
            font-size: 14px;
            color: #555;
        }
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }

        .banner {
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #f8f8f8;
            text-align: center;
            border-top: 1px solid #ddd;
            padding-top:6px;
            padding-bottom: 6px;
            font-size: x-large;
            font-weight: 500;
            color: #171717;
        }

        .banner a {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div class="card">
        <h1>2024 US Election Counter</h1>
        <p>Live results updated every 10 seconds</p>
        <div id="content">
            <div class="loading">Loading...</div>
        </div>
    </div>


    <!-- Google tag (gtag.js) -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-W16Z0D8BJ7"></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());

    gtag('config', 'G-W16Z0D8BJ7');
    </script>

    <script>
        const content = document.getElementById('content');

        function updateCounter(party, count, percentage, votes) {
            const countElement = document.getElementById(`${party}-count`);
            if (countElement) {
                countElement.textContent = count;
                document.getElementById(`${party}-percentage`).textContent = `${percentage}%`;
                document.getElementById(`${party}-votes`).textContent = `Votes: ${votes}`;
                countElement.style.animation = 'pulse 0.5s ease';
                setTimeout(() => {
                    countElement.style.animation = '';
                }, 500);
            }
        }

        function renderCounters(democratsCount, republicansCount, demPercentage, repPercentage, demVotes, repVotes) {
            content.innerHTML = `
                <div class="counter-container">
                    <div class="counter">
                        <h2 class="democrats">Democrats</h2>
                        <div id="democrats-count" class="count democrats">${democratsCount}</div>
                        <div id="democrats-percentage" class="vote-info">${demPercentage}%</div>
                        <div id="democrats-votes" class="vote-info">Votes: ${demVotes}</div>
                    </div>
                    <div class="counter">
                        <h2 class="republicans">Republicans</h2>
                        <div id="republicans-count" class="count republicans">${republicansCount}</div>
                        <div id="republicans-percentage" class="vote-info">${repPercentage}%</div>
                        <div id="republicans-votes" class="vote-info">Votes: ${repVotes}</div>
                    </div>
                </div>
            `;
        }

        async function fetchElectionData() {
            try {
                const response = await fetch('https://politics.api.cnn.io/results/bop/2024-PG-US.json', {
                    headers: {
                        'accept': '*/*',
                        'accept-language': 'en-US,en;q=0.9',
                        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
                        'x-api-key': 'TtGlrrOrcdJNvE5U9t4XulVZuwk68Ecru3UIgtnr'
                    }
                });

                if (!response.ok) {
                    throw new Error('Failed to fetch election data');
                }

                const data = await response.json();

                // Extract the relevant counts, percentages, and vote numbers
                const democratsData = data.meta.candidates.DEM;
                const republicansData = data.meta.candidates.REP;

                const democratsCount = democratsData.count;
                const republicansCount = republicansData.count;
                const democratsPercentage = democratsData.votePercentStr;
                const republicansPercentage = republicansData.votePercentStr;
                const democratsVotes = democratsData.voteStr;
                const republicansVotes = republicansData.voteStr;

                // Render the counters or update them if they already exist
                if (content.querySelector('.counter-container')) {
                    updateCounter('democrats', democratsCount, democratsPercentage, democratsVotes);
                    updateCounter('republicans', republicansCount, republicansPercentage, republicansVotes);
                } else {
                    renderCounters(democratsCount, republicansCount, democratsPercentage, republicansPercentage, democratsVotes, republicansVotes);
                }
            } catch (error) {
                console.error('Error:', error);
                content.innerHTML = '<div class="error">Error fetching election data</div>';
            }
        }

        function startPolling() {
            fetchElectionData(); // Initial fetch on load
            setInterval(fetchElectionData, 10000); // Poll every 10 seconds
        }

        startPolling();
    </script>

    <div class="banner">
        Sponsored by <a href="https://mylinx.cc/" target="_blank">Mylinx</a>
    </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)