Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Player: Difference between revisions

From eSportsAmaze
No edit summary
No edit summary
Line 35: Line 35:
end
end


-- [[ FIX: ROBUST RANK LOOKUP ]]
-- Rank Lookup
-- Checks BOTH "Players/Jonathan" AND "Jonathan"
local function getKraftonRank(fullPageName, displayName)
local function getKraftonRank(fullPageName, displayName)
     local sqlFull = fullPageName:gsub("'", "\\'")
     local sqlFull = fullPageName:gsub("'", "\\'")
     local sqlShort = displayName:gsub("'", "\\'")
     local sqlShort = displayName:gsub("'", "\\'")
   
     local whereClause = string.format("(name = '%s' OR name = '%s') AND type='Player'", sqlFull, sqlShort)
     local whereClause = string.format("(name = '%s' OR name = '%s') AND type='Player'", sqlFull, sqlShort)
   
     local results = cargo.query("Krafton_Rankings", "rank", { where = whereClause, limit = 1 })
     local results = cargo.query("Krafton_Rankings", "rank", { where = whereClause, limit = 1 })
   
     if results and #results > 0 then  
     if results and #results > 0 then  
         return "#" .. results[1].rank  
         return "#" .. results[1].rank  
Line 53: Line 49:


-- ============================================================
-- ============================================================
-- MAIN 1: PLAYER INFOBOX (WITH RANK FIX)
-- MAIN 1: PLAYER INFOBOX (WITH EARNINGS BREAKDOWN)
-- ============================================================
-- ============================================================
function p.infobox(frame)
function p.infobox(frame)
Line 59: Line 55:
      
      
     -- Variables
     -- Variables
     local fullPageName = mw.title.getCurrentTitle().text -- Players/Jonathan
     local fullPageName = mw.title.getCurrentTitle().text
     local displayName = args.id or mw.title.getCurrentTitle().subpageText -- Jonathan
     local displayName = args.id or mw.title.getCurrentTitle().subpageText
     local image = args.image or ""
     local image = args.image or ""
      
      
Line 77: Line 73:
     end
     end
      
      
     -- 3. EARNINGS CALCULATION (Robust)
     -- 3. EARNINGS CALCULATION (SEPARATED)
     local totalEarnings = 0
     local individualEarnings = 0
    local teamEarnings = 0
     local sqlNameFull = fullPageName:gsub("'", "\\'")
     local sqlNameFull = fullPageName:gsub("'", "\\'")
     local sqlNameShort = displayName:gsub("'", "\\'")
     local sqlNameShort = displayName:gsub("'", "\\'")
Line 87: Line 84:
         local pResults = cargo.query("PrizeMoney", "SUM(prize)=total", { where = pWhere })
         local pResults = cargo.query("PrizeMoney", "SUM(prize)=total", { where = pWhere })
         if pResults and #pResults > 0 and pResults[1].total then
         if pResults and #pResults > 0 and pResults[1].total then
             totalEarnings = totalEarnings + (tonumber(pResults[1].total) or 0)
             individualEarnings = (tonumber(pResults[1].total) or 0)
         end
         end
     end
     end
      
      
     -- PART B: TEAM WINNINGS (Verified via Roster)
     -- PART B: TEAM WINNINGS
     if cargo and cargo.query then
     if cargo and cargo.query then
         local rosterTable = "Tournament_Teams"
         local rosterTable = "Tournament_Teams"
Line 116: Line 113:
                  
                  
                 if teamPrizes and #teamPrizes > 0 and teamPrizes[1].team_total then
                 if teamPrizes and #teamPrizes > 0 and teamPrizes[1].team_total then
                     totalEarnings = totalEarnings + (tonumber(teamPrizes[1].team_total) or 0)
                     teamEarnings = (tonumber(teamPrizes[1].team_total) or 0)
                 end
                 end
             end
             end
         end
         end
     end
     end
    -- Calculate Total
    local totalEarnings = individualEarnings + teamEarnings


     -- 4. Status & Rank Grid
     -- 4. Status & Rank Grid
