CoolFace
Apppublic

wuavy/comp-shell-tracker

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
index.html676 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4    <meta charset="UTF-8">5    <meta name="viewport" content="width=device-width, initial-scale=1.0">6    <title>Shell Tracker</title>7    <script src="https://cdn.tailwindcss.com"></script>8    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">9    <style>10        body {11            background: linear-gradient(135deg, #000033 0%, #0a0a2a 100%);12            min-height: 100vh;13            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;14        }15        16        .leaderboard-box {17            background: linear-gradient(135deg, #1a237e 0%, #0d47a1 100%);18            box-shadow: 0 15px 30px rgba(13, 71, 161, 0.2);19            border-radius: 12px;20            transform: perspective(1000px) rotateX(5deg);21            transition: all 0.3s ease;22        }23        24        .leaderboard-box:hover {25            transform: perspective(1000px) rotateX(0deg);26            box-shadow: 0 20px 40px rgba(13, 71, 161, 0.3);27        }28        29        .leaderboard-header {30            border-bottom: 2px solid rgba(255, 255, 255, 0.1);31            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);32        }33        34        .leaderboard-row {35            transition: all 0.2s ease;36            border-bottom: 1px solid rgba(255, 255, 255, 0.05);37            display: grid;38            grid-template-columns: 80px 2fr 1fr 1fr 1fr 80px;39            align-items: center;40        }41        42        .leaderboard-row:hover {43            background-color: rgba(255, 255, 255, 0.05);44            transform: translateX(5px);45        }46        47        .rank-1 {48            background: linear-gradient(90deg, rgba(255,215,0,0.15) 0%, rgba(255,215,0,0) 100%);49        }50        51        .rank-2 {52            background: linear-gradient(90deg, rgba(192,192,192,0.15) 0%, rgba(192,192,192,0) 100%);53        }54        55        .rank-3 {56            background: linear-gradient(90deg, rgba(205,127,50,0.15) 0%, rgba(205,127,50,0) 100%);57        }58        59        .pulse {60            animation: pulse 2s infinite;61        }62        63        @keyframes pulse {64            0% {65                box-shadow: 0 0 0 0 rgba(25, 118, 210, 0.5);66            }67            70% {68                box-shadow: 0 0 0 10px rgba(25, 118, 210, 0);69            }70            100% {71                box-shadow: 0 0 0 0 rgba(25, 118, 210, 0);72            }73        }74        75        .btn-primary {76            background: linear-gradient(135deg, #1565c0 0%, #0d47a1 100%);77            transition: all 0.3s ease;78        }79        80        .btn-primary:hover {81            transform: translateY(-2px);82            box-shadow: 0 5px 15px rgba(21, 101, 192, 0.3);83        }84        85        .btn-discord {86            background: linear-gradient(135deg, #7289da 0%, #5865a8 100%);87            transition: all 0.3s ease;88        }89        90        .btn-discord:hover {91            transform: translateY(-2px);92            box-shadow: 0 5px 15px rgba(114, 137, 218, 0.3);93        }94        95        .btn-edit {96            background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);97            transition: all 0.3s ease;98        }99        100        .btn-edit:hover {101            transform: translateY(-2px);102            box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);103        }104        105        .btn-remove {106            background: linear-gradient(135deg, #f44336 0%, #c62828 100%);107            transition: all 0.3s ease;108        }109        110        .btn-remove:hover {111            transform: translateY(-2px);112            box-shadow: 0 5px 15px rgba(244, 67, 54, 0.3);113        }114        115        .search-bar {116            background: rgba(255, 255, 255, 0.1);117            border: 1px solid rgba(255, 255, 255, 0.2);118            transition: all 0.3s ease;119        }120        121        .search-bar:focus {122            background: rgba(255, 255, 255, 0.15);123            box-shadow: 0 0 0 3px rgba(66, 165, 245, 0.3);124        }125        126        .modal-overlay {127            position: fixed;128            top: 0;129            left: 0;130            right: 0;131            bottom: 0;132            background-color: rgba(0, 0, 0, 0.7);133            display: flex;134            justify-content: center;135            align-items: center;136            z-index: 1000;137        }138        139        .modal-content {140            background: linear-gradient(135deg, #1a237e 0%, #0d47a1 100%);141            padding: 1.5rem;142            border-radius: 12px;143            max-width: 400px;144            width: 90%;145            box-shadow: 0 15px 30px rgba(13, 71, 161, 0.4);146            text-align: center;147        }148        149        .modal-close {150            position: absolute;151            top: 10px;152            right: 10px;153            background: none;154            border: none;155            color: white;156            font-size: 1.5rem;157            cursor: pointer;158        }159        160        .form-group {161            margin-bottom: 0.75rem;162            text-align: left;163        }164        165        .form-label {166            display: block;167            margin-bottom: 0.25rem;168            color: #90CAF9;169            font-weight: 500;170            font-size: 0.875rem;171        }172        173        .form-input {174            width: 100%;175            padding: 0.5rem;176            border-radius: 6px;177            border: 1px solid rgba(255, 255, 255, 0.2);178            background: rgba(255, 255, 255, 0.1);179            color: white;180            transition: all 0.3s ease;181            font-size: 0.875rem;182        }183        184        .form-input:focus {185            outline: none;186            background: rgba(255, 255, 255, 0.15);187            border-color: #42A5F5;188            box-shadow: 0 0 0 2px rgba(66, 165, 245, 0.2);189        }190        191        .staff-password {192            background: rgba(255, 0, 0, 0.1);193            border: 1px solid rgba(255, 0, 0, 0.3);194            margin-top: 1rem;195            padding: 0.75rem;196            border-radius: 6px;197        }198        199        .staff-label {200            color: #FF5252;201            font-weight: 600;202            font-size: 0.875rem;203        }204        205        .error-message {206            color: #FF5252;207            font-size: 0.75rem;208            margin-top: 0.25rem;209            display: none;210        }211        212        .hidden-row {213            display: none;214        }215        216        .header-row {217            display: grid;218            grid-template-columns: 80px 2fr 1fr 1fr 1fr 80px;219            align-items: center;220            padding: 0.75rem 1.5rem;221            font-weight: 600;222            text-transform: uppercase;223            font-size: 0.75rem;224            color: rgba(200, 200, 255, 0.8);225            border-bottom: 1px solid rgba(255, 255, 255, 0.1);226        }227        228        .password-modal {229            background: linear-gradient(135deg, #1a237e 0%, #0d47a1 100%);230            padding: 1.5rem;231            border-radius: 12px;232            max-width: 350px;233            width: 90%;234            box-shadow: 0 15px 30px rgba(13, 71, 161, 0.4);235            text-align: center;236        }237        238        .password-input {239            width: 100%;240            padding: 0.75rem;241            margin: 1rem 0;242            border-radius: 6px;243            border: 1px solid rgba(255, 255, 255, 0.2);244            background: rgba(255, 255, 255, 0.1);245            color: white;246            font-size: 1rem;247        }248        249        .password-error {250            color: #FF5252;251            font-size: 0.875rem;252            margin-top: 0.5rem;253            display: none;254        }255    </style>256</head>257<body class="flex items-center justify-center p-4">258    <div class="leaderboard-box w-full max-w-5xl overflow-hidden">259        <div class="leaderboard-header p-6 bg-gradient-to-r from-blue-900 to-blue-800">260            <div class="flex items-center justify-between">261                <h1 class="text-3xl font-bold text-white flex items-center">262                    <i class="fas fa-shell mr-3 text-blue-300"></i>263                    Shell Tracker264                </h1>265                <div class="flex space-x-4">266                    <button id="editBtn" class="btn-edit px-4 py-2 text-white rounded-lg font-semibold flex items-center">267                        <i class="fas fa-key mr-2"></i> Edit268                    </button>269                    <button id="registerBtn" class="btn-primary px-4 py-2 text-white rounded-lg font-semibold flex items-center">270                        <i class="fas fa-user-plus mr-2"></i> Register Now271                    </button>272                    <a href="https://discord.gg/DXDMurpuCW" target="_blank" class="btn-discord px-4 py-2 text-white rounded-lg font-semibold flex items-center">273                        <i class="fab fa-discord mr-2"></i> Join Discord274                    </a>275                </div>276            </div>277            278            <div class="mt-4 relative">279                <input type="text" 280                       id="searchInput"281                       placeholder="Search players..." 282                       class="search-bar w-full px-4 py-3 rounded-lg text-white placeholder-blue-200 focus:outline-none">283                <i class="fas fa-search absolute right-4 top-3.5 text-blue-200"></i>284            </div>285        </div>286        287        <div class="bg-blue-900 bg-opacity-20">288            <div class="header-row">289                <div>Rank</div>290                <div>Player</div>291                <div>PR</div>292                <div>Region</div>293                <div>Device</div>294                <div>Actions</div>295            </div>296            297            <div id="leaderboardContent" class="divide-y divide-blue-800 divide-opacity-50">298                <!-- Empty state -->299                <div class="py-12 text-center">300                    <i class="fas fa-user-slash text-4xl text-blue-400 opacity-50 mb-4"></i>301                    <h3 class="text-xl text-blue-200 font-medium">No players found</h3>302                    <p class="text-blue-300 mt-2">Start tracking players by registering above</p>303                </div>304            </div>305        </div>306        307        <div class="p-4 bg-blue-900 bg-opacity-30 flex justify-between items-center">308            <div class="text-blue-200 text-sm">309                Showing <span id="showingFrom" class="font-bold">0</span>-<span id="showingTo" class="font-bold">0</span> of <span id="totalPlayers" class="font-bold">0</span> players310            </div>311            <div class="flex space-x-2">312                <button class="px-3 py-1 bg-blue-800 bg-opacity-50 text-blue-200 rounded hover:bg-blue-700 transition" disabled>313                    <i class="fas fa-chevron-left"></i>314                </button>315                <button class="px-3 py-1 bg-blue-700 text-white rounded font-bold">316                    1317                </button>318                <button class="px-3 py-1 bg-blue-800 bg-opacity-50 text-blue-200 rounded hover:bg-blue-700 transition" disabled>319                    <i class="fas fa-chevron-right"></i>320                </button>321            </div>322        </div>323    </div>324 325    <!-- Coming Soon Modal -->326    <div id="comingSoonModal" class="modal-overlay hidden">327        <div class="modal-content relative">328            <button class="modal-close">&times;</button>329            <i class="fas fa-clock text-5xl text-blue-300 mb-4"></i>330            <h2 class="text-2xl font-bold text-white mb-2">Coming Soon!</h2>331            <p class="text-blue-200 mb-6">The registration feature will be available shortly. Stay tuned for updates!</p>332            <button class="btn-primary px-6 py-2 text-white rounded-lg font-semibold">333                Got it!334            </button>335        </div>336    </div>337 338    <!-- Edit Modal -->339    <div id="editModal" class="modal-overlay hidden">340        <div class="modal-content relative">341            <button class="modal-close">&times;</button>342            <i class="fas fa-user-edit text-4xl text-blue-300 mb-3"></i>343            <h2 class="text-xl font-bold text-white mb-3">Edit Player</h2>344            345            <form id="editForm">346                <div class="form-group">347                    <label for="playerName" class="form-label">Player Name</label>348                    <input type="text" id="playerName" class="form-input" required>349                    <div id="nameError" class="error-message">Please enter a player name</div>350                </div>351                352                <div class="form-group">353                    <label for="profilePic" class="form-label">Profile Picture URL</label>354                    <input type="url" id="profilePic" class="form-input" required>355                    <div id="picError" class="error-message">Please enter a valid URL</div>356                </div>357                358                <div class="form-group">359                    <label for="playerPR" class="form-label">Player PR</label>360                    <input type="number" id="playerPR" class="form-input" required>361                    <div id="prError" class="error-message">Please enter a valid PR</div>362                </div>363                364                <div class="form-group">365                    <label for="playerRank" class="form-label">Rank</label>366                    <input type="number" id="playerRank" class="form-input" required>367                    <div id="rankError" class="error-message">Please enter a valid rank</div>368                </div>369                370                <div class="form-group">371                    <label for="playerRegion" class="form-label">Region</label>372                    <select id="playerRegion" class="form-input" required>373                        <option value="">Select Region</option>374                        <option value="NA">North America</option>375                        <option value="EU">Europe</option>376                        <option value="AS">Asia</option>377                        <option value="SA">South America</option>378                        <option value="OC">Oceania</option>379                    </select>380                    <div id="regionError" class="error-message">Please select a region</div>381                </div>382                383                <div class="form-group">384                    <label for="playerDevice" class="form-label">Device</label>385                    <select id="playerDevice" class="form-input" required>386                        <option value="">Select Device</option>387                        <option value="Mobile">Mobile</option>388                        <option value="PC">PC</option>389                        <option value="Console">Console</option>390                    </select>391                    <div id="deviceError" class="error-message">Please select a device</div>392                </div>393                394                <div class="staff-password">395                    <label for="staffPassword" class="staff-label">Password (Staff Only)</label>396                    <input type="password" id="staffPassword" class="form-input mt-2" required>397                    <div id="passwordError" class="error-message">Incorrect password</div>398                </div>399                400                <button type="submit" class="btn-primary px-6 py-2 text-white rounded-lg font-semibold mt-4 w-full">401                    <i class="fas fa-check mr-2"></i> Finish402                </button>403            </form>404        </div>405    </div>406 407    <!-- Remove Password Modal -->408    <div id="removePasswordModal" class="modal-overlay hidden">409        <div class="password-modal relative">410            <button class="modal-close">&times;</button>411            <i class="fas fa-lock text-4xl text-blue-300 mb-3"></i>412            <h2 class="text-xl font-bold text-white mb-2">Confirm Removal</h2>413            <p class="text-blue-200 mb-4">Enter password to remove this player:</p>414            <input type="password" id="removePassword" class="password-input" placeholder="Enter password">415            <div id="removePasswordError" class="password-error">Incorrect password</div>416            <div class="flex space-x-4 mt-4">417                <button id="cancelRemove" class="px-4 py-2 bg-gray-600 text-white rounded-lg font-semibold flex-1">418                    Cancel419                </button>420                <button id="confirmRemove" class="px-4 py-2 btn-remove text-white rounded-lg font-semibold flex-1">421                    <i class="fas fa-trash-alt mr-2"></i> Remove422                </button>423            </div>424        </div>425    </div>426 427    <script>428        document.addEventListener('DOMContentLoaded', function() {429            const searchInput = document.getElementById('searchInput');430            const registerBtn = document.getElementById('registerBtn');431            const editBtn = document.getElementById('editBtn');432            const comingSoonModal = document.getElementById('comingSoonModal');433            const editModal = document.getElementById('editModal');434            const removePasswordModal = document.getElementById('removePasswordModal');435            const closeModals = document.querySelectorAll('.modal-close');436            const gotItBtn = document.querySelector('.comingSoonModal button');437            const editForm = document.getElementById('editForm');438            const leaderboardContent = document.getElementById('leaderboardContent');439            const showingFrom = document.getElementById('showingFrom');440            const showingTo = document.getElementById('showingTo');441            const totalPlayers = document.getElementById('totalPlayers');442            const cancelRemove = document.getElementById('cancelRemove');443            const confirmRemove = document.getElementById('confirmRemove');444            const removePassword = document.getElementById('removePassword');445            const removePasswordError = document.getElementById('removePasswordError');446            447            let players = [];448            let playerToRemove = null;449            450            // Search functionality451            searchInput.addEventListener('input', function() {452                const searchTerm = this.value.toLowerCase();453                const rows = leaderboardContent.querySelectorAll('.leaderboard-row');454                455                let visibleCount = 0;456                457                rows.forEach(row => {458                    const playerName = row.querySelector('div:nth-child(2) span').textContent.toLowerCase();459                    if (playerName.includes(searchTerm)) {460                        row.classList.remove('hidden-row');461                        visibleCount++;462                    } else {463                        row.classList.add('hidden-row');464                    }465                });466                467                updateShowingCount(visibleCount);468            });469            470            // Register button opens modal471            registerBtn.addEventListener('click', function() {472                comingSoonModal.classList.remove('hidden');473            });474            475            // Edit button opens modal476            editBtn.addEventListener('click', function() {477                editModal.classList.remove('hidden');478            });479            480            // Close modals481            closeModals.forEach(btn => {482                btn.addEventListener('click', function() {483                    comingSoonModal.classList.add('hidden');484                    editModal.classList.add('hidden');485                    removePasswordModal.classList.add('hidden');486                });487            });488            489            // Close modals when clicking outside490            [comingSoonModal, editModal, removePasswordModal].forEach(modal => {491                modal.addEventListener('click', function(e) {492                    if (e.target === modal) {493                        modal.classList.add('hidden');494                    }495                });496            });497            498            // Cancel remove499            cancelRemove.addEventListener('click', function() {500                removePasswordModal.classList.add('hidden');501                playerToRemove = null;502                removePassword.value = '';503                removePasswordError.style.display = 'none';504            });505            506            // Confirm remove507            confirmRemove.addEventListener('click', function() {508                if (removePassword.value === "Sub2beargm!") {509                    // Remove the player510                    removePlayer(playerToRemove);511                    removePasswordModal.classList.add('hidden');512                    removePassword.value = '';513                    removePasswordError.style.display = 'none';514                } else {515                    removePasswordError.style.display = 'block';516                }517            });518            519            // Edit form submission520            editForm.addEventListener('submit', function(e) {521                e.preventDefault();522                523                // Reset error messages524                document.querySelectorAll('.error-message').forEach(el => {525                    el.style.display = 'none';526                });527                528                // Validate form529                let isValid = true;530                const playerName = document.getElementById('playerName').value;531                const profilePic = document.getElementById('profilePic').value;532                const playerPR = document.getElementById('playerPR').value;533                const playerRank = document.getElementById('playerRank').value;534                const playerRegion = document.getElementById('playerRegion').value;535                const playerDevice = document.getElementById('playerDevice').value;536                const staffPassword = document.getElementById('staffPassword').value;537                538                if (!playerName) {539                    document.getElementById('nameError').style.display = 'block';540                    isValid = false;541                }542                543                if (!profilePic) {544                    document.getElementById('picError').style.display = 'block';545                    isValid = false;546                }547                548                if (!playerPR) {549                    document.getElementById('prError').style.display = 'block';550                    isValid = false;551                }552                553                if (!playerRank) {554                    document.getElementById('rankError').style.display = 'block';555                    isValid = false;556                }557                558                if (!playerRegion) {559                    document.getElementById('regionError').style.display = 'block';560                    isValid = false;561                }562                563                if (!playerDevice) {564                    document.getElementById('deviceError').style.display = 'block';565                    isValid = false;566                }567                568                // Check password569                if (staffPassword !== "Sub2beargm!") {570                    document.getElementById('passwordError').style.display = 'block';571                    isValid = false;572                }573                574                if (isValid) {575                    // Add player to players array576                    const newPlayer = {577                        name: playerName,578                        pic: profilePic,579                        pr: playerPR,580                        rank: playerRank,581                        region: playerRegion,582                        device: playerDevice583                    };584                    585                    players.push(newPlayer);586                    587                    // Update leaderboard588                    updateLeaderboard();589                    590                    // Close modal591                    editModal.classList.add('hidden');592                    593                    // Reset form594                    editForm.reset();595                }596            });597            598            function updateLeaderboard() {599                // Remove empty state if it exists600                if (leaderboardContent.querySelector('.py-12')) {601                    leaderboardContent.innerHTML = '';602                }603                604                // Clear current leaderboard605                leaderboardContent.innerHTML = '';606                607                // Sort players by rank608                players.sort((a, b) => a.rank - b.rank);609                610                // Add players to leaderboard611                players.forEach(player => {612                    const row = document.createElement('div');613                    row.className = `leaderboard-row px-6 py-4 rank-${player.rank}`;614                    615                    row.innerHTML = `616                        <div class="font-bold text-white">${player.rank}</div>617                        <div class="flex items-center">618                            <img src="${player.pic}" alt="${player.name}" class="w-10 h-10 rounded-full mr-3 object-cover">619                            <span class="text-white font-medium">${player.name}</span>620                        </div>621                        <div class="text-blue-200">${player.pr} PR</div>622                        <div class="text-blue-200">${player.region}</div>623                        <div class="text-blue-200">${player.device}</div>624                        <div class="flex justify-end">625                            <button class="btn-remove px-3 py-1 text-white rounded text-sm flex items-center remove-btn" data-player="${player.name}">626                                <i class="fas fa-trash-alt mr-1"></i> Remove627                            </button>628                        </div>629                    `;630                    631                    // Add to leaderboard632                    leaderboardContent.appendChild(row);633                });634                635                // Add event listeners to remove buttons636                document.querySelectorAll('.remove-btn').forEach(btn => {637                    btn.addEventListener('click', function() {638                        playerToRemove = this.getAttribute('data-player');639                        removePasswordModal.classList.remove('hidden');640                    });641                });642                643                // Update showing count644                updateShowingCount(players.length);645            }646            647            function removePlayer(playerName) {648                // Remove player from array649                players = players.filter(player => player.name !== playerName);650                651                // Update leaderboard652                updateLeaderboard();653                654                // If no players left, show empty state655                if (players.length === 0) {656                    leaderboardContent.innerHTML = `657                        <div class="py-12 text-center">658                            <i class="fas fa-user-slash text-4xl text-blue-400 opacity-50 mb-4"></i>659                            <h3 class="text-xl text-blue-200 font-medium">No players found</h3>660                            <p class="text-blue-300 mt-2">Start tracking players by registering above</p>661                        </div>662                    `;663                    664                    updateShowingCount(0);665                }666            }667            668            function updateShowingCount(count) {669                showingFrom.textContent = count > 0 ? '1' : '0';670                showingTo.textContent = count;671                totalPlayers.textContent = count;672            }673        });674    </script>675</body>676</html>