Fix game management save/retrieve; add last-edited to game cards

Root cause: saves went through admin.php which still used old console_url column
and had broken response using undefined $sent variable (always returned error).

- api/admin.php: platforms_create/update/delete fully rewritten with all agent
  fields, master-admin gating, and correct json_encode responses
- api/admin.php: update now sets updated_at=NOW() on save
- admin/index.php: game cards show last-edited date (✏️ from updated_at)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 18:15:55 +00:00
parent 7eade583f7
commit 185c27f6b4
2 changed files with 46 additions and 22 deletions
+1
View File
@@ -2893,6 +2893,7 @@ async function loadGames() {
</div>
<div style="text-align:right;flex-shrink:0">
<div style="font-size:15px;color:var(--text2);margin-bottom:4px">Order: ${g.sort_order}</div>
<div style="font-size:11px;color:var(--text2);margin-bottom:4px" title="Last edited">✏️ ${g.updated_at ? new Date(g.updated_at).toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'}) : '—'}</div>
<div id="credit-total-${g.id}" style="font-family:'Exo 2',sans-serif;font-weight:700;font-size:13px;color:var(--cyan);margin-bottom:6px">💳 —</div>
<div class="game-actions">
<button class="game-edit-btn" style="background:rgba(0,229,255,.1);color:var(--cyan);border:1px solid rgba(0,229,255,.2)" onclick="editGame(${g.id})">✏️ Edit</button>
+45 -22
View File
@@ -785,18 +785,27 @@ switch ($action) {
// ─── PLATFORMS: create ────────────────────────────────
case 'platforms_create':
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$slug = preg_replace('/[^a-z0-9_]/', '', strtolower(trim($d['slug'] ?? '')));
$name = substr(trim($d['name'] ?? ''), 0, 100);
$purl = substr(trim($d['player_url'] ?? ''), 0, 500);
$curl = substr(trim($d['console_url'] ?? ''), 0, 500);
$color= preg_match('/^#[0-9a-fA-F]{3,8}$/', $d['color']??'') ? $d['color'] : '#f0c040';
$sort = (int)($d['sort_order'] ?? 99);
$active=(int)(bool)($d['is_active'] ?? 1);
$d = json_decode(file_get_contents('php://input'), true);
$isMasterAdmin = (int)($_SESSION['user_id'] ?? 0) === MASTER_ADMIN_ID;
$slug = preg_replace('/[^a-z0-9_]/', '', strtolower(trim($d['slug'] ?? '')));
$name = substr(trim($d['name'] ?? ''), 0, 100);
$purl = substr(trim($d['player_url'] ?? ''), 0, 500);
$color = preg_match('/^#[0-9a-fA-F]{3,8}$/', $d['color']??'') ? $d['color'] : '#f0c040';
$sort = (int)($d['sort_order'] ?? 99);
$active = (int)(bool)($d['is_active'] ?? 1);
$agent_link = $isMasterAdmin ? substr(trim($d['agent_link'] ?? ''), 0, 500) : '';
$agent_login = $isMasterAdmin ? substr(trim($d['agent_login'] ?? ''), 0, 200) : '';
$agent_password = $isMasterAdmin ? substr(trim($d['agent_password'] ?? ''), 0, 200) : '';
$games_link = $isMasterAdmin ? substr(trim($d['games_link'] ?? ''), 0, 500) : '';
$agent_guide = $isMasterAdmin ? trim($d['agent_guide'] ?? '') : '';
$sub_agent_login = $isMasterAdmin ? substr(trim($d['sub_agent_login'] ?? ''), 0, 200) : '';
$sub_agent_password = $isMasterAdmin ? substr(trim($d['sub_agent_password'] ?? ''), 0, 200) : '';
$cashier_login = $isMasterAdmin ? substr(trim($d['cashier_login'] ?? ''), 0, 200) : '';
$cashier_password = $isMasterAdmin ? substr(trim($d['cashier_password'] ?? ''), 0, 200) : '';
if (!$slug||!$name||!$purl) { echo json_encode(['success'=>false,'error'=>'Slug, name, and player URL required']); exit; }
try {
db()->prepare("INSERT INTO platforms (slug,name,player_url,console_url,color,sort_order,is_active) VALUES (?,?,?,?,?,?,?)")
->execute([$slug,$name,$purl,$curl,$color,$sort,$active]);
db()->prepare("INSERT INTO platforms (slug,name,player_url,agent_link,agent_login,agent_password,games_link,agent_guide,sub_agent_login,sub_agent_password,cashier_login,cashier_password,color,sort_order,is_active) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
->execute([$slug,$name,$purl,$agent_link,$agent_login,$agent_password,$games_link,$agent_guide,$sub_agent_login,$sub_agent_password,$cashier_login,$cashier_password,$color,$sort,$active]);
echo json_encode(['success'=>true,'id'=>db()->lastInsertId()]);
} catch (Exception $e) { echo json_encode(['success'=>false,'error'=>'Slug already exists']); }
break;
@@ -804,18 +813,32 @@ switch ($action) {
// ─── PLATFORMS: update ────────────────────────────────
case 'platforms_update':
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$id = (int)($d['id'] ?? 0);
$name = substr(trim($d['name'] ?? ''), 0, 100);
$purl = substr(trim($d['player_url'] ?? ''), 0, 500);
$curl = substr(trim($d['console_url'] ?? ''), 0, 500);
$color= preg_match('/^#[0-9a-fA-F]{3,8}$/', $d['color']??'') ? $d['color'] : '#f0c040';
$sort = (int)($d['sort_order'] ?? 99);
$active=(int)(bool)($d['is_active'] ?? 1);
$d = json_decode(file_get_contents('php://input'), true);
$isMasterAdmin = (int)($_SESSION['user_id'] ?? 0) === MASTER_ADMIN_ID;
$id = (int)($d['id'] ?? 0);
$name = substr(trim($d['name'] ?? ''), 0, 100);
$purl = substr(trim($d['player_url'] ?? ''), 0, 500);
$color = preg_match('/^#[0-9a-fA-F]{3,8}$/', $d['color']??'') ? $d['color'] : '#f0c040';
$sort = (int)($d['sort_order'] ?? 99);
$active = (int)(bool)($d['is_active'] ?? 1);
if (!$id||!$name||!$purl) { echo json_encode(['success'=>false,'error'=>'ID, name, and URL required']); exit; }
db()->prepare("UPDATE platforms SET name=?,player_url=?,console_url=?,color=?,sort_order=?,is_active=? WHERE id=?")
->execute([$name,$purl,$curl,$color,$sort,$active,$id]);
echo json_encode($sent ? ['success'=>true] : ['success'=>false,'error'=>'Failed to send reset email. Please try again.']);
if ($isMasterAdmin) {
$agent_link = substr(trim($d['agent_link'] ?? ''), 0, 500);
$agent_login = substr(trim($d['agent_login'] ?? ''), 0, 200);
$agent_password = substr(trim($d['agent_password'] ?? ''), 0, 200);
$games_link = substr(trim($d['games_link'] ?? ''), 0, 500);
$agent_guide = trim($d['agent_guide'] ?? '');
$sub_agent_login = substr(trim($d['sub_agent_login'] ?? ''), 0, 200);
$sub_agent_password = substr(trim($d['sub_agent_password'] ?? ''), 0, 200);
$cashier_login = substr(trim($d['cashier_login'] ?? ''), 0, 200);
$cashier_password = substr(trim($d['cashier_password'] ?? ''), 0, 200);
db()->prepare("UPDATE platforms SET name=?,player_url=?,agent_link=?,agent_login=?,agent_password=?,games_link=?,agent_guide=?,sub_agent_login=?,sub_agent_password=?,cashier_login=?,cashier_password=?,color=?,sort_order=?,is_active=?,updated_at=NOW() WHERE id=?")
->execute([$name,$purl,$agent_link,$agent_login,$agent_password,$games_link,$agent_guide,$sub_agent_login,$sub_agent_password,$cashier_login,$cashier_password,$color,$sort,$active,$id]);
} else {
db()->prepare("UPDATE platforms SET name=?,player_url=?,color=?,sort_order=?,is_active=?,updated_at=NOW() WHERE id=?")
->execute([$name,$purl,$color,$sort,$active,$id]);
}
echo json_encode(['success'=>true]);
break;
// ─── PLATFORMS: delete ────────────────────────────────
@@ -825,7 +848,7 @@ switch ($action) {
$id = (int)($d['id'] ?? 0);
if (!$id) { echo json_encode(['success'=>false,'error'=>'ID required']); exit; }
db()->prepare("DELETE FROM platforms WHERE id=?")->execute([$id]);
echo json_encode($sent ? ['success'=>true] : ['success'=>false,'error'=>'Failed to send reset email. Please try again.']);
echo json_encode(['success'=>true]);
break;
case 'billing_get':
$uid = (int)($_GET['user_id'] ?? 0);