const venuesEl = document.getElementById('venues');
const seedBtn = document.getElementById('seed');
const addBtn = document.getElementById('v-add');
const nameIn = document.getElementById('v-name');
const slugIn = document.getElementById('v-slug');
const makeBtn = document.getElementById('session-make');
const slugSessionIn = document.getElementById('session-slug');
const qrArea = document.getElementById('qr-area');
const crmSee = document.getElementById('crm-see');
const crmJson = document.getElementById('crm-json');
async function listVenues(){
const r = await fetch('/api/admin/venues', {cache:'no-store'});
const items = await r.json();
if (!Array.isArray(items) || items.length === 0){
venuesEl.textContent = '(登録なし)';
return;
}
venuesEl.innerHTML = '
' + items.map(v => `${v.slug} — ${v.name} `).join('') + '
';
}
async function seedDemo(){
const r = await fetch('/api/admin/seed', {method:'POST'});
const j = await r.json();
alert(j.created ? 'デモ店舗を作成しました' : 'デモ店舗は既に存在します');
await listVenues();
}
async function addVenue(){
const name = nameIn.value.trim();
const slug = slugIn.value.trim();
if (!name || !slug){ alert('店名とslugを入力してください'); return; }
const r = await fetch('/api/admin/venues', {
method:'POST',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({name, slug})
});
if (r.ok){ nameIn.value=''; slugIn.value=''; await listVenues(); }
else { const e = await r.json().catch(()=>({})); alert('登録失敗: ' + (e.detail || r.status)); }
}
async function fetchQRObjectURL(sessionId){
const url = `/qrcode/${sessionId}`;
const r = await fetch(url, {cache:'no-store'});
if (!r.ok) throw new Error(`QR取得失敗: ${r.status}`);
const blob = await r.blob();
return URL.createObjectURL(blob);
}
async function makeSession(){
const slug = slugSessionIn.value.trim();
if (!slug){ alert('店舗slugを入力してください'); return; }
const r = await fetch('/api/checkin/session', {
method:'POST',
headers:{'Content-Type':'application/json'},
body: JSON.stringify({venue_slug: slug})
});
const j = await r.json();
if (!r.ok){ alert('発行失敗: ' + (j.detail || r.status)); return; }
const checkinUrl = `/checkin/${j.session_id}`;
// QRはBlob→ObjectURLで確実に表示
let qrObjectUrl = '';
try {
qrObjectUrl = await fetchQRObjectURL(j.session_id);
} catch (e) {
console.error(e);
}
qrArea.innerHTML = `
セッション: ${j.session_id}
画像が表示されない場合は、右のボタンでページを開き、URLを手元のQR生成アプリに貼ってください。
※ QRは5分で失効します。必要に応じて再発行してください。
`;
}
async function seeCRM(){
const r = await fetch('/api/crm/segments', {cache:'no-store'});
const j = await r.json();
crmJson.textContent = JSON.stringify(j, null, 2);
}
seedBtn.onclick = seedDemo;
addBtn.onclick = addVenue;
makeBtn.onclick = makeSession;
crmSee.onclick = seeCRM;
listVenues();