Line 135: Line 135:
     grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Status'):done():tag('div'):addClass('fib-value-sm'):css('color', statusColor):wikitext(statusText):done()
     grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Status'):done():tag('div'):addClass('fib-value-sm'):css('color', statusColor):wikitext(statusText):done()
      
      
    -- [[ FIX: PASS BOTH NAMES TO RANK FUNCTION ]]
     local rankVal = getKraftonRank(fullPageName, displayName)
     local rankVal = getKraftonRank(fullPageName, displayName)
     grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Krafton Rank'):done():tag('div'):addClass('fib-value-sm'):wikitext(rankVal):done()
     grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Krafton Rank'):done():tag('div'):addClass('fib-value-sm'):wikitext(rankVal):done()
Line 144: Line 143:
     grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Role'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.role or 'Player'):done()
     grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Role'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.role or 'Player'):done()


     -- 6. Earnings (Highlight)
     -- 6. Earnings (Highlight WITH BREAKDOWN)
     if totalEarnings > 0 then
     if totalEarnings > 0 then
         root:tag('div'):addClass('fib-prize')
         local prizeBox = root:tag('div'):addClass('fib-prize')
            :tag('div'):addClass('fib-label-sm'):wikitext('Approx. Earnings'):done()
       
            :tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(totalEarnings)):done()
        -- Main Total
        prizeBox:tag('div'):addClass('fib-label-sm'):wikitext('Approx. Earnings'):done()
        prizeBox:tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(totalEarnings)):done()
       
        -- Breakdown Sub-Section
        local breakdown = prizeBox:tag('div')
            :css('display', 'flex')
            :css('justify-content', 'space-between')
            :css('margin-top', '8px')
            :css('padding-top', '6px')
            :css('border-top', '1px solid rgba(0,0,0,0.08)')
       
        -- Team Winnings (Left)
        local tDiv = breakdown:tag('div'):css('text-align', 'left')
        tDiv:tag('div'):css('font-size', '0.65em'):css('text-transform', 'uppercase'):css('opacity', '0.7'):wikitext('From Team'):done()
        tDiv:tag('div'):css('font-size', '0.85em'):css('font-weight', '600'):wikitext(formatCurrency(teamEarnings)):done()
       
        -- Individual Winnings (Right)
        local iDiv = breakdown:tag('div'):css('text-align', 'right')
        iDiv:tag('div'):css('font-size', '0.65em'):css('text-transform', 'uppercase'):css('opacity', '0.7'):wikitext('Individual'):done()
        iDiv:tag('div'):css('font-size', '0.85em'):css('font-weight', '600'):wikitext(formatCurrency(individualEarnings)):done()
     end
     end
      
      
