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

Module:Tournament: Difference between revisions

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


-- Social Icons using CSS Classes (Data URIs)
-- Social Icons (Using Standard File Uploads)
local function getSocials(args)
local function getSocials(args)
     local container = html.create('div'):addClass('fib-socials plainlinks')
     local container = html.create('div'):addClass('fib-socials')
     local hasSocials = false
     local hasSocials = false
      
      
    -- Map args to File Names
     local platforms = {
     local platforms = {
         {arg='instagram', class='icon-instagram'},
         {arg='instagram', file='Icon_instagram.png'},
         {arg='twitter',  class='icon-twitter'},
         {arg='twitter',  file='Icon_twitter.png'},
         {arg='youtube',  class='icon-youtube'},
         {arg='youtube',  file='Icon_youtube.png'},
         {arg='discord',  class='icon-discord'},
         {arg='discord',  file='Icon_discord.png'},
         {arg='website',  class='icon-website'}
        {arg='facebook',  file='Icon_facebook.png'},
         {arg='website',  file='Icon_website.png'}
     }
     }
      
      
Line 55: Line 57:
         if args[p.arg] and args[p.arg] ~= "" then
         if args[p.arg] and args[p.arg] ~= "" then
             hasSocials = true
             hasSocials = true
             -- Generates: <a href="..." class="social-btn icon-name"></a>
             -- Standard Image Link: [[File:Name.png|20px|link=URL]]
             container:tag('a')
             container:wikitext('[[File:' .. p.file .. '|24px|link=' .. args[p.arg] .. '|class=social-img]]')
                :attr('href', args[p.arg])
                :attr('target', '_blank')
                :addClass('social-btn ' .. p.class)
         end
         end
     end
     end
Line 66: Line 65:
end
end


-- Automatic Series Navigation
-- Smart Series Navigation (Value Based)
local function getSeriesNav(currentSeries, currentValue)
local function getSeriesNav(currentSeries, currentValue)
     if not currentSeries or not currentValue or not cargo then return "" end
     if not currentSeries or not currentValue or not cargo then return "" end
Line 72: Line 71:
     local nav = html.create('div'):addClass('fib-nav')
     local nav = html.create('div'):addClass('fib-nav')
      
      
     -- Query for Previous
     -- 1. Find PREVIOUS (Highest value LESS than current)
    -- Example: If current is 2025, finding max value < 2025 (e.g. 2024)
     local prevQuery = cargo.query('Tournaments', '_pageName, series_season', {
     local prevQuery = cargo.query('Tournaments', '_pageName, series_season', {
         where = string.format('series = "%s" AND series_value < %s', currentSeries, currentValue),
         where = string.format('series = "%s" AND series_value < %s', currentSeries, currentValue),
         orderBy = 'series_value DESC',
         orderBy = 'series_value DESC', -- Get the closest previous one
         limit = 1
         limit = 1
     })
     })
Line 82: Line 82:
     if prevQuery and #prevQuery > 0 then
     if prevQuery and #prevQuery > 0 then
         local row = prevQuery[1]
         local row = prevQuery[1]
         prevBtn:wikitext('[[' .. row._pageName .. '|« ' .. (row.series_season or "Previous") .. ']]')
        local label = row.series_season or "Previous"
         prevBtn:wikitext('[[' .. row._pageName .. '|' .. label .. ']]')
     else
     else
         prevBtn:css('opacity', '0.3'):wikitext('« Previous')
        -- If no previous, show empty or placeholder
         prevBtn:css('opacity', '0.3'):wikitext('Previous')  
     end
     end
      
      
     -- Query for Next
     -- 2. Find NEXT (Lowest value GREATER than current)
    -- Example: If current is 2025, finding min value > 2025 (e.g. 2026)
     local nextQuery = cargo.query('Tournaments', '_pageName, series_season', {
     local nextQuery = cargo.query('Tournaments', '_pageName, series_season', {
         where = string.format('series = "%s" AND series_value > %s', currentSeries, currentValue),
         where = string.format('series = "%s" AND series_value > %s', currentSeries, currentValue),
         orderBy = 'series_value ASC',
         orderBy = 'series_value ASC', -- Get the closest next one
         limit = 1
         limit = 1
     })
     })
Line 97: Line 100:
     if nextQuery and #nextQuery > 0 then
     if nextQuery and #nextQuery > 0 then
         local row = nextQuery[1]
         local row = nextQuery[1]
         nextBtn:wikitext('[[' .. row._pageName .. '|' .. (row.series_season or "Next") .. ' »]]')
        local label = row.series_season or "Next"
         nextBtn:wikitext('[[' .. row._pageName .. '|' .. label .. ']]')
     else
     else
         nextBtn:css('opacity', '0.3'):wikitext('Next »')
         nextBtn:css('opacity', '0.3'):wikitext('Next')  
     end
     end
      
      
Line 121: Line 125:
     local dSpan = container:tag('span'):addClass('logo-darkmode')
     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
     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
