Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 14:20, 27 January 2026 by Esportsamaze (talk | contribs)

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

local p = {}
local html = mw.html
local cargo = mw.ext.cargo
local lang = mw.getContentLanguage()

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

local function formatCurrency(amount)
    if not amount or amount == "" or amount == "0" then return "TBD" end
    local currency = "₹" 
    if string.find(amount, "%$") then currency = "$" end
    local n = tostring(amount):gsub(",", ""):gsub("₹", ""):gsub("%$", "")
    if #n <= 3 then return currency .. " " .. n end
    local last3 = n:sub(-3)
    local rest = n:sub(1, -4)
    local formattedRest = rest:reverse():gsub("(%d%d)", "%1,"):reverse()
    if formattedRest:sub(1, 1) == "," then formattedRest = formattedRest:sub(2) end
    return '<span class="pz-prize">' .. currency .. " " .. formattedRest .. "," .. last3 .. '</span>'
end

local function formatDateRange(startStr, endStr)
    if not startStr or startStr == "" then return "TBA" end
    if endStr and endStr ~= "" and endStr ~= startStr then
        local s = lang:formatDate('d M', startStr)
        local e = lang:formatDate('d M, Y', endStr)
        return s .. " – " .. e 
    else
        return lang:formatDate('d M, Y', startStr)
    end
end

local function getCleanTitle(pageLink)
    if not pageLink then return "" end
    local title = mw.title.new(pageLink)
    if title then return title.subpageText end
    return pageLink
end

-- Social Icons using CSS Classes (Data URIs)
local function getSocials(args)
    local container = html.create('div'):addClass('fib-socials plainlinks')
    local hasSocials = false
    
    local platforms = {
        {arg='instagram', class='icon-instagram'},
        {arg='twitter',   class='icon-twitter'},
        {arg='youtube',   class='icon-youtube'},
        {arg='discord',   class='icon-discord'},
        {arg='website',   class='icon-website'}
    }
    
    for _, p in ipairs(platforms) do
        if args[p.arg] and args[p.arg] ~= "" then
            hasSocials = true
            -- Generates: <a href="..." class="social-btn icon-name"></a>
            container:tag('a')
                :attr('href', args[p.arg])
                :attr('target', '_blank')
                :addClass('social-btn ' .. p.class)
        end
    end
    
    if hasSocials then return tostring(container) else return "" end
end

-- Automatic Series Navigation
local function getSeriesNav(currentSeries, currentValue)
    if not currentSeries or not currentValue or not cargo then return "" end
    
    local nav = html.create('div'):addClass('fib-nav')
    
    -- Query for Previous
    local prevQuery = cargo.query('Tournaments', '_pageName, series_season', {
        where = string.format('series = "%s" AND series_value < %s', currentSeries, currentValue),
        orderBy = 'series_value DESC',
        limit = 1
    })
    
    local prevBtn = nav:tag('div'):addClass('fib-nav-btn prev')
    if prevQuery and #prevQuery > 0 then
        local row = prevQuery[1]
        prevBtn:wikitext('[[' .. row._pageName .. '|« ' .. (row.series_season or "Previous") .. ']]')
    else
        prevBtn:css('opacity', '0.3'):wikitext('« Previous')
    end
    
    -- Query for Next
    local nextQuery = cargo.query('Tournaments', '_pageName, series_season', {
        where = string.format('series = "%s" AND series_value > %s', currentSeries, currentValue),
        orderBy = 'series_value ASC',
        limit = 1
    })
    
    local nextBtn = nav:tag('div'):addClass('fib-nav-btn next')
    if nextQuery and #nextQuery > 0 then
        local row = nextQuery[1]
        nextBtn:wikitext('[[' .. row._pageName .. '|' .. (row.series_season or "Next") .. ' »]]')
    else
        nextBtn:css('opacity', '0.3'):wikitext('Next »')
    end
    
    return tostring(nav)
end

