diff --git a/index.html b/index.html new file mode 100644 index 0000000..489e8c2 --- /dev/null +++ b/index.html @@ -0,0 +1,126 @@ + + + + + + + + LeetCode Leaderboard + + + +
+
+ +
+
+

TBPPP Leaderboard

+
+

PRASHANT PATHAK got accepted on "UNIQUE PATHS"

+
+ + +
+ + +
+ + + + + + + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + +
RankRoll NumberUpName + Section + + + Total Solved + + + Easy + + + Medium + + + Hard + + + Last question +
+ + + + + + +
+
+
+ }); + + + + + + \ No newline at end of file diff --git a/index.js b/index.js index e5ccb38..584da84 100644 --- a/index.js +++ b/index.js @@ -1,192 +1,835 @@ -const express = require('express'); -const fs = require('fs'); -const cors = require('cors'); -const axios = require('axios'); -const app = express(); -const port = 3001; - -app.use(cors()); - -// GraphQL query to fetch user stats (problem count by difficulty) -const userStatsQuery = ` - query userStats($username: String!) { - matchedUser(username: $username) { - username - submitStats: submitStatsGlobal { - acSubmissionNum { - difficulty - count - submissions - } - } - } - } -`; - -// GraphQL query to fetch recent submissions -const recentSubQuery = ` - query recentAcSubmissions($username: String!, $limit: Int!) { - recentAcSubmissionList(username: $username, limit: $limit) { - id - title - timestamp - statusDisplay - runtime - memory - lang - } - } -`; - -async function fetchLeet(username) { - const graphqlUrl = "https://leetcode.com/graphql"; - - try { - // Fetch user statistics (problem count by difficulty) - const statsResponse = await axios.post(graphqlUrl, { - query: userStatsQuery, - variables: { username }, - }); - - // Fetch recent submissions - const recentSubResponse = await axios.post(graphqlUrl, { - query: recentSubQuery, - variables: { username, limit: 5 }, - }); - - const userStats = statsResponse.data.data.matchedUser.submitStats.acSubmissionNum || []; - const recentSubmissions = recentSubResponse.data.data.recentAcSubmissionList || []; - - // Process user stats to get counts by difficulty - const stats = { - totalSolved: 0, - easySolved: 0, - mediumSolved: 0, - hardSolved: 0, - }; - - userStats.forEach(item => { - switch (item.difficulty) { - case "All": - stats.totalSolved = item.count; - break; - case "Easy": - stats.easySolved = item.count; - break; - case "Medium": - stats.mediumSolved = item.count; - break; - case "Hard": - stats.hardSolved = item.count; - break; - default: - break; - } - }); - - return { - stats, - recentSubmissions, - }; - } catch (error) { - console.error(`Error fetching data for ${username}:`, error); - return { - stats: { - totalSolved: 0, - easySolved: 0, - mediumSolved: 0, - hardSolved: 0, - }, - recentSubmissions: [], - }; - } -} - -async function fetchAndSaveData() { - try { - console.log('Starting to read input files...'); - const rolls = fs.readFileSync('roll.txt', 'utf-8').split('\n').map(line => line.trim()).filter(Boolean); - const names = fs.readFileSync('name.txt', 'utf-8').split('\n').map(line => line.trim()).filter(Boolean); - const urls = fs.readFileSync('urls.txt', 'utf-8').split('\n').map(line => line.trim()).filter(Boolean); - const sections = fs.readFileSync('sections.txt', 'utf-8').split('\n').map(line => line.trim()).filter(Boolean); - const day = fs.readFileSync('day.txt','utf-8').split('\n').map(line=>line.trim()).filter(Boolean); - - if (rolls.length !== names.length || names.length !== urls.length || names.length !== sections.length) { - console.error('Error: The number of rolls, names, URLs, and sections do not match.'); - return; - } - - console.log('Input files read successfully.'); - const combinedData = []; - - async function processStudentData(i) { - const roll = rolls[i]; - const name = names[i]; - const url = urls[i]; - const section = sections[i]; - const dayi = day[i]; - let studentData = { roll, name, url, section, dayi }; - - console.log(`Processing data for roll number: ${roll}, name: ${name}, section: ${section}, day: ${dayi}`); - - // Check if URL is a LeetCode URL - if (url.startsWith('https://leetcode.com/u/')) { - var username = url.split('/u/')[1]; - if (username.charAt(username.length - 1) == '/') username = username.substring(0, username.length - 1); - console.log(`Fetching data for LeetCode username: ${username}`); - - try { - // Fetch user stats and recent submissions using GraphQL API - const { stats, recentSubmissions } = await fetchLeet(username); - studentData = { - ...studentData, - username, - totalSolved: stats.totalSolved, - easySolved: stats.easySolved, - mediumSolved: stats.mediumSolved, - hardSolved: stats.hardSolved, - recentSubmissions, - }; - console.log(`Data for ${username} fetched and processed successfully.`); - } catch (error) { - console.error(`Error fetching data for ${username}:`, error); - } - } else { - console.log(`URL for ${name} is not a LeetCode profile. Skipping API call.`); - studentData.info = 'No LeetCode data available'; - } - - combinedData.push(studentData); - } - - const promises = []; - for (let i = 0; i < rolls.length; i++) { - promises.push(processStudentData(i)); - } - await Promise.all(promises); - - // Sort the data by totalSolved in descending order, treating 'NA' or invalid values as 0 - combinedData.sort((a, b) => { - const aTotalSolved = isNaN(a.totalSolved) ? 0 : a.totalSolved; - const bTotalSolved = isNaN(b.totalSolved) ? 0 : b.totalSolved; - return bTotalSolved - aTotalSolved; - }); - - fs.writeFileSync('data.json', JSON.stringify(combinedData, null, 2)); - console.log('Data saved to data.json successfully.'); - } catch (error) { - console.error('Error processing data:', error); - } -} - -app.get('/data', (req, res) => { - res.sendFile(__dirname + '/data.json'); -}); - -// Initial data fetch and periodic refresh every hour -fetchAndSaveData(); -setInterval(fetchAndSaveData, 60 * 60 * 1000); - -app.listen(port, () => { - console.log(`Server is running at http://localhost:${port}`); -}); +const oldData = { + "2215001289":1077, + "2215500064":863, + "2215001079":805, + "2215001867":794, + "2215001258":718, + "2215001596":683, + "2215002035":682, + "2215001352":660, + "2215001897":641, + "2215001541":640, + "2215001653":589, + "2215000728":542, + "2215800029":533, + "2215000438":517, + "2215500171":515, + "2215000598":513, + "2215000699":509, + "2215000884":505, + "2215000097":486, + "2215500088":483, + "2215001473":481, + "2215001545":478, + "2215500122":470, + "2215500076":463, + "2215000061":446, + "2215000333":433, + "2215500058":425, + "2215000974":424, + "2215001187":423, + "2215500096":421, + "2215001014":418, + "2215001780":412, + "2215001511":403, + "2215000872":399, + "2215001565":393, + "2215000242":393, + "2215000117":388, + "2215000201":378, + "2215001985":369, + "2215000523":366, + "2215001153":366, + "2215001670":364, + "2215800010":356, + "2215001904":355, + "2215800033":354, + "2215001606":353, + "2215000265":348, + "2215500165":348, + "2215001435":345, + "2215001815":340, + "2215000816":339, + "2215500103":335, + "2215000373":335, + "2215500054":329, + "2215001680":326, + "2215001889":325, + "2215001665":325, + "2215500104":323, + "2215000335":323, + "2215000940":321, + "2215000865":318, + "2215001736":317, + "2215000821":317, + "2215001913":316, + "2215000573":306, + "2215001994":305, + "2215001543":303, + "2215000429":300, + "2215000877":300, + "2215001504":299, + "2215001582":298, + "2215001840":294, + "2215500094":293, + "2215500148":293, + "2215500027":289, + "2215000328":287, + "2215000632":286, + "2215001706":282, + "2215001299":278, + "2215000954":277, + "2215000182":276, + "2215000958":274, + "2215001489":272, + "2215001116":269, + "2215000634":268, + "2215000785":267, + "2215001941":266, + "2215000399":265, + "2215001170":265, + "2215000164":264, + "2215001178":263, + "2215500173":261, + "2215001855":260, + "2215001717":260, + "2215800025":258, + "2215000155":256, + "2215001201":256, + "2215001229":256, + "2215800011":254, + "2215000011":254, + "2215001751":254, + "2215001812":253, + "2215500028":253, + "2215000906":251, + "2215002021":248, + "2215000286":248, + "2215000919":247, + "2215001494":246, + "2215500006":246, + "2215500166":246, + "2215000104":245, + "2215000170":245, + "2215000574":244, + "2215001092":242, + "2215001375":242, + "2215500052":240, + "2215002049":240, + "2215000105":235, + "2215001301":233, + "2215500040":232, + "2215001650":230, + "2215500038":230, + "2215001056":229, + "2215000531":224, + "2215001800":223, + "2215001777":223, + "2215001043":223, + "2215500030":222, + "2215000274":222, + "2215001122":222, + "2215000674":221, + "2215002007":216, + "2215000385":216, + "2215000490":215, + "2215001175":214, + "2215000555":213, + "2215000527":213, + "2215001257":213, + "2215500074":212, + "2215000670":211, + "2215500138":209, + "2215500107":204, + "2215000146":204, + "2215500067":204, + "2215000800":203, + "2215001225":202, + "2215001412":202, + "2215000679":200, + "2215500086":200, + "2215000956":198, + "2215000408":196, + "2215000478":196, + "2215000830":196, + "2215000883":195, + "2215000288":195, + "2215002024":194, + "2315990006":192, + "2215500174":191, + "2215000895":191, + "2215001069":190, + "2215000208":189, + "2215001772":189, + "2215000786":187, + "2215001468":186, + "2215001002":185, + "2215000259":185, + "2215001492":185, + "2215500141":184, + "2215001836":183, + "2215000620":183, + "2215001713":182, + "2215001444":178, + "2215001554":178, + "2215500087":177, + "2215001029":176, + "2215001073":174, + "2215000368":174, + "2215000939":172, + "2215000410":172, + "2215000319":171, + "2215000582":171, + "2215000909":169, + "2215001561":168, + "2215000918":168, + "2215001341":167, + "2215001152":167, + "2215001402":167, + "2215000952":166, + "2215000590":166, + "2215000689":166, + "2215500085":166, + "2215500093":164, + "2215000476":163, + "2215000340":160, + "2215001761":158, + "2215000907":158, + "2215500099":155, + "2215001725":154, + "2215000106":154, + "2215000316":152, + "2215000636":152, + "2215001111":152, + "2215500001":152, + "2215000860":151, + "2215001384":151, + "2215001359":150, + "2215001973":149, + "2215001361":148, + "2215000169":148, + "2215000372":148, + "2215000008":147, + "2215000966":147, + "2215000026":147, + "2215000470":146, + "2215000084":145, + "2215500077":144, + "2215000022":144, + "2215000622":142, + "2215001612":142, + "2215000436":141, + "2215500136":141, + "2215000119":140, + "2215000505":139, + "2215001709":138, + "2215500031":138, + "2215500115":138, + "2215001908":137, + "2215001193":136, + "2215000087":136, + "2215000363":136, + "2215500125":136, + "2215000583":135, + "2215001123":135, + "2215001886":135, + "2215000894":134, + "2215001020":132, + "2215500012":132, + "2215001281":130, + "2215000554":130, + "2215500112":130, + "2215001316":129, + "2215000908":129, + "2215001063":128, + "2215001368":128, + "2215500110":128, + "2215000716":127, + "2215002066":126, + "2215500179":125, + "2215000621":124, + "2215001569":124, + "2215000902":124, + "2215000255":124, + "2215000069":123, + "2215001230":123, + "2215001716":123, + "2215000601":122, + "2215000057":122, + "2215000248":121, + "2215001920":121, + "2215800016":121, + "2215000614":120, + "2215500123":120, + "2215500170":120, + "2215000312":119, + "2215000409":119, + "2215500160":118, + "2215500034":117, + "2215001125":116, + "2215001191":116, + "2215001605":116, + "2215500057":115, + "2215500161":115, + "2215000857":114, + "2215000747":113, + "2215001393":111, + "2215000912":111, + "2215000557":111, + "2215000714":111, + "2215000025":110, + "2215800007":110, + "2215000433":109, + "2215001893":109, + "2215001523":109, + "2215500089":106, + "2215500022":106, + "2215000607":106, + "2215500035":106, + "2215000337":105, + "2215000783":105, + "2215500102":105, + "2215500113":105, + "2215500177":105, + "2215001372":105, + "2215500078":105, + "2215001024":104, + "2215000174":104, + "2215001017":103, + "2215001564":103, + "2215000838":103, + "2215000052":102, + "2215000229":102, + "2215001829":102, + "2215001212":101, + "2215001279":101, + "2215001163":101, + "2215500146":100, + "2215500047":99, + "2215000665":99, + "2215000913":99, + "2215000302":98, + "2215500033":97, + "2215000037":97, + "2215000230":96, + "2215001513":95, + "2215800003":95, + "2215000810":95, + "2215000560":94, + "2215500008":94, + "2215000888":94, + "2215500009":93, + "2215001537":92, + "2215001134":92, + "2215500176":92, + "2215800006":92, + "2215000556":92, + "2215001508":91, + "2215001366":90, + "2215500139":90, + "2215000509":90, + "2215500156":90, + "2315990051":89, + "2215500135":89, + "2215000981":89, + "2215000473":88, + "2215000530":86, + "2215001732":86, + "2215000355":86, + "2215000300":86, + "2315990039":86, + "2215001339":84, + "2215800021":84, + "2215000211":83, + "2215500100":83, + "2215500127":82, + "2215001131":82, + "2215000681":82, + "2215500082":81, + "2215000773":80, + "2215500114":80, + "2215000483":80, + "2215800012":80, + "2215001559":80, + "2215001935":79, + "2215500071":79, + "2215000144":78, + "2215500025":78, + "2215000503":78, + "2215500132":77, + "2215001723":77, + "2215001323":77, + "2215001389":77, + "2215000095":77, + "2215000638":77, + "2215500108":77, + "2215500079":75, + "2215500150":75, + "2215500075":75, + "2215800027":75, + "2215000631":74, + "2215500056":74, + "2315990033":74, + "2215800018":74, + "2215500117":74, + "2215001775":73, + "2215500121":73, + "2215500168":73, + "2215500164":73, + "2215001906":72, + "2215000565":72, + "2215001644":72, + "2215500041":71, + "2215000392":71, + "2215001214":70, + "2215000801":70, + "2215001365":70, + "2215001265":70, + "2215000384":69, + "2215500023":69, + "2215000628":68, + "2215000992":67, + "2215000428":66, + "2215500175":66, + "2215001345":66, + "2215500133":66, + "2215000542":65, + "2215001943":65, + "2215000227":65, + "2215500101":65, + "2215500152":64, + "2215000698":64, + "2215500036":64, + "2215800032":64, + "2215000493":64, + "2215001593":64, + "2215800031":63, + "2215500032":63, + "2215001485":62, + "2215500020":62, + "2215500055":61, + "2215000792":61, + "2215001567":61, + "2215001926":61, + "2215001768":61, + "2215500014":60, + "2215000653":60, + "2215500080":60, + "2215500051":60, + "2215500172":59, + "2215000306":58, + "2215500109":58, + "2215500145":58, + "2215001643":58, + "2215800004":58, + "2215500069":58, + "2215000881":56, + "2215500018":55, + "2215500118":55, + "2215001293":55, + "2215500158":54, + "2215000903":53, + "2215500153":53, + "2215001924":52, + "2215500044":52, + "2215000571":51, + "2215001273":51, + "2215001235":51, + "2215001329":50, + "2215800008":50, + "2215500005":49, + "2215000081":49, + "2215001008":48, + "2215001781":47, + "2215000151":46, + "2215001140":46, + "2215002017":45, + "2215500015":45, + "2215500126":45, + "2215500048":43, + "2215500167":43, + "2215001403":43, + "2215500142":43, + "2215500130":42, + "2115500045":42, + "2215001597":42, + "2215001353":42, + "2215001763":41, + "2215500060":41, + "2115500102":41, + "2215500066":40, + "2215001053":40, + "2215001452":40, + "2215500091":39, + "2215500111":39, + "2215001505":39, + "2315990015":39, + "2215001557":38, + "2215001462":38, + "2215000283":38, + "2215500143":37, + "2215500154":37, + "2115500154":37, + "2215000419":36, + "2215001388":36, + "2215001130":36, + "2215001132":34, + "2215500017":34, + "2215001991":34, + "2215001117":34, + "2215001693":34, + "2215001443":33, + "2215001803":33, + "2215001205":33, + "2215500084":33, + "2215001832":32, + "2215500073":32, + "2215001295":31, + "2215800024":31, + "2215500010":31, + "2215500019":30, + "2215000423":30, + "2215001465":30, + "2215500151":30, + "2215800013":30, + "2215000401":30, + "2215001699":28, + "2215500131":28, + "2215000935":28, + "2215001413":28, + "2215000866":28, + "2215001599":27, + "2215500116":27, + "2215001718":27, + "2215500137":27, + "2215500043":26, + "2215500155":25, + "2215500081":25, + "2215500169":24, + "2215800026":24, + "2215500068":24, + "2215500162":23, + "2215000768":23, + "2215001972":22, + "2215500097":22, + "2215001860":22, + "2215500007":22, + "2215800028":21, + "2215000029":21, + "2215500140":21, + "2215000411":20, + "2215000953":20, + "2215000623":20, + "2215000861":19, + "2215001407":18, + "2215001711":18, + "2215500039":18, + "2215500124":18, + "2215500092":18, + "2215000135":17, + "2215500159":17, + "2215500053":17, + "2215001752":16, + "2215002036":16, + "2215000058":16, + "2215001774":16, + "2215000275":15, + "2215001377":15, + "2215800014":14, + "2215500013":14, + "2215001274":13, + "2215000039":13, + "2215800020":13, + "2215000484":12, + "2215000814":12, + "2215800019":11, + "2215000019":11, + "2215000765":11, + "2215000649":11, + "2215001669":10, + "2215500147":9, + "2215000445":8, + "2215000180":8, + "2215500021":8, + "2215800015":6, + "2215500042":6, + "2215500178":6, + "2215001109":5, + "2215001090":5, + "2215500065":4, + "2215000771":3, + "2215800002":3, + "2215800023":2, + "2215800030":2, + "2215800005":0, + "2215001189":0, + "2215000260":0, + "2215001169":0, + "2215000584":0, + "2215001022":0, + "2215001207":0, + "2215000002":0, + "2215001607":0, + "2215000818":0, + "2215001135":0, + "2215001202":0, + "2215001733":0, + "2115800013":0, + "2215800009":0, + "2215000338":0, + "2215000354":0, + "2215000488":0, + "2215000040":0, + "2215001629":0, + "2215000237":0, + "2215500016":0, + "2215500059":0, + "2215500046":0, + "2215500144":0, + "2215500098":0, + "2215000971":0, + "2215000295":0, + "2215000167":0, + "2315990027":0, + "2215800017":0, + "2215800022":0, + "2215000018":0, + "2215001506":0, + "2215000477":0, + "2215000183":0, + "2215500062":0, + "2215001744":0, + "2215001642":0, + "2315990047":0, + "2215500134":0, + "2215500049":0, + "2215500083":0, + "2215500004":0, + "2215000426":0, + "2215000460":0, + "2215500011":0, + "2215500163":0, + "2215500105":0, + "2215500129":0, + "2215500157":0, + "2215500119":0, + "2215500037":0, + "2215500002":0, + "2215500149":0, + "2215500045":0, + }; + console.log(oldData["2215001289"]); +document.addEventListener('DOMContentLoaded', async () => { + try { + + + const response = await fetch("http://localhost:3001/data"); + const data = await response.json(); + let filteredData = [...data]; // Keep original data separate + let yashData = [...data]; + const leaderboardBody = document.getElementById('leaderboard-body'); + const sectionFilter = document.getElementById('section-filter'); + var host =0; + var day =0; + yashData.forEach(myFunction); + + function myFunction(item) { + if(item.dayi==='Day Scholars') host+=1; + else day+=1; + } + console.log(host); + console.log(day); + + const xValues = ["Hostellers", "Day Scholars",]; + const yValues = [311,307]; + const barColors = [ + "#b91d47", + "#00aba9", + ]; + + // new Chart("myChart", { + // type: "pie", + // data: { + // labels: xValues, + // datasets: [{ + // backgroundColor: barColors, + // data: yValues + // }] + // }, + // options: { + // title: { + // display: true, + // text: "Hostellers and DaySchollars" + // } + // } + // }); + + + // Populate section filter dropdown + const populateSectionFilter = () => { + // var sections = [...new Set(data.map(student => student.section || 'N/A'))].sort(); + const sections = ['A(H)','AC','AD','AE','C','D','E','F','G','H','Day Scholars','Hostellers']; + sectionFilter.innerHTML = ''; + sections.forEach(section => { + const option = document.createElement('option'); + option.value = section; + option.textContent = section; + sectionFilter.appendChild(option); + }); + }; + + // Function to export data to CSV + const exportToCSV = (data) => { + const headers = ['Rank', 'Roll Number','up', 'Name', 'Section', 'Total Solved', 'Easy', 'Medium', 'Hard', 'LeetCode URL','Last question']; + const csvRows = data.map((student, index) => { + return [ + index + 1, + student.roll, + student.name, + student.section || 'N/A', + student.totalSolved || 'N/A', + student.easySolved || 'N/A', + student.mediumSolved || 'N/A', + student.hardSolved || 'N/A', + student.url + ].join(','); + }); + + const csvContent = [headers.join(','), ...csvRows].join('\n'); + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + const url = URL.createObjectURL(blob); + link.setAttribute('href', url); + link.setAttribute('download', 'leaderboard.csv'); + link.style.display = 'none'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + + // Function to render the leaderboard + const renderLeaderboard = (sortedData) => { + leaderboardBody.innerHTML = ''; + sortedData.forEach((student, index) => { + const row = document.createElement('tr'); + var diff = student.totalSolved - oldData[student.roll]; + var utcSeconds=0; + var d; + if( diff === student.totalSolved) diff =0; + if(student.recentSubmissions){ + if(student.recentSubmissions.length > 0){ + val = student.recentSubmissions[0].title || ''; + utcSeconds = student.recentSubmissions[0].timestamp || 0;; + d = new Date(0); // The 0 there is the key, which sets the date to the epoch + d.setUTCSeconds(utcSeconds); + }else {val = "" } + }else{ + val=""; + utcSeconds = ""; + } + + // console.log(student.name + " question " + val ? val : "" + " date " + d ? d : ""); + // console.log(diff); + row.classList.add('border-b', 'border-gray-700'); + row.innerHTML = ` + ${index + 1} + ${student.roll} + ${(diff>0)? " \u2191 " + diff : diff} + + ${student.url.startsWith('https://leetcode.com/u/') + ? `${student.name}` + : `
${student.name}
`} + + ${student.section || 'N/A'} + ${student.totalSolved || 'N/A'} + ${student.easySolved || 'N/A'} + ${student.mediumSolved || 'N/A'} + ${student.hardSolved || 'N/A'} + + ${val ? val : "Not found"} + at +
+ ${d ? d : "Unknown date"} + + + `; + leaderboardBody.appendChild(row); + }); + }; + + // Filter function + const filterData = (section) => { + filteredData = section === 'all' + ? [...data] + : data.filter(student => ((((student.section || 'N/A') === section)) || ((student.dayi || 'N/A') === section))); + renderLeaderboard(filteredData); + }; + + // Sorting logic with ascending and descending functionality + let totalSolvedDirection = 'desc'; + let easySolvedDirection = 'desc'; + let mediumSolvedDirection = 'desc'; + let hardSolvedDirection = 'desc'; + let sectionDirection = 'asc'; + + const sortData = (data, field, direction, isNumeric = false) => { + return data.sort((a, b) => { + const valA = a[field] || (isNumeric ? 0 : 'Z'); + const valB = b[field] || (isNumeric ? 0 : 'Z'); + if (isNumeric) { + return direction === 'desc' ? valB - valA : valA - valB; + } else { + return direction === 'desc' + ? valB.toString().localeCompare(valA.toString()) + : valA.toString().localeCompare(valB.toString()); + } + }); + }; + + // Initialize the page + populateSectionFilter(); + renderLeaderboard(data); + + // Event Listeners + sectionFilter.addEventListener('change', (e) => { + filterData(e.target.value); + }); + + document.getElementById('export-btn').addEventListener('click', () => { + exportToCSV(filteredData); // Export only filtered data + }); + + document.getElementById('sort-section').addEventListener('click', () => { + sectionDirection = sectionDirection === 'desc' ? 'asc' : 'desc'; + const sortedData = sortData(filteredData, 'section', sectionDirection, false); + renderLeaderboard(sortedData); + }); + + document.getElementById('sort-total').addEventListener('click', () => { + totalSolvedDirection = totalSolvedDirection === 'desc' ? 'asc' : 'desc'; + const sortedData = sortData(filteredData, 'totalSolved', totalSolvedDirection, true); + renderLeaderboard(sortedData); + }); + + document.getElementById('sort-easy').addEventListener('click', () => { + easySolvedDirection = easySolvedDirection === 'desc' ? 'asc' : 'desc'; + const sortedData = sortData(filteredData, 'easySolved', easySolvedDirection, true); + renderLeaderboard(sortedData); + }); + + document.getElementById('sort-medium').addEventListener('click', () => { + mediumSolvedDirection = mediumSolvedDirection === 'desc' ? 'asc' : 'desc'; + const sortedData = sortData(filteredData, 'mediumSolved', mediumSolvedDirection, true); + renderLeaderboard(sortedData); + }); + + document.getElementById('sort-hard').addEventListener('click', () => { + hardSolvedDirection = hardSolvedDirection === 'desc' ? 'asc' : 'desc'; + const sortedData = sortData(filteredData, 'hardSolved', hardSolvedDirection, true); + renderLeaderboard(sortedData); + }); + + } catch (error) { + console.error('Error fetching data:', error); + } +}); \ No newline at end of file