forked from wmantly/mc-bot-town
AI works here
This commit is contained in:
@@ -145,6 +145,17 @@ function createRouter(getActiveInstance) {
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/api/maps', async (req, res) => {
|
||||
if (!dbAvailable()) return res.status(503).json({ error: 'Storage database not initialized' });
|
||||
try {
|
||||
const maps = await database.getAllMaps();
|
||||
res.json({ maps });
|
||||
} catch (error) {
|
||||
console.error('API Error /api/maps:', error);
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/api/special-items', async (req, res) => {
|
||||
if (!dbAvailable()) return res.status(503).json({ error: 'Storage database not initialized' });
|
||||
try {
|
||||
@@ -323,6 +334,7 @@ const webUI = {
|
||||
<div class="tab active" onclick="switchStorageSubTab('inventory')">Inventory</div>
|
||||
<div class="tab" onclick="switchStorageSubTab('map')">Storage Map</div>
|
||||
<div class="tab" onclick="switchStorageSubTab('special')">Special Items</div>
|
||||
<div class="tab" onclick="switchStorageSubTab('maps')">Maps</div>
|
||||
<div class="tab" onclick="switchStorageSubTab('withdraw')">Withdraw</div>
|
||||
</div>
|
||||
<div id="stab-inventory" class="stab-content active" style="margin-top:16px">
|
||||
@@ -353,6 +365,12 @@ const webUI = {
|
||||
<div id="specialItems"><div style="padding:20px;color:#6b7280;text-align:center">Click tab to load...</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="stab-maps" class="stab-content" style="margin-top:16px">
|
||||
<div class="panel">
|
||||
<h3>Filled Maps</h3>
|
||||
<div id="mapsGrid"><div style="padding:20px;color:#6b7280;text-align:center">Click tab to load...</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="stab-withdraw" class="stab-content" style="margin-top:16px">
|
||||
<div class="panel">
|
||||
<h3>Request Withdrawal</h3>
|
||||
@@ -455,6 +473,11 @@ const webUI = {
|
||||
.special-card .sp-withdraw button{background:#2563eb;color:#fff;border:none;padding:6px 12px;border-radius:4px;cursor:pointer;font-size:.8em}
|
||||
.special-card .sp-withdraw button:hover{background:#1d4ed8}
|
||||
.special-card .sp-status{font-size:.8em;margin-top:4px;min-height:16px}
|
||||
.maps-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px}
|
||||
.map-card{background:#111827;border:1px solid #374151;border-radius:8px;padding:8px;text-align:center;transition:border-color .2s}
|
||||
.map-card:hover{border-color:#60a5fa}
|
||||
.map-card img{width:128px;height:128px;image-rendering:pixelated;border-radius:4px}
|
||||
.map-card .map-label{font-size:.8em;color:#9ca3af;margin-top:6px}
|
||||
.stab-content{display:none}
|
||||
.stab-content.active{display:block}
|
||||
.storage-sub-tabs{display:flex;border-bottom:1px solid #374151}
|
||||
@@ -462,7 +485,7 @@ const webUI = {
|
||||
`,
|
||||
js: `
|
||||
let allItems=[], mapData=[], sortKey='total_count', sortDir=-1;
|
||||
let specialLoaded=false, storageSubTab='inventory';
|
||||
let specialLoaded=false, mapsLoaded=false, storageSubTab='inventory';
|
||||
|
||||
function onStorageTabActive() {
|
||||
if (allItems.length === 0) { loadStats(); loadInventory(); loadPlayers(); }
|
||||
@@ -474,12 +497,13 @@ function switchStorageSubTab(name) {
|
||||
document.querySelectorAll('.stab-content').forEach(t => t.classList.remove('active'));
|
||||
const el = document.getElementById('stab-'+name);
|
||||
if (el) el.classList.add('active');
|
||||
const subNames=['inventory','map','special','withdraw'];
|
||||
const subNames=['inventory','map','special','maps','withdraw'];
|
||||
const tabs = document.querySelectorAll('.storage-sub-tabs .tab');
|
||||
const idx = subNames.indexOf(name);
|
||||
if (idx >= 0 && tabs[idx]) tabs[idx].classList.add('active');
|
||||
if (name === 'map' && mapData.length === 0) loadMap();
|
||||
if (name === 'special' && !specialLoaded) loadSpecialItems();
|
||||
if (name === 'maps' && !mapsLoaded) loadMaps();
|
||||
}
|
||||
|
||||
async function loadStats() {
|
||||
@@ -875,7 +899,30 @@ async function loadPlayers(){
|
||||
try{const r=await fetch('/api/players');if(!r.ok)return;const d=await r.json();playerNames=(d.players||[]).map(p=>p.player_name)}catch(e){}
|
||||
}
|
||||
|
||||
function storageLoadAll(){loadStats();loadInventory();loadPlayers();if(storageSubTab==='map')loadMap();if(storageSubTab==='special')loadSpecialItems()}
|
||||
async function loadMaps() {
|
||||
const container = document.getElementById('mapsGrid');
|
||||
container.innerHTML = '<div style="padding:20px;color:#6b7280;text-align:center">Loading...</div>';
|
||||
try {
|
||||
const r = await fetch('/api/maps');
|
||||
const d = await r.json();
|
||||
const maps = d.maps || [];
|
||||
mapsLoaded = true;
|
||||
if (maps.length === 0) {
|
||||
container.innerHTML = '<div style="padding:20px;color:#6b7280;text-align:center">No maps captured yet</div>';
|
||||
return;
|
||||
}
|
||||
container.innerHTML = '<div class="maps-grid">' + maps.map(m =>
|
||||
'<div class="map-card">' +
|
||||
'<img src="data:image/png;base64,' + m.image_data + '" alt="Map #' + m.map_id + '">' +
|
||||
'<div class="map-label">Map #' + m.map_id + '</div>' +
|
||||
'</div>'
|
||||
).join('') + '</div>';
|
||||
} catch(e) {
|
||||
container.innerHTML = '<div style="padding:20px;color:#ef4444">Failed to load maps</div>';
|
||||
}
|
||||
}
|
||||
|
||||
function storageLoadAll(){loadStats();loadInventory();loadPlayers();if(storageSubTab==='map')loadMap();if(storageSubTab==='special')loadSpecialItems();if(storageSubTab==='maps')loadMaps()}
|
||||
`,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user