-- Helper: List Logo (For Homepage)
local function getTourneyLogo(imageFile, darkImageFile)
    local container = html.create('div'):addClass('tr-event-logo')
    if imageFile and imageFile ~= "" then
        local darkFile = darkImageFile
        if not darkFile or darkFile == "" then
            local ext = imageFile:match("^.+(%..+)$") or ".png"
            local name = imageFile:gsub("%..+$", "")
            darkFile = name .. "_dark" .. ext
        end
        local hasDark = mw.title.new('File:' .. darkFile).exists
        container:tag('span'):addClass('logo-lightmode'):wikitext('[[File:' .. imageFile .. '|40px|link=]]')
        local dSpan = container:tag('span'):addClass('logo-darkmode')
        if hasDark then dSpan:wikitext('[[File:' .. darkFile .. '|40px|link=]]') else dSpan:wikitext('[[File:' .. imageFile .. '|40px|link=]]') end
    else
        container:wikitext('<i class="fa-solid fa-trophy" style="color:var(--text-muted); opacity:0.3;"></i>')
    end
     return tostring(container)
     return tostring(container)
end
end
Line 133: Line 157:
     local prizeMoney = args.prize_pool or args.prizepool
     local prizeMoney = args.prize_pool or args.prizepool
      
      
    -- STORE TO CARGO
     if mw.ext.cargo and mw.ext.cargo.store then
     if cargo and cargo.store then
         mw.ext.cargo.store('Tournaments', {
         cargo.store('Tournaments', {
             _pageName = mw.title.getCurrentTitle().prefixedText,
             _pageName = mw.title.getCurrentTitle().prefixedText,
             name = args.name or cleanName,
             name = args.name or cleanName,
Line 201: Line 224:
     if args.winner then addRow('Winner', "'''[[" .. args.winner .. "]]'''") end
     if args.winner then addRow('Winner', "'''[[" .. args.winner .. "]]'''") end
      
      
    -- Socials (Using CSS Classes)
     root:wikitext(getSocials(args))
     root:wikitext(getSocials(args))
      
      
     -- Auto Navigation (Using Series Value)
     -- Automatic Series Navigation
     if args.series and args.series_value then
     if args.series and args.series_value then
         root:wikitext(getSeriesNav(args.series, args.series_value))
         root:wikitext(getSeriesNav(args.series, args.series_value))
Line 212: Line 234:
end
end


-- (Keep ListRow and ListRowMain functions as they were in previous steps, ensuring getTourneyLogo is updated if needed)
function p.listRow(frame)
function p.listRow(frame) return "" end -- Placeholder to save space in this response, keep your existing logic
    local args = frame.args
function p.listRowMain(frame) return "" end -- Placeholder
    local page = args.Page or ""
    local name = getCleanTitle(page)
    local startDate = args.start_date or ""
    local endDate = args.end_date or ""
    local row = html.create('div'):addClass('tourney-row')
    row:tag('div'):addClass('tr-date'):wikitext(formatDateRange(startDate, endDate))
    local info = row:tag('div'):addClass('tr-info')
    info:tag('div'):addClass('tr-name'):wikitext('[[' .. page .. '|' .. name .. ']]')
    if args.organizer then info:tag('div'):addClass('tr-org'):wikitext(args.organizer) end
    local winDiv = row:tag('div'):addClass('tr-winner mobile-hide')
    if args.winner and args.winner ~= "" then winDiv:wikitext("🏆 " .. args.winner) else winDiv:tag('span'):addClass('dim-text'):wikitext('-') end
    local prizeDiv = row:tag('div'):addClass('tr-prize')
    prizeDiv:wikitext(formatCurrency(args.prize_pool))
    return tostring(row)
end
 
function p.listRowMain(frame)
    local args = frame.args
    local page = args.Page or ""
    local name = getCleanTitle(page)
    local startDate = args.start_date or ""
    local endDate = args.end_date or ""
    local image = args.image or ""
    local imageDark = args.image_dark or ""
    local row = html.create('div'):addClass('tourney-row tr-compact')
    row:tag('div'):addClass('tr-date'):wikitext(formatDateRange(startDate, endDate))
    row:tag('div'):addClass('tr-event-logo-col'):wikitext(getTourneyLogo(image, imageDark))
    local info = row:tag('div'):addClass('tr-info')
    info:tag('div'):addClass('tr-name'):wikitext('[[' .. page .. '|' .. name .. ']]')
    if args.organizer then info:tag('div'):addClass('tr-org'):wikitext(args.organizer) end
    local prizeDiv = row:tag('div'):addClass('tr-prize')
    prizeDiv:wikitext(formatCurrency(args.prize_pool))
    return tostring(row)
end


return p
return p

Revision as of 19:07, 27 January 2026

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 Standard File Uploads)
local function getSocials(args)
    local container = html.create('div'):addClass('fib-socials')
    local hasSocials = false
    
    -- Map args to File Names
    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'},
        {arg='website',   file='Icon_website.png'}
    }
    
    for _, p in ipairs(platforms) do
        if args[p.arg] and args[p.arg] ~= "" then
            hasSocials = true
            -- Standard Image Link: [[File:Name.png|20px|link=URL]]
            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

-- Smart Series Navigation (Value Based)
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')
    
    -- 1. Find PREVIOUS (Highest value LESS than current)
    -- Example: If current is 2025, finding max value < 2025 (e.g. 2024)
    local prevQuery = cargo.query('Tournaments', '_pageName, series_season', {
        where = string.format('series = "%s" AND series_value < %s', currentSeries, currentValue),
        orderBy = 'series_value DESC', -- Get the closest previous one
        limit = 1
    })
    
    local prevBtn = nav:tag('div'):addClass('fib-nav-btn prev')
    if prevQuery and #prevQuery > 0 then
        local row = prevQuery[1]
        local label = row.series_season or "Previous"
        prevBtn:wikitext('[[' .. row._pageName .. '|' .. label .. ']]')
    else
        -- If no previous, show empty or placeholder
        prevBtn:css('opacity', '0.3'):wikitext('Previous') 
    end
    
    -- 2. Find NEXT (Lowest value GREATER than current)
    -- Example: If current is 2025, finding min value > 2025 (e.g. 2026)
    local nextQuery = cargo.query('Tournaments', '_pageName, series_season', {
        where = string.format('series = "%s" AND series_value > %s', currentSeries, currentValue),
        orderBy = 'series_value ASC', -- Get the closest next one
        limit = 1
    })
    
    local nextBtn = nav:tag('div'):addClass('fib-nav-btn next')
    if nextQuery and #nextQuery > 0 then
        local row = nextQuery[1]
        local label = row.series_season or "Next"
        nextBtn:wikitext('[[' .. row._pageName .. '|' .. label .. ']]')
    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

-- Helper: List Logo (For Homepage)
local function getTourneyLogo(imageFile, darkImageFile)
    local container = html.create('div'):addClass('tr-event-logo')
    if imageFile and imageFile ~= "" then
        local darkFile = darkImageFile
        if not darkFile or darkFile == "" then
            local ext = imageFile:match("^.+(%..+)$") or ".png"
            local name = imageFile:gsub("%..+$", "")
            darkFile = name .. "_dark" .. ext
        end
        local hasDark = mw.title.new('File:' .. darkFile).exists
        container:tag('span'):addClass('logo-lightmode'):wikitext('[[File:' .. imageFile .. '|40px|link=]]')
        local dSpan = container:tag('span'):addClass('logo-darkmode')
        if hasDark then dSpan:wikitext('[[File:' .. darkFile .. '|40px|link=]]') else dSpan:wikitext('[[File:' .. imageFile .. '|40px|link=]]') end
    else
        container:wikitext('<i class="fa-solid fa-trophy" style="color:var(--text-muted); opacity:0.3;"></i>')
    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
    
    if mw.ext.cargo and mw.ext.cargo.store then
        mw.ext.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
    
    root:wikitext(getSocials(args))
    
    -- Automatic Series Navigation
    if args.series and args.series_value then
        root:wikitext(getSeriesNav(args.series, args.series_value))
    end

    return tostring(root)
end

function p.listRow(frame)
    local args = frame.args
    local page = args.Page or ""
    local name = getCleanTitle(page)
    local startDate = args.start_date or ""
    local endDate = args.end_date or ""
    local row = html.create('div'):addClass('tourney-row')
    row:tag('div'):addClass('tr-date'):wikitext(formatDateRange(startDate, endDate))
    local info = row:tag('div'):addClass('tr-info')
    info:tag('div'):addClass('tr-name'):wikitext('[[' .. page .. '|' .. name .. ']]')
    if args.organizer then info:tag('div'):addClass('tr-org'):wikitext(args.organizer) end
    local winDiv = row:tag('div'):addClass('tr-winner mobile-hide')
    if args.winner and args.winner ~= "" then winDiv:wikitext("🏆 " .. args.winner) else winDiv:tag('span'):addClass('dim-text'):wikitext('-') end
    local prizeDiv = row:tag('div'):addClass('tr-prize')
    prizeDiv:wikitext(formatCurrency(args.prize_pool))
    return tostring(row)
end

function p.listRowMain(frame)
    local args = frame.args
    local page = args.Page or ""
    local name = getCleanTitle(page)
    local startDate = args.start_date or ""
    local endDate = args.end_date or ""
    local image = args.image or ""
    local imageDark = args.image_dark or ""
    local row = html.create('div'):addClass('tourney-row tr-compact')
    row:tag('div'):addClass('tr-date'):wikitext(formatDateRange(startDate, endDate))
    row:tag('div'):addClass('tr-event-logo-col'):wikitext(getTourneyLogo(image, imageDark))
    local info = row:tag('div'):addClass('tr-info')
    info:tag('div'):addClass('tr-name'):wikitext('[[' .. page .. '|' .. name .. ']]')
    if args.organizer then info:tag('div'):addClass('tr-org'):wikitext(args.organizer) end
    local prizeDiv = row:tag('div'):addClass('tr-prize')
    prizeDiv:wikitext(formatCurrency(args.prize_pool))
    return tostring(row)
end

return p