first commit
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
const resource = typeof GetParentResourceName === 'function' ? GetParentResourceName() : 'devx_housing';
|
||||
const preview = document.querySelector('#preview');
|
||||
const panel = document.querySelector('#panel');
|
||||
const building = document.querySelector('#building');
|
||||
const label = document.querySelector('#label');
|
||||
const meta = document.querySelector('#meta');
|
||||
const price = document.querySelector('#price');
|
||||
const buy = document.querySelector('#buy');
|
||||
const buyText = document.querySelector('#buyText');
|
||||
const panelTitle = document.querySelector('#panelTitle');
|
||||
const panelText = document.querySelector('#panelText');
|
||||
const panelBody = document.querySelector('#panelBody');
|
||||
let currentDoor = null;
|
||||
|
||||
async function post(name, data = {}) {
|
||||
const response = await fetch(`https://${resource}/${name}`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
return response.json();
|
||||
}
|
||||
|
||||
function money(value){return `${new Intl.NumberFormat('de-DE').format(Number(value)||0)} $`}
|
||||
function closePanel(){panel.classList.add('hidden');post('uiClose')}
|
||||
|
||||
document.querySelector('#previous').onclick = () => post('previewPrevious');
|
||||
document.querySelector('#next').onclick = () => post('previewNext');
|
||||
document.querySelector('#previewClose').onclick = () => post('previewClose');
|
||||
document.querySelector('#panelClose').onclick = closePanel;
|
||||
buy.onclick = async () => {
|
||||
buy.disabled = true;
|
||||
const result = await post('previewBuy');
|
||||
if (!result.ok) {
|
||||
buyText.textContent = result.error || 'KAUF FEHLGESCHLAGEN';
|
||||
setTimeout(() => buyText.textContent = 'KAUFEN', 2200);
|
||||
buy.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keyup', event => {
|
||||
if (event.key === 'Escape') {
|
||||
if (!preview.classList.contains('hidden')) post('previewClose');
|
||||
else if (!panel.classList.contains('hidden')) closePanel();
|
||||
}
|
||||
});
|
||||
|
||||
function elevator(data){
|
||||
panel.classList.remove('hidden');
|
||||
panelTitle.textContent = data.building;
|
||||
panelText.textContent = `Aufzug · aktuelle Etage ${data.currentFloor || 'Lobby'}`;
|
||||
panelBody.innerHTML = '';
|
||||
for(let floor=1;floor<=Number(data.floors||1);floor++){
|
||||
const button=document.createElement('button');button.className='panel-action';
|
||||
button.innerHTML=`<b>Etage ${floor}</b><span>Wohnungen ${floor}01–${floor}04</span>`;
|
||||
button.onclick=()=>post('elevatorFloor',{floor});
|
||||
panelBody.appendChild(button);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function invite(data){
|
||||
panel.classList.remove('hidden');
|
||||
panelTitle.textContent=data.title||'Spieler einladen';
|
||||
panelText.textContent='Der ausgewählte Spieler erhält eine Einladung und wird erst nach der Annahme teleportiert.';
|
||||
panelBody.innerHTML='';
|
||||
const players=Array.isArray(data.players)?data.players:[];
|
||||
if(players.length===0){
|
||||
const empty=document.createElement('div');empty.className='empty-state';empty.textContent='Aktuell ist kein anderer Spieler online.';panelBody.appendChild(empty);return;
|
||||
}
|
||||
for(const player of players){
|
||||
const button=document.createElement('button');button.className='panel-action';
|
||||
button.innerHTML=`<b>${player.name||'Spieler'}</b><span>Server-ID ${player.source}</span>`;
|
||||
button.onclick=async()=>{button.disabled=true;const result=await post('invitePlayer',{target:player.source});if(!result.ok)button.disabled=false;};
|
||||
panelBody.appendChild(button);
|
||||
}
|
||||
}
|
||||
|
||||
function door(data){
|
||||
currentDoor=data;
|
||||
panel.classList.remove('hidden');
|
||||
panelTitle.textContent=data.label;
|
||||
panelText.textContent=data.sold?`Bewohner: ${data.ownerName||'Unbekannt'}`:'Diese Wohnung ist noch frei.';
|
||||
panelBody.innerHTML='';
|
||||
const actions=document.createElement('div');actions.className='door-actions';
|
||||
if(data.sold){
|
||||
const ring=document.createElement('button');ring.className='panel-action';ring.innerHTML='<b>Klingeln</b>';ring.onclick=()=>post('doorRing',{propertyKey:data.propertyKey});
|
||||
const knock=document.createElement('button');knock.className='panel-action';knock.innerHTML='<b>Klopfen</b>';knock.onclick=()=>post('doorKnock',{propertyKey:data.propertyKey});
|
||||
actions.append(ring,knock);
|
||||
const enter=document.createElement('button');enter.className='panel-action enter';enter.innerHTML='<b>Mit Einladung eintreten</b>';enter.onclick=()=>post('doorEnter',{propertyKey:data.propertyKey});actions.appendChild(enter);
|
||||
}
|
||||
panelBody.appendChild(actions);
|
||||
}
|
||||
|
||||
window.addEventListener('message', event => {
|
||||
const data=event.data||{};
|
||||
if(data.action==='previewOpen'){preview.classList.remove('hidden');panel.classList.add('hidden')}
|
||||
if(data.action==='previewData'){
|
||||
building.textContent=data.building||'DEVX IMMOBILIEN';
|
||||
label.textContent=data.label||'Wohnung';
|
||||
meta.textContent=`Etage ${data.floor} · Wohnung ${data.unitNumber} · ${data.style} · ${data.index}/${data.total}`;
|
||||
price.textContent=money(data.price);
|
||||
buy.disabled=Boolean(data.sold);
|
||||
buyText.textContent=data.ownedByMe?'DEINE WOHNUNG':data.sold?`VERKAUFT · ${data.ownerName||'Bewohnt'}`:'KAUFEN';
|
||||
}
|
||||
if(data.action==='elevatorOpen')elevator(data);
|
||||
if(data.action==='doorOpen')door(data);
|
||||
if(data.action==='inviteOpen')invite(data);
|
||||
if(data.action==='close'){preview.classList.add('hidden');panel.classList.add('hidden')}
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main id="preview" class="hidden">
|
||||
<section class="preview-bar">
|
||||
<button id="previous" class="arrow" aria-label="Vorherige Wohnung">‹</button>
|
||||
<div class="preview-copy">
|
||||
<small id="building">DEVX IMMOBILIEN</small>
|
||||
<strong id="label">Wohnung</strong>
|
||||
<span id="meta">Etage · Stil</span>
|
||||
</div>
|
||||
<button id="buy" class="buy">
|
||||
<span id="buyText">KAUFEN</span>
|
||||
<b id="price">0 $</b>
|
||||
</button>
|
||||
<button id="next" class="arrow" aria-label="Nächste Wohnung">›</button>
|
||||
<button id="previewClose" class="close">×</button>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<main id="panel" class="hidden overlay">
|
||||
<section class="panel-card">
|
||||
<button id="panelClose" class="close panel-close">×</button>
|
||||
<small id="panelEyebrow">DEVX-CITY</small>
|
||||
<h1 id="panelTitle">Aufzug</h1>
|
||||
<p id="panelText"></p>
|
||||
<div id="panelBody" class="panel-body"></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,2 @@
|
||||
:root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#fff}*{box-sizing:border-box}body{margin:0;background:transparent;overflow:hidden}.hidden{display:none!important}button{font:inherit}.preview-bar{position:fixed;left:50%;bottom:42px;transform:translateX(-50%);display:grid;grid-template-columns:64px minmax(260px,1fr) 190px 64px;align-items:stretch;width:min(860px,calc(100vw - 80px));min-height:98px;border:1px solid rgba(255,255,255,.14);border-radius:18px;background:linear-gradient(180deg,rgba(12,17,28,.96),rgba(7,10,18,.97));box-shadow:0 25px 80px rgba(0,0,0,.55);backdrop-filter:blur(14px);overflow:visible}.preview-copy{display:flex;flex-direction:column;justify-content:center;padding:14px 22px}.preview-copy small,#panelEyebrow{font-size:10px;font-weight:900;letter-spacing:.2em;color:#79a7ff}.preview-copy strong{font-size:20px;margin-top:4px}.preview-copy span{font-size:12px;color:rgba(255,255,255,.58);margin-top:4px}.arrow,.buy{border:0;cursor:pointer;color:#fff}.arrow{font-size:42px;background:rgba(255,255,255,.035);transition:.15s}.arrow:hover{background:rgba(90,136,255,.22)}.buy{display:flex;flex-direction:column;align-items:center;justify-content:center;background:linear-gradient(135deg,#4977f3,#6e95ff);font-weight:900}.buy span{font-size:13px;letter-spacing:.1em}.buy b{font-size:18px;margin-top:4px}.buy:disabled{cursor:not-allowed;background:#2b303c;color:rgba(255,255,255,.5)}.close{border:1px solid rgba(255,255,255,.16);background:#111722;color:white;border-radius:999px;width:34px;height:34px;cursor:pointer;font-size:22px;line-height:1}.preview-bar>.close{position:absolute;right:-14px;top:-14px}.overlay{position:fixed;inset:0;display:grid;place-items:center;background:rgba(2,5,11,.62);backdrop-filter:blur(8px)}.panel-card{position:relative;width:min(520px,calc(100vw - 60px));max-height:76vh;padding:30px;border:1px solid rgba(255,255,255,.14);border-radius:22px;background:linear-gradient(180deg,#101725,#080d16);box-shadow:0 35px 100px rgba(0,0,0,.65)}.panel-close{position:absolute;right:18px;top:18px}.panel-card h1{margin:6px 0 8px;font-size:28px}.panel-card p{margin:0 0 20px;color:rgba(255,255,255,.62)}.panel-body{display:grid;gap:10px;max-height:52vh;overflow:auto}.panel-action{display:flex;align-items:center;justify-content:space-between;width:100%;padding:14px 16px;border:1px solid rgba(255,255,255,.11);border-radius:12px;background:rgba(255,255,255,.04);color:white;cursor:pointer;text-align:left}.panel-action:hover{border-color:#6e95ff;background:rgba(80,120,235,.15)}.panel-action b{font-size:15px}.panel-action span{font-size:12px;color:rgba(255,255,255,.55)}.door-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px}.door-actions .panel-action{justify-content:center;text-align:center}.door-actions .enter{grid-column:1/-1;background:linear-gradient(135deg,#4977f3,#6e95ff);border:0}
|
||||
.empty-state{padding:18px;border:1px dashed rgba(255,255,255,.16);border-radius:12px;color:rgba(255,255,255,.62);text-align:center}.panel-action:disabled{opacity:.55;cursor:wait}
|
||||
Reference in New Issue
Block a user