Line 184: Line 203:
         end
         end
     else
     else
        -- Fallback check for short name
         local historyShort = cargo.query("Player_Former_Teams", "team, join_date, leave_date", {  
         local historyShort = cargo.query("Player_Former_Teams", "team, join_date, leave_date", {  
             where = "player_id = '" .. displayName:gsub("'", "\\'") .. "'",
             where = "player_id = '" .. displayName:gsub("'", "\\'") .. "'",
Line 208: Line 228:


-- ============================================================
-- ============================================================
-- MAIN 2: FORMER PLAYERS TABLE (For Team Pages)
-- MAIN 2: FORMER PLAYERS TABLE
-- ============================================================
-- ============================================================
function p.formerPlayers(frame)
function p.formerPlayers(frame)

Revision as of 18:11, 28 January 2026

Documentation for this module may be created at Module:Player/doc

local p = {}
local cargo = mw.ext.cargo
local html = mw.html

-- ============================================================
-- HELPER FUNCTIONS
-- ============================================================

-- Currency Formatter
local function formatCurrency(amount)
    if not amount then return "0" end
    local n = tonumber(amount) or 0
    local formatted = tostring(n):reverse():gsub("(%d%d%d)(%d%d%d)","%1,%2"):reverse()
    return '<span class="indian-currency">₹ ' .. formatted .. '</span>'
end

-- Social Icons
local function getSocials(args)
    local container = html.create('div'):addClass('fib-socials')
    local hasSocials = false
    local platforms = {
        {arg='instagram', file='Icon_instagram.png'},
        {arg='twitter',   file='Icon_twitter.png'},
        {arg='youtube',   file='Icon_youtube.png'},
        {arg='discord',   file='Icon_discord.png'},
        {arg='facebook',  file='Icon_facebook.png'}
    }
    for _, p in ipairs(platforms) do
        if args[p.arg] and args[p.arg] ~= "" then
            hasSocials = true
            container:wikitext('[[File:' .. p.file .. '|24px|link=' .. args[p.arg] .. '|class=social-img]]')
        end
    end
    if hasSocials then return tostring(container) else return "" end
end

-- Rank Lookup
local function getKraftonRank(fullPageName, displayName)
    local sqlFull = fullPageName:gsub("'", "\\'")
    local sqlShort = displayName:gsub("'", "\\'")
    local whereClause = string.format("(name = '%s' OR name = '%s') AND type='Player'", sqlFull, sqlShort)
    local results = cargo.query("Krafton_Rankings", "rank", { where = whereClause, limit = 1 })
    if results and #results > 0 then 
        return "#" .. results[1].rank 
    else 
        return "Unranked" 
    end
end

-- ============================================================
-- MAIN 1: PLAYER INFOBOX (WITH EARNINGS BREAKDOWN)
-- ============================================================
function p.infobox(frame)
    local args = frame:getParent().args
    
    -- Variables
    local fullPageName = mw.title.getCurrentTitle().text
    local displayName = args.id or mw.title.getCurrentTitle().subpageText
    local image = args.image or ""
    
    local root = html.create('div'):addClass('flat-infobox')
    
    -- 1. Header
    root:tag('div'):addClass('fib-header')
        :tag('div'):addClass('fib-title'):wikitext(displayName)
    
    -- 2. Image
    local imgContainer = root:tag('div'):addClass('fib-image')
    if image ~= "" then
        imgContainer:wikitext('[[File:' .. image .. '|250px]]')
    else
        imgContainer:wikitext('[[File:Player_Placeholder.png|200px|link=]]')
    end
    
    -- 3. EARNINGS CALCULATION (SEPARATED)
    local individualEarnings = 0
    local teamEarnings = 0
    local sqlNameFull = fullPageName:gsub("'", "\\'")
    local sqlNameShort = displayName:gsub("'", "\\'")

    -- PART A: INDIVIDUAL AWARDS
    if cargo and cargo.query then
        local pWhere = string.format("(player = '%s' OR player = '%s')", sqlNameFull, sqlNameShort)
        local pResults = cargo.query("PrizeMoney", "SUM(prize)=total", { where = pWhere })
        if pResults and #pResults > 0 and pResults[1].total then
            individualEarnings = (tonumber(pResults[1].total) or 0)
        end
    end
    
    -- PART B: TEAM WINNINGS
    if cargo and cargo.query then
        local rosterTable = "Tournament_Teams"
        local rosterFields = "tournament, team"
        local rosterWhere = string.format(
            "p1='%s' OR p1='%s' OR p2='%s' OR p2='%s' OR p3='%s' OR p3='%s' OR p4='%s' OR p4='%s' OR p5='%s' OR p5='%s' OR p6='%s' OR p6='%s'",
            sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort,
            sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort, sqlNameFull, sqlNameShort
        )
        
        local participation = cargo.query(rosterTable, rosterFields, { where = rosterWhere, limit=500 })
        
        if participation and #participation > 0 then
            local prizeConditions = {}
            for _, row in ipairs(participation) do
                if row.tournament and row.team then
                    table.insert(prizeConditions, string.format("(tournament='%s' AND team='%s')", row.tournament:gsub("'", "\\'"), row.team:gsub("'", "\\'")))
                end
            end
            
            if #prizeConditions > 0 then
                local complexWhere = "(" .. table.concat(prizeConditions, " OR ") .. ") AND (player='' OR player IS NULL)"
                local teamPrizes = cargo.query("PrizeMoney", "SUM(prize)=team_total", { where = complexWhere })
                
                if teamPrizes and #teamPrizes > 0 and teamPrizes[1].team_total then
                    teamEarnings = (tonumber(teamPrizes[1].team_total) or 0)
                end
            end
        end
    end

    -- Calculate Total
    local totalEarnings = individualEarnings + teamEarnings

    -- 4. Status & Rank Grid
    local statusColor = "#333"
    local statusText = args.status or "Active"
    if args.status then
        local s = args.status:lower()
        if s == "active" then statusColor = "#16a34a"
        elseif s == "inactive" or s == "banned" or s == "retired" then statusColor = "#dc2626"
        end
    end
    
    local grid1 = root:tag('div'):addClass('fib-grid')
    grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Status'):done():tag('div'):addClass('fib-value-sm'):css('color', statusColor):wikitext(statusText):done()
    
    local rankVal = getKraftonRank(fullPageName, displayName)
    grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Krafton Rank'):done():tag('div'):addClass('fib-value-sm'):wikitext(rankVal):done()

    -- 5. Role & Nation Grid
    local grid2 = root:tag('div'):addClass('fib-grid')
    grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Nationality'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.nationality or 'India'):done()
    grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Role'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.role or 'Player'):done()

    -- 6. Earnings (Highlight WITH BREAKDOWN)
    if totalEarnings > 0 then
        local prizeBox = root:tag('div'):addClass('fib-prize')
        
        -- Main Total
        prizeBox:tag('div'):addClass('fib-label-sm'):wikitext('Approx. Earnings'):done()
        prizeBox:tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(totalEarnings)):done()
        
        -- Breakdown Sub-Section
        local breakdown = prizeBox:tag('div')
            :css('display', 'flex')
            :css('justify-content', 'space-between')
            :css('margin-top', '8px')
            :css('padding-top', '6px')
            :css('border-top', '1px solid rgba(0,0,0,0.08)')
        
        -- Team Winnings (Left)
        local tDiv = breakdown:tag('div'):css('text-align', 'left')
        tDiv:tag('div'):css('font-size', '0.65em'):css('text-transform', 'uppercase'):css('opacity', '0.7'):wikitext('From Team'):done()
        tDiv:tag('div'):css('font-size', '0.85em'):css('font-weight', '600'):wikitext(formatCurrency(teamEarnings)):done()
        
        -- Individual Winnings (Right)
        local iDiv = breakdown:tag('div'):css('text-align', 'right')
        iDiv:tag('div'):css('font-size', '0.65em'):css('text-transform', 'uppercase'):css('opacity', '0.7'):wikitext('Individual'):done()
        iDiv:tag('div'):css('font-size', '0.85em'):css('font-weight', '600'):wikitext(formatCurrency(individualEarnings)):done()
    end
    
    -- 7. Info List
    local list = root:tag('div'):addClass('fib-list')
    local function addRow(label, value)
        if value and value ~= "" then
            list:tag('div'):addClass('fib-row'):tag('div'):addClass('fib-label'):wikitext(label):done():tag('div'):addClass('fib-data'):wikitext(value):done()
        end
    end
    
    addRow('Real Name', args.real_name)
    addRow('Born', args.birth_date)
    if args.current_team then
        addRow('Current Team', '[[' .. args.current_team .. ']]') 
    end
    addRow('Game', args.game or "BGMI")

    -- 8. Team History
    local history = cargo.query("Player_Former_Teams", "team, join_date, leave_date", { 
        where = "player_id = '" .. fullPageName:gsub("'", "\\'") .. "'",
        orderBy = "join_date DESC",
        limit = 10 
    })
    
    if #history > 0 then
        list:tag('div'):addClass('fib-header'):css('font-size','0.95em'):css('padding','10px'):css('margin-top','15px'):css('border-radius','6px'):wikitext('Team History')
        local histTable = list:tag('table'):css('width','100%'):css('font-size','0.9em'):css('border-collapse','collapse'):css('margin-top','5px')
        
        for _, hRow in ipairs(history) do
            local tr = histTable:tag('tr'):css('border-bottom','1px solid #e2e8f0')
            tr:tag('td'):css('padding','8px 4px'):css('font-weight','600'):wikitext('[[' .. hRow.team .. ']]')
            local dates = (hRow.join_date and mw.getContentLanguage():formatDate('M y', hRow.join_date) or '?') .. ' – ' .. (hRow.leave_date and mw.getContentLanguage():formatDate('M y', hRow.leave_date) or 'Now')
            tr:tag('td'):css('text-align','right'):css('padding','8px 4px'):css('color','#64748b'):wikitext(dates)
        end
    else
        -- Fallback check for short name
        local historyShort = cargo.query("Player_Former_Teams", "team, join_date, leave_date", { 
            where = "player_id = '" .. displayName:gsub("'", "\\'") .. "'",
            orderBy = "join_date DESC",
            limit = 10 
        })
        if #historyShort > 0 then
            list:tag('div'):addClass('fib-header'):css('font-size','0.95em'):css('padding','10px'):css('margin-top','15px'):css('border-radius','6px'):wikitext('Team History')
            local histTable = list:tag('table'):css('width','100%'):css('font-size','0.9em'):css('border-collapse','collapse'):css('margin-top','5px')
            for _, hRow in ipairs(historyShort) do
                local tr = histTable:tag('tr'):css('border-bottom','1px solid #e2e8f0')
                tr:tag('td'):css('padding','8px 4px'):css('font-weight','600'):wikitext('[[' .. hRow.team .. ']]')
                local dates = (hRow.join_date and mw.getContentLanguage():formatDate('M y', hRow.join_date) or '?') .. ' – ' .. (hRow.leave_date and mw.getContentLanguage():formatDate('M y', hRow.leave_date) or 'Now')
                tr:tag('td'):css('text-align','right'):css('padding','8px 4px'):css('color','#64748b'):wikitext(dates)
            end
        end
    end

    -- 9. Socials
    root:wikitext(getSocials(args))

    return tostring(root)
end

-- ============================================================
-- MAIN 2: FORMER PLAYERS TABLE
-- ============================================================
function p.formerPlayers(frame)
    local args = frame:getParent().args
    local team = args.team or mw.title.getCurrentTitle().text
    
    local results = cargo.query("Player_Former_Teams, Players", "Player_Former_Teams.player_id=id, Players.real_name=Name, Player_Former_Teams.role=role, Player_Former_Teams.join_date=join_date, Player_Former_Teams.leave_date=leave_date", {
        joinOn = "Player_Former_Teams.player_id = Players._pageName",
        where = "Player_Former_Teams.team = '" .. team:gsub("'", "\\'") .. "' AND Player_Former_Teams.leave_date != ''",
        orderBy = "Player_Former_Teams.leave_date DESC"
    })
    
    local root = html.create('table'):addClass('wikitable flat-table sortable'):css('width','100%')
    local header = root:tag('tr')
    header:tag('th'):wikitext('ID'); header:tag('th'):wikitext('Name'); header:tag('th'):wikitext('Role'); header:tag('th'):wikitext('Duration')
    
    if #results > 0 then
        for _, row in ipairs(results) do
            local tr = root:tag('tr')
            tr:tag('td'):css('font-weight','bold'):wikitext('[[' .. row.id .. ']]')
            tr:tag('td'):wikitext(row.Name)
            tr:tag('td'):wikitext(row.role)
            local range = (row.join_date and mw.getContentLanguage():formatDate('M Y', row.join_date) or '?') .. ' – ' .. (row.leave_date and mw.getContentLanguage():formatDate('M Y', row.leave_date) or '?')
            tr:tag('td'):attr('data-sort-value', row.leave_date):wikitext(range)
        end
    else
        return '<div style="font-style:italic; color:#64748b; padding:10px;">No former players found for this team.</div>'
    end
    
    return tostring(root)
end

return p