<!DOCTYPE html>
<html lang="bn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AP Point Maker</title>
<style>
*{box-sizing:border-box}
body{margin:0;background:#090d18;color:#fff;font-family:Arial,sans-serif;padding:15px}
header{text-align:center;padding:20px 8px;background:#111a2d;border:1px solid #263653;border-radius:15px}
h1{color:#38e6a5;margin:0;font-size:27px}
header p{color:#aab8cc;margin:8px 0 0}
.card{background:#111a2d;padding:16px;margin-top:15px;border-radius:13px;border:1px solid #263653}
h2{font-size:18px;color:#38e6a5;margin:0 0 13px}
input,select{width:100%;padding:12px;margin:6px 0;background:#080f1d;border:1px solid #354765;border-radius:8px;color:white;font-size:15px}
button{padding:11px 14px;border:0;border-radius:8px;background:#20d99a;color:#07130f;font-weight:bold;margin:5px 2px;cursor:pointer}
button.secondary{background:#273954;color:white}
button.danger{background:#e74c3c;color:white}
.small{font-size:12px;color:#aab8cc}
table{width:100%;border-collapse:collapse;margin-top:12px;min-width:440px}
th,td{padding:10px 7px;border-bottom:1px solid #293750;text-align:center;font-size:13px}
th{background:#1c2a43;color:#38e6a5}
.tablewrap{overflow-x:auto}
.rank{color:#ffd45a;font-weight:bold}
footer{text-align:center;color:#8290a7;font-size:12px;padding:25px}
.actions{display:flex;flex-wrap:wrap;gap:5px}
</style>
</head>
<body>
<header>
<h1>🏆 AP POINT MAKER</h1>
<p>Free Fire Tournament Point Calculator</p>
<p class="small">DESIGNED BY TANJIM</p>
</header>
<section class="card">
<h2>⚙️ Point Settings</h2>
<label>পয়েন্ট সিস্টেম</label>
<select id="system" onchange="render()">
<option value="official">Official Style</option>
<option value="custom">Custom Points</option>
</select>
<div id="customSettings" style="display:none">
<label>প্রতি কিল পয়েন্ট</label>
<input id="killPoint" type="number" value="1" min="0">
<label>১ম স্থান</label><input id="p1" type="number" value="12">
<label>২য় স্থান</label><input id="p2" type="number" value="9">
<label>৩য় স্থান</label><input id="p3" type="number" value="8">
<label>৪র্থ স্থান</label><input id="p4" type="number" value="7">
<label>৫ম স্থান</label><input id="p5" type="number" value="6">
<label>৬ষ্ঠ স্থান</label><input id="p6" type="number" value="5">
<label>৭ম স্থান</label><input id="p7" type="number" value="4">
<label>৮ম স্থান</label><input id="p8" type="number" value="3">
<label>৯ম স্থান</label><input id="p9" type="number" value="2">
<label>১০ম স্থান</label><input id="p10" type="number" value="1">
</div>
</section>
<section class="card">
<h2>👥 Team Registration</h2>
<input id="teamName" placeholder="Team Name">
<input id="players" placeholder="Player names (কমা দিয়ে আলাদা করো)">
<button onclick="addTeam()">+ Add Team</button>
<div id="teamList" class="small"></div>
</section>
<section class="card">
<h2>🎮 Match Result Entry</h2>
<p class="small">Player name লিখলে রেজিস্টার করা টিম খুঁজে নেওয়ার চেষ্টা করবে।</p>
<input id="playerName" placeholder="Player Name">
<input id="kills" type="number" min="0" placeholder="Kills">
<input id="position" type="number" min="1" max="12" placeholder="Position (1-12)">
<button onclick="addResult()">+ Add Result</button>
<div id="resultList" class="small"></div>
</section>
<section class="card">
<h2>🏆 Tournament Leaderboard</h2>
<div class="actions">
<button onclick="render()">🔄 Update Points</button>
<button class="secondary" onclick="downloadCSV()">Download CSV</button>
<button class="secondary" onclick="window.print()">Print / Save PDF</button>
<button class="danger" onclick="clearAll()">Clear All</button>
</div>
<div class="tablewrap">
<table>
<thead><tr>
<th>Rank</th><th>Team</th><th>Position</th><th>Kills</th><th>Placement Pts</th><th>Total</th>
</tr></thead>
<tbody id="board"></tbody>
</table>
</div>
</section>
<footer>AP POINT MAKER<br>Designed by Tanjim</footer>
<script>
let teams=JSON.parse(localStorage.getItem("apTeams")||"[]");
let results=JSON.parse(localStorage.getItem("apResults")||"[]");
function save(){
localStorage.setItem("apTeams",JSON.stringify(teams));
localStorage.setItem("apResults",JSON.stringify(results));
}
function addTeam(){
let name=document.getElementById("teamName").value.trim();
let players=document.getElementById("players").value.split(",").map(x=>x.trim()).filter(Boolean);
if(!name){alert("Team name লিখো");return}
if(teams.some(t=>t.name.toLowerCase()===name.toLowerCase())){alert("এই Team আগে আছে");return}
teams.push({name,players});
save();
document.getElementById("teamName").value="";
document.getElementById("players").value="";
showTeams();
}
function showTeams(){
document.getElementById("teamList").innerHTML=teams.length?
teams.map(t=>"• "+t.name+" — "+t.players.join(", ")).join("<br>"):"কোনো Team যোগ করা হয়নি";
}
function findTeam(player){
let p=player.toLowerCase();
return teams.find(t=>t.players.some(n=>n.toLowerCase()===p));
}
function addResult(){
let player=document.getElementById("playerName").value.trim();
let kills=Number(document.getElementById("kills").value);
let pos=Number(document.getElementById("position").value);
if(!player||!Number.isInteger(kills)||kills<0||!Number.isInteger(pos)||pos<1||pos>12){
alert("সঠিক Player, Kills এবং Position দাও");return;
}
let team=findTeam(player);
if(!team){alert("এই Player কোনো Team-এ নেই। আগে Team Registration করো।");return}
results.push({player,team:team.name,kills,pos});
save();
document.getElementById("playerName").value="";
document.getElementById("kills").value="";
document.getElementById("position").value="";
showResults();
render();
}
function showResults(){
document.getElementById("resultList").innerHTML=results.length?
results.map((r,i)=>(i+1)+". "+r.player+" ("+r.team+") — "+r.kills+" kills, Position "+r.pos+
' <button class="danger" onclick="removeResult('+i+')">X</button>').join("<br>"):
"এখনো কোনো Result যোগ করা হয়নি";
}
function removeResult(i){results.splice(i,1);save();showResults();render()}
function placementPoints(pos){
if(document.getElementById("system").value==="custom"){
let v=document.getElementById("p"+pos);
return v?Number(v.value):0;
}
let official=[12,9,8,7,6,5,4,3,2,1,0,0];
return official[pos-1]||0;
}
function render(){
let custom=document.getElementById("customSettings");
custom.style.display=document.getElementById("system").value==="custom"?"block":"none";
let data={};
results.forEach(r=>{
if(!data[r.team])data[r.team]={team:r.team,kills:0,pos:99};
data[r.team].kills+=r.kills;
data[r.team].pos=Math.min(data[r.team].pos,r.pos);
});
let list=Object.values(data).map(t=>{
let pp=placementPoints(t.pos);
let kp=document.getElementById("system").value==="custom"?
Number(document.getElementById("killPoint").value):1;
return {...t,pp,total:pp+t.kills*kp};
}).sort((a,b)=>b.total-a.total||b.kills-a.kills);
document.getElementById("board").innerHTML=list.map((t,i)=>`
<tr><td class="rank">${i+1}</td><td>${escapeHTML(t.team)}</td>
<td>${t.pos}</td><td>${t.kills}</td><td>${t.pp}</td>
<td><b>${t.total}</b></td></tr>`).join("");
}
function escapeHTML(s){
return String(s).replace(/[&<>"']/g,c=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[c]));
}
function downloadCSV(){
let rows=[["Rank","Team","Position","Kills","Placement Points","Total"]];
let trs=[...document.querySelectorAll("#board tr")];
trs.forEach((tr)=>rows.push([...tr.querySelectorAll("td")].map(td=>td.innerText)));
let csv="\uFEFF"+rows.map(r=>r.join(",")).join("\n");
let a=document.createElement("a");
a.href=URL.createObjectURL(new Blob([csv],{type:"text/csv;charset=utf-8"}));
a.download="AP_Point_Maker.csv";a.click();
URL.revokeObjectURL(a.href);
}
function clearAll(){
if(confirm("সব Team ও Result মুছে ফেলবে?")){
teams=[];results=[];save();showTeams();showResults();render();
}
}
showTeams();showResults();render();
</script>
</body>
</html>