-- Helper: Theme Aware Logo
local function getInfoboxLogo(pageName, image, imageDark)
    local lightFile = (image ~= "" and image) or (pageName .. '.png')
    local darkFile = imageDark
    if not darkFile or darkFile == "" then
        local ext = lightFile:match("^.+(%..+)$") or ".png"
        local name = lightFile:gsub("%..+$", "")
        darkFile = name .. "_dark" .. ext
    end
    local hasLight = mw.title.new('File:' .. lightFile).exists
    local hasDark = mw.title.new('File:' .. darkFile).exists
    local container = html.create('div'):addClass('fib-image')
    local lSpan = container:tag('span'):addClass('logo-lightmode')
    if hasLight then lSpan:wikitext('[[File:' .. lightFile .. '|250px]]') else lSpan:wikitext('[[File:Shield_team.png|150px]]') end
    local dSpan = container:tag('span'):addClass('logo-darkmode')
    if hasDark then dSpan:wikitext('[[File:' .. darkFile .. '|250px]]') elseif hasLight then dSpan:wikitext('[[File:' .. lightFile .. '|250px]]') else dSpan:wikitext('[[File:Shield_team_dark.png|150px]]') end
    return tostring(container)
end

-- ============================================================
-- MAIN 1: TOURNAMENT INFOBOX
-- ============================================================
function p.infobox(frame)
    local args = frame:getParent().args
    local page = args.name or mw.title.getCurrentTitle().text
    local cleanName = mw.title.getCurrentTitle().subpageText
    local prizeMoney = args.prize_pool or args.prizepool
    
    -- STORE TO CARGO
    if cargo and cargo.store then
        cargo.store('Tournaments', {
            _pageName = mw.title.getCurrentTitle().prefixedText,
            name = args.name or cleanName,
            series = args.series,
            series_season = args.series_season,
            series_value = args.series_value,
            organizer = args.organizer,
            sponsor = args.sponsor,
            game = args.game or "BGMI",
            mode = args.mode,
            type = args.type,
            tier = args.tier,
            device = args.device,
            location = args.location,
            venue = args.venue,
            prize_pool = prizeMoney,
            start_date = args.start_date,
            end_date = args.end_date,
            winner = args.winner,
            image = args.image,
            image_dark = args.image_dark,
            instagram = args.instagram,
            twitter = args.twitter,
            youtube = args.youtube,
            discord = args.discord,
            facebook = args.facebook,
            website = args.website
        })
    end

    local root = html.create('div'):addClass('flat-infobox')
    
    local header = root:tag('div'):addClass('fib-header')
    header:tag('div'):addClass('fib-title'):wikitext(args.name or cleanName)
    root:wikitext(getInfoboxLogo(page, args.image, args.image_dark))
    
    local grid1 = root:tag('div'):addClass('fib-grid')
    grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Event Tier'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.tier or 'Unranked'):done()
    grid1:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Type'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.type or 'Online'):done()
         
    local grid2 = root:tag('div'):addClass('fib-grid')
    grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Mode'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.mode or 'TBD'):done()
    grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Location'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.location or 'India'):done()
    
    if prizeMoney then
        root:tag('div'):addClass('fib-prize')
            :tag('div'):addClass('fib-label-sm'):wikitext('Total Prize Pool'):done()
            :tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(prizeMoney)):done()
    end
    
    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('Series', args.series and '[[' .. args.series .. ']]')
    if args.series_season then addRow('Season', args.series_season) end
    addRow('Organizer', args.organizer)
    addRow('Sponsors', args.sponsor)
    addRow('Venue', args.venue)
    addRow('Dates', formatDateRange(args.start_date, args.end_date))
    addRow('Device', args.device)
    if args.winner then addRow('Winner', "'''[[" .. args.winner .. "]]'''") end
    
    -- Socials (Using CSS Classes)
    root:wikitext(getSocials(args))
    
    -- Auto Navigation (Using Series Value)
    if args.series and args.series_value then
        root:wikitext(getSeriesNav(args.series, args.series_value))
    end

    return tostring(root)
end

-- (Keep ListRow and ListRowMain functions as they were in previous steps, ensuring getTourneyLogo is updated if needed)
function p.listRow(frame) return "" end -- Placeholder to save space in this response, keep your existing logic
function p.listRowMain(frame) return "" end -- Placeholder

return p