Module:Team: Difference between revisions
From eSportsAmaze
More actions
Esportsamaze (talk | contribs) Undo revision 2839 by Esportsamaze (talk) Tag: Undo |
Esportsamaze (talk | contribs) No edit summary |
||
| Line 2: | Line 2: | ||
local cargo = mw.ext.cargo | local cargo = mw.ext.cargo | ||
local html = mw.html | local html = mw.html | ||
local currentTitle = mw.title.getCurrentTitle() | |||
-- ============================================================ | -- ============================================================ | ||
-- HELPER FUNCTIONS | -- HELPER FUNCTIONS (Logos, Socials, Currency) | ||
-- ============================================================ | -- ============================================================ | ||
local function formatCurrency(amount) | local function formatCurrency(amount) | ||
if not amount then return "0" end | if not amount then return "0" end | ||
| Line 15: | Line 15: | ||
end | end | ||
local function getSocials(args) | local function getSocials(args) | ||
local container = html.create('div'):addClass('fib-socials') | local container = html.create('div'):addClass('fib-socials') | ||
local hasSocials = false | local hasSocials = false | ||
local platforms = { | local platforms = { | ||
{arg='instagram', file='Icon_instagram.png'}, | {arg='instagram', file='Icon_instagram.png'}, | ||
| Line 28: | Line 26: | ||
{arg='website', file='Icon_website.png'} | {arg='website', file='Icon_website.png'} | ||
} | } | ||
for _, p in ipairs(platforms) do | for _, p in ipairs(platforms) do | ||
if args[p.arg] and args[p.arg] ~= "" then | if args[p.arg] and args[p.arg] ~= "" then | ||
| Line 35: | Line 32: | ||
end | end | ||
end | end | ||
if hasSocials then return tostring(container) else return "" end | if hasSocials then return tostring(container) else return "" end | ||
end | end | ||
local function getInfoboxLogo(teamName, image, imageDark) | local function getInfoboxLogo(teamName, image, imageDark) | ||
local lightFile = (image ~= "" and image) or (teamName .. '.png') | local lightFile = (image ~= "" and image) or (teamName .. '.png') | ||
local darkFile = (imageDark ~= "" and imageDark) or (teamName .. '_dark.png') | local darkFile = (imageDark ~= "" and imageDark) or (teamName .. '_dark.png') | ||
local hasLight = mw.title.new('File:' .. lightFile).exists | local hasLight = mw.title.new('File:' .. lightFile).exists | ||
local hasDark = mw.title.new('File:' .. darkFile).exists | local hasDark = mw.title.new('File:' .. darkFile).exists | ||
local container = html.create('div'):addClass('fib-image') | local container = html.create('div'):addClass('fib-image') | ||
local lSpan = container:tag('span'):addClass('logo-lightmode') | local lSpan = container:tag('span'):addClass('logo-lightmode') | ||
if hasLight then lSpan:wikitext('[[File:' .. lightFile .. '|220px]]') else lSpan:wikitext('[[File:Shield_team.png|180px]]') end | if hasLight then lSpan:wikitext('[[File:' .. lightFile .. '|220px]]') else lSpan:wikitext('[[File:Shield_team.png|180px]]') end | ||
local dSpan = container:tag('span'):addClass('logo-darkmode') | local dSpan = container:tag('span'):addClass('logo-darkmode') | ||
if hasDark then dSpan:wikitext('[[File:' .. darkFile .. '|220px]]') elseif hasLight then dSpan:wikitext('[[File:' .. lightFile .. '|220px]]') else dSpan:wikitext('[[File:Shield_team_dark.png|180px]]') end | if hasDark then dSpan:wikitext('[[File:' .. darkFile .. '|220px]]') elseif hasLight then dSpan:wikitext('[[File:' .. lightFile .. '|220px]]') else dSpan:wikitext('[[File:Shield_team_dark.png|180px]]') end | ||
return tostring(container) | return tostring(container) | ||
end | end | ||
-- ============================================================ | -- ============================================================ | ||
-- MAIN 1: TEAM INFOBOX ( | -- MAIN 1: TEAM INFOBOX (Standard) | ||
-- ============================================================ | -- ============================================================ | ||
function p.infobox(frame) | function p.infobox(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local team = args.name or currentTitle.subpageText | |||
local team = args.name or | |||
local root = html.create('div'):addClass('flat-infobox') | local root = html.create('div'):addClass('flat-infobox') | ||
root:tag('div'):addClass('fib-header'):tag('div'):addClass('fib-title'):wikitext(team) | |||
root:tag('div'):addClass('fib-header') | |||
root:wikitext(getInfoboxLogo(team, args.image, args.image_dark)) | root:wikitext(getInfoboxLogo(team, args.image, args.image_dark)) | ||
local earnings = "0" | local earnings = "0" | ||
if cargo and cargo.query then | if cargo and cargo.query then | ||
local | local results = cargo.query("PrizeMoney", "SUM(prize)=total", { where = "team = '" .. team:gsub("'", "\\'") .. "' AND (player='' OR player IS NULL)" }) | ||
if results and #results > 0 and results[1].total then earnings = results[1].total end | |||
if results and #results > 0 and results[1].total then | |||
end | end | ||
| Line 95: | Line 71: | ||
end | end | ||
local statusColor = "#333" | local statusColor = "#333" | ||
local statusText = args.status or "Active" | local statusText = args.status or "Active" | ||
if args.status then | if args.status then | ||
local s = args.status:lower() | local s = args.status:lower() | ||
if s == "active" then statusColor = "#16a34a" | if s == "active" then statusColor = "#16a34a" elseif s == "inactive" or s == "disbanded" then statusColor = "#dc2626" end | ||
end | end | ||
local grid1 = root:tag('div'):addClass('fib-grid') | 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() | 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() | ||
| Line 114: | Line 86: | ||
grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Tag'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.short_code or '-'):done() | grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Tag'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.short_code or '-'):done() | ||
if earnings and tonumber(earnings) and tonumber(earnings) > 0 then | if earnings and tonumber(earnings) and tonumber(earnings) > 0 then | ||
root:tag('div'):addClass('fib-prize') | root:tag('div'):addClass('fib-prize'):tag('div'):addClass('fib-label-sm'):wikitext('Total Earnings'):done():tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(earnings)):done() | ||
end | end | ||
local list = root:tag('div'):addClass('fib-list') | local list = root:tag('div'):addClass('fib-list') | ||
local function addRow(label, value) | local function addRow(label, value) | ||
if value and value ~= "" then | 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 | end | ||
addRow('Full Name', args.other_team) | addRow('Full Name', args.other_team) | ||
if args.sponsors then addRow('Sponsors', args.sponsors:gsub(",", "<br>")) end | if args.sponsors then addRow('Sponsors', args.sponsors:gsub(",", "<br>")) end | ||
root:wikitext(getSocials(args)) | root:wikitext(getSocials(args)) | ||
return tostring(root) | return tostring(root) | ||
end | end | ||
-- ============================================================ | -- ============================================================ | ||
-- MAIN 2: | -- MAIN 2: HYBRID ACTIVE ROSTER (HERO GRID) | ||
-- ============================================================ | -- ============================================================ | ||
function p. | function p.roster(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local team = args.team or | local team = args.team or currentTitle.subpageText | ||
local | |||
where = " | -- 1. Fetch Database Players | ||
orderBy = " | local dbPlayers = {} | ||
if cargo and cargo.query then | |||
local tables = "Players" | |||
local fields = "id, real_name, role, nationality, image, _pageName" | |||
local where = "current_team = '" .. team:gsub("'", "\\'") .. "' AND status='Active'" | |||
local results = cargo.query(tables, fields, { where = where, orderBy = "role ASC" }) | |||
for _, row in ipairs(results) do | |||
dbPlayers[row.id] = { | |||
id = row.id, | |||
name = row.real_name, | |||
role = row.role, | |||
flag = row.nationality, | |||
image = row.image, | |||
link = row._pageName, | |||
source = "auto" | |||
} | |||
end | |||
end | |||
-- 2. Process Manual Inputs (Check for duplicates) | |||
local finalRoster = {} | |||
if | -- Add DB players first | ||
local | for _, pData in pairs(dbPlayers) do | ||
local | table.insert(finalRoster, pData) | ||
end | |||
-- Check manual args (player1, player2...) | |||
for i = 1, 10 do | |||
local mid = args['player' .. i] | |||
if mid and mid ~= "" then | |||
-- Only add if NOT in DB list | |||
if not dbPlayers[mid] then | |||
table.insert(finalRoster, { | |||
id = mid, | |||
name = args['name' .. i] or "", | |||
role = args['role' .. i] or "Player", | |||
flag = args['flag' .. i] or "India", | |||
image = "", -- Manual entries usually have no image | |||
link = mid, -- Redlink assumption | |||
source = "manual" | |||
}) | |||
end | |||
end | |||
end | |||
-- 3. Render the Grid (USING NEW CLASS NAMES) | |||
local grid = html.create('div'):addClass('hero-roster-grid') | |||
for _, player in ipairs(finalRoster) do | |||
local card = grid:tag('div'):addClass('hero-player-card') | |||
-- Header (Image Area) | |||
local header = card:tag('div'):addClass('hero-card-image') | |||
if player.image and player.image ~= "" then | |||
header:wikitext('[[File:' .. player.image .. '|link=' .. player.link .. ']]') | |||
else | |||
-- Fallback Silhouette | |||
header:wikitext('[[File:Player_Placeholder.png|link=' .. player.link .. ']]') | |||
end | |||
-- Info Body | |||
local body = card:tag('div'):addClass('hero-card-body') | |||
-- Role Pill | |||
local roleColor = "#64748b" -- Default Gray | |||
local r = (player.role or ""):lower() | |||
if r:find("igl") then roleColor = "#eab308" -- Gold | |||
elseif r:find("fragger") or r:find("entry") or r:find("assault") then roleColor = "#ef4444" -- Red | |||
elseif r:find("support") or r:find("medic") then roleColor = "#22c55e" -- Green | |||
elseif r:find("sniper") then roleColor = "#3b82f6" -- Blue | |||
elseif r:find("coach") then roleColor = "#a855f7" -- Purple | |||
end | |||
body:tag('div'):addClass('hero-role-pill') | |||
:css('background-color', roleColor) | |||
:wikitext(player.role or "Player") | |||
-- ID and Name | |||
body:tag('div'):addClass('hero-player-id'):wikitext('[[' .. player.link .. '|' .. player.id .. ']]') | |||
if player.name and player.name ~= "" then | |||
body:tag('div'):addClass('hero-player-name'):wikitext(player.name) | |||
end | |||
-- Flag | |||
if player.flag then | |||
body:tag('div'):addClass('hero-player-flag'):wikitext('[[File:Flag_' .. player.flag .. '.png|20px]] ' .. player.flag) | |||
end | end | ||
end | |||
return tostring( | |||
return tostring(grid) | |||
end | |||
-- ============================================================ | |||
-- MAIN 3: FORMER PLAYERS LIST | |||
-- ============================================================ | |||
function p.formerPlayers(frame) | |||
local args = frame:getParent().args | |||
local team = args.team or currentTitle.subpageText | |||
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.id", | |||
where = "Player_Former_Teams.team = '" .. team:gsub("'", "\\'") .. "'", | |||
orderBy = "Player_Former_Teams.leave_date DESC" | |||
} | |||
) | |||
if not results or #results == 0 then | |||
return '<div style="font-style:italic; color:#64748b; padding:10px;">No former players recorded.</div>' | |||
end | |||
local tbl = html.create('table'):addClass('wikitable flat-table sortable'):css('width','100%') | |||
local h = tbl:tag('tr') | |||
h:tag('th'):wikitext('ID') | |||
h:tag('th'):wikitext('Name') | |||
h:tag('th'):wikitext('Role') | |||
h:tag('th'):wikitext('Join Date') | |||
h:tag('th'):wikitext('Leave Date') | |||
for _, row in ipairs(results) do | |||
local tr = tbl:tag('tr') | |||
tr:tag('td'):css('font-weight','bold'):wikitext('[[' .. row.id .. ']]') | |||
tr:tag('td'):wikitext(row.Name or "-") | |||
tr:tag('td'):wikitext(row.role or "-") | |||
tr:tag('td'):wikitext(row.join_date or "?") | |||
tr:tag('td'):wikitext(row.leave_date or "?") | |||
end | |||
return tostring(tbl) | |||
end | end | ||
-- ============================================================ | -- ============================================================ | ||
-- MAIN | -- MAIN 4: STAT HEADER (KEY METRICS) | ||
-- ============================================================ | -- ============================================================ | ||
function p. | function p.statHeader(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local team = args.team or | local team = args.team or currentTitle.subpageText | ||
local results = cargo.query(" | |||
local earnings = "0" | |||
local results = cargo.query("PrizeMoney", "SUM(prize)=total", { where = "team = '" .. team:gsub("'", "\\'") .. "' AND (player='' OR player IS NULL)" }) | |||
if results and #results > 0 and results[1].total then earnings = results[1].total end | |||
local | local rank = "N/A" | ||
local rRes = cargo.query("Krafton_Rankings", "rank", { where = "name = '" .. team:gsub("'", "\\'") .. "' AND type='Team'", limit = 1 }) | |||
if rRes and #rRes > 0 then rank = "#" .. rRes[1].rank end | |||
local bar = html.create('div'):addClass('team-dashboard-bar') | |||
local m1 = bar:tag('div'):addClass('tdb-item') | |||
m1:tag('div'):addClass('tdb-label'):wikitext('Krafton Rank') | |||
local val1 = m1:tag('div'):addClass('tdb-value'):wikitext(rank) | |||
if rank ~= "N/A" then val1:addClass('highlight-gold') end | |||
local m2 = bar:tag('div'):addClass('tdb-item') | |||
m2:tag('div'):addClass('tdb-label'):wikitext('Total Earnings') | |||
return tostring( | m2:tag('div'):addClass('tdb-value'):wikitext('₹ ' .. formatCurrency(earnings):gsub("₹ ", ""):gsub('<[^>]+>','')) | ||
local m3 = bar:tag('div'):addClass('tdb-item') | |||
m3:tag('div'):addClass('tdb-label'):wikitext('Recent Form') | |||
m3:tag('div'):addClass('tdb-value'):css('font-size','1em'):wikitext('Coming Soon') | |||
return tostring(bar) | |||
end | end | ||
return p | return p | ||
Revision as of 20:19, 29 January 2026
Documentation for this module may be created at Module:Team/doc
local p = {}
local cargo = mw.ext.cargo
local html = mw.html
local currentTitle = mw.title.getCurrentTitle()
-- ============================================================
-- HELPER FUNCTIONS (Logos, Socials, Currency)
-- ============================================================
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
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'},
{arg='website', file='Icon_website.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
local function getInfoboxLogo(teamName, image, imageDark)
local lightFile = (image ~= "" and image) or (teamName .. '.png')
local darkFile = (imageDark ~= "" and imageDark) or (teamName .. '_dark.png')
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 .. '|220px]]') else lSpan:wikitext('[[File:Shield_team.png|180px]]') end
local dSpan = container:tag('span'):addClass('logo-darkmode')
if hasDark then dSpan:wikitext('[[File:' .. darkFile .. '|220px]]') elseif hasLight then dSpan:wikitext('[[File:' .. lightFile .. '|220px]]') else dSpan:wikitext('[[File:Shield_team_dark.png|180px]]') end
return tostring(container)
end
-- ============================================================
-- MAIN 1: TEAM INFOBOX (Standard)
-- ============================================================
function p.infobox(frame)
local args = frame:getParent().args
local team = args.name or currentTitle.subpageText
local root = html.create('div'):addClass('flat-infobox')
root:tag('div'):addClass('fib-header'):tag('div'):addClass('fib-title'):wikitext(team)
root:wikitext(getInfoboxLogo(team, args.image, args.image_dark))
local earnings = "0"
if cargo and cargo.query then
local results = cargo.query("PrizeMoney", "SUM(prize)=total", { where = "team = '" .. team:gsub("'", "\\'") .. "' AND (player='' OR player IS NULL)" })
if results and #results > 0 and results[1].total then earnings = results[1].total end
end
local rankVal = "Unranked"
if cargo and cargo.query then
local rResults = cargo.query("Krafton_Rankings", "rank", { where = "name = '" .. team:gsub("'", "\\'") .. "' AND type='Team'", limit = 1 })
if rResults and #rResults > 0 then rankVal = "#" .. rResults[1].rank end
end
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 == "disbanded" 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()
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()
local grid2 = root:tag('div'):addClass('fib-grid')
grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Country'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.country or 'TBD'):done()
grid2:tag('div'):addClass('fib-cell'):tag('div'):addClass('fib-label-sm'):wikitext('Tag'):done():tag('div'):addClass('fib-value-sm'):wikitext(args.short_code or '-'):done()
if earnings and tonumber(earnings) and tonumber(earnings) > 0 then
root:tag('div'):addClass('fib-prize'):tag('div'):addClass('fib-label-sm'):wikitext('Total Earnings'):done():tag('div'):addClass('fib-prize-val'):wikitext(formatCurrency(earnings)):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('Full Name', args.other_team)
if args.sponsors then addRow('Sponsors', args.sponsors:gsub(",", "<br>")) end
root:wikitext(getSocials(args))
return tostring(root)
end
-- ============================================================
-- MAIN 2: HYBRID ACTIVE ROSTER (HERO GRID)
-- ============================================================
function p.roster(frame)
local args = frame:getParent().args
local team = args.team or currentTitle.subpageText
-- 1. Fetch Database Players
local dbPlayers = {}
if cargo and cargo.query then
local tables = "Players"
local fields = "id, real_name, role, nationality, image, _pageName"
local where = "current_team = '" .. team:gsub("'", "\\'") .. "' AND status='Active'"
local results = cargo.query(tables, fields, { where = where, orderBy = "role ASC" })
for _, row in ipairs(results) do
dbPlayers[row.id] = {
id = row.id,
name = row.real_name,
role = row.role,
flag = row.nationality,
image = row.image,
link = row._pageName,
source = "auto"
}
end
end
-- 2. Process Manual Inputs (Check for duplicates)
local finalRoster = {}
-- Add DB players first
for _, pData in pairs(dbPlayers) do
table.insert(finalRoster, pData)
end
-- Check manual args (player1, player2...)
for i = 1, 10 do
local mid = args['player' .. i]
if mid and mid ~= "" then
-- Only add if NOT in DB list
if not dbPlayers[mid] then
table.insert(finalRoster, {
id = mid,
name = args['name' .. i] or "",
role = args['role' .. i] or "Player",
flag = args['flag' .. i] or "India",
image = "", -- Manual entries usually have no image
link = mid, -- Redlink assumption
source = "manual"
})
end
end
end
-- 3. Render the Grid (USING NEW CLASS NAMES)
local grid = html.create('div'):addClass('hero-roster-grid')
for _, player in ipairs(finalRoster) do
local card = grid:tag('div'):addClass('hero-player-card')
-- Header (Image Area)
local header = card:tag('div'):addClass('hero-card-image')
if player.image and player.image ~= "" then
header:wikitext('[[File:' .. player.image .. '|link=' .. player.link .. ']]')
else
-- Fallback Silhouette
header:wikitext('[[File:Player_Placeholder.png|link=' .. player.link .. ']]')
end
-- Info Body
local body = card:tag('div'):addClass('hero-card-body')
-- Role Pill
local roleColor = "#64748b" -- Default Gray
local r = (player.role or ""):lower()
if r:find("igl") then roleColor = "#eab308" -- Gold
elseif r:find("fragger") or r:find("entry") or r:find("assault") then roleColor = "#ef4444" -- Red
elseif r:find("support") or r:find("medic") then roleColor = "#22c55e" -- Green
elseif r:find("sniper") then roleColor = "#3b82f6" -- Blue
elseif r:find("coach") then roleColor = "#a855f7" -- Purple
end
body:tag('div'):addClass('hero-role-pill')
:css('background-color', roleColor)
:wikitext(player.role or "Player")
-- ID and Name
body:tag('div'):addClass('hero-player-id'):wikitext('[[' .. player.link .. '|' .. player.id .. ']]')
if player.name and player.name ~= "" then
body:tag('div'):addClass('hero-player-name'):wikitext(player.name)
end
-- Flag
if player.flag then
body:tag('div'):addClass('hero-player-flag'):wikitext('[[File:Flag_' .. player.flag .. '.png|20px]] ' .. player.flag)
end
end
return tostring(grid)
end
-- ============================================================
-- MAIN 3: FORMER PLAYERS LIST
-- ============================================================
function p.formerPlayers(frame)
local args = frame:getParent().args
local team = args.team or currentTitle.subpageText
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.id",
where = "Player_Former_Teams.team = '" .. team:gsub("'", "\\'") .. "'",
orderBy = "Player_Former_Teams.leave_date DESC"
}
)
if not results or #results == 0 then
return '<div style="font-style:italic; color:#64748b; padding:10px;">No former players recorded.</div>'
end
local tbl = html.create('table'):addClass('wikitable flat-table sortable'):css('width','100%')
local h = tbl:tag('tr')
h:tag('th'):wikitext('ID')
h:tag('th'):wikitext('Name')
h:tag('th'):wikitext('Role')
h:tag('th'):wikitext('Join Date')
h:tag('th'):wikitext('Leave Date')
for _, row in ipairs(results) do
local tr = tbl:tag('tr')
tr:tag('td'):css('font-weight','bold'):wikitext('[[' .. row.id .. ']]')
tr:tag('td'):wikitext(row.Name or "-")
tr:tag('td'):wikitext(row.role or "-")
tr:tag('td'):wikitext(row.join_date or "?")
tr:tag('td'):wikitext(row.leave_date or "?")
end
return tostring(tbl)
end
-- ============================================================
-- MAIN 4: STAT HEADER (KEY METRICS)
-- ============================================================
function p.statHeader(frame)
local args = frame:getParent().args
local team = args.team or currentTitle.subpageText
local earnings = "0"
local results = cargo.query("PrizeMoney", "SUM(prize)=total", { where = "team = '" .. team:gsub("'", "\\'") .. "' AND (player='' OR player IS NULL)" })
if results and #results > 0 and results[1].total then earnings = results[1].total end
local rank = "N/A"
local rRes = cargo.query("Krafton_Rankings", "rank", { where = "name = '" .. team:gsub("'", "\\'") .. "' AND type='Team'", limit = 1 })
if rRes and #rRes > 0 then rank = "#" .. rRes[1].rank end
local bar = html.create('div'):addClass('team-dashboard-bar')
local m1 = bar:tag('div'):addClass('tdb-item')
m1:tag('div'):addClass('tdb-label'):wikitext('Krafton Rank')
local val1 = m1:tag('div'):addClass('tdb-value'):wikitext(rank)
if rank ~= "N/A" then val1:addClass('highlight-gold') end
local m2 = bar:tag('div'):addClass('tdb-item')
m2:tag('div'):addClass('tdb-label'):wikitext('Total Earnings')
m2:tag('div'):addClass('tdb-value'):wikitext('₹ ' .. formatCurrency(earnings):gsub("₹ ", ""):gsub('<[^>]+>',''))
local m3 = bar:tag('div'):addClass('tdb-item')
m3:tag('div'):addClass('tdb-label'):wikitext('Recent Form')
m3:tag('div'):addClass('tdb-value'):css('font-size','1em'):wikitext('Coming Soon')
return tostring(bar)
end
return p