{"id":12,"date":"2026-08-24T10:35:20","date_gmt":"2026-08-24T10:35:20","guid":{"rendered":"https:\/\/www.kallihospitality.gr\/?page_id=12"},"modified":"2026-08-24T10:58:22","modified_gmt":"2026-08-24T10:58:22","slug":"boufos-beach","status":"publish","type":"page","link":"https:\/\/www.kallihospitality.gr\/?page_id=12","title":{"rendered":"Boufos beach"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"12\" class=\"elementor elementor-12\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b65611b e-con e-atomic-element e-flexbox-base e-4ffd189 \" data-id=\"b65611b\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"b65611b\">\n    \t\t<div class=\"elementor-element elementor-element-45fc5b1 elementor-widget elementor-widget-html\" data-id=\"45fc5b1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t\r\n<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\r\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\r\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">\r\n<title>Boufos Beach<\/title>\r\n<style>\r\n*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}\r\nbody{font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue',sans-serif;background:#F5F3EF;color:#1C1510;min-height:100vh;overflow-x:hidden}\r\n.topbar{position:fixed;top:0;left:0;right:0;z-index:100;background:#1C1510;padding:12px 16px 0;padding-top:env(safe-area-inset-top,12px)}\r\n.logo{color:#B8975A;font-size:18px;font-weight:700}\r\n.tabs{display:flex;margin-top:6px}\r\n.tab{flex:1;padding:9px;text-align:center;color:#666;font-size:14px;font-weight:600;border:none;background:none;cursor:pointer;border-bottom:3px solid transparent}\r\n.tab.active{color:#B8975A;border-bottom-color:#B8975A}\r\n.stats{display:flex;gap:6px;padding:8px 10px;background:#fff;border-bottom:1px solid #E8E4DC;overflow-x:auto;margin-top:88px}\r\n.stat{flex:0 0 auto;text-align:center;padding:5px 12px;border-radius:20px;background:#F5F3EF;border:1px solid #E8E4DC}\r\n.stat .lbl{font-size:10px;color:#888}\r\n.stat .val{font-size:15px;font-weight:700;color:#1C1510}\r\n.stat.gold .val{color:#B8975A}\r\n.panel{display:none;padding:8px 8px 90px}\r\n.panel.active{display:block}\r\n.beach-row{display:grid;gap:5px;margin-bottom:5px}\r\n.cols-6{grid-template-columns:repeat(6,1fr)}\r\n.set{border-radius:8px;border:2px solid #aaa;background:#EAEAEA;cursor:pointer;overflow:hidden;transition:transform .1s;min-height:68px}\r\n.set:active{transform:scale(.95)}\r\n.set.has-slot1{border-color:#1C6B2E}\r\n.set.has-slot2{border-color:#B8975A}\r\n.hdr{padding:3px 6px;display:flex;justify-content:space-between;align-items:center;background:#888}\r\n.set.has-slot1 .hdr{background:#1C6B2E}\r\n.set.has-slot2 .hdr{background:#B8975A}\r\n.hdr .num{color:#fff;font-weight:800;font-size:13px}\r\n.hdr .pr{color:rgba(255,255,255,.9);font-size:10px;font-weight:600}\r\n.slots{padding:3px 5px}\r\n.slot-row{font-size:10px;color:#555;line-height:1.5;display:flex;align-items:center;gap:4px}\r\n.slot-row.filled{color:#1C1510;font-weight:500}\r\n.slot-num{background:#888;color:#fff;font-size:8px;font-weight:700;border-radius:3px;padding:0 3px;flex-shrink:0}\r\n.slot-num.s1{background:#1C6B2E}\r\n.slot-num.s2{background:#B8975A}\r\n.slot-empty{color:#aaa;font-size:10px}\r\n.slot-note{font-size:10px;font-weight:600;line-height:1.4;padding:2px 0;border-radius:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n.slot-note.s1n{color:#1C6B2E}\r\n.slot-note.s2n{color:#B8975A}\r\n\/* MODAL *\/\r\n.moverlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:200;align-items:flex-end;justify-content:center}\r\n.moverlay.open{display:flex}\r\n.modal{background:#fff;border-radius:20px 20px 0 0;width:100%;max-width:500px;padding-bottom:env(safe-area-inset-bottom,20px);max-height:92vh;overflow-y:auto}\r\n.mhandle{width:36px;height:4px;border-radius:2px;background:#ddd;margin:12px auto 0}\r\n.mhdr{padding:14px 18px 10px;border-bottom:1px solid #eee}\r\n.mtitle{font-size:20px;font-weight:800;color:#1C1510}\r\n.msub{font-size:12px;color:#888;margin-top:2px}\r\n.slot-tabs{display:flex;gap:0;margin:12px 18px 0;border-radius:10px;overflow:hidden;border:1px solid #E8E4DC}\r\n.slot-tab{flex:1;padding:10px;text-align:center;font-size:13px;font-weight:600;cursor:pointer;border:none;background:#F5F3EF;color:#888}\r\n.slot-tab.active{background:#1C1510;color:#B8975A}\r\n.slot-tab.has-data{position:relative}\r\n.slot-tab.has-data::after{content:'\u25cf';position:absolute;top:4px;right:8px;font-size:8px;color:#28A745}\r\n.mbody{padding:14px 18px}\r\n.field{margin-bottom:12px}\r\n.field label{display:block;font-size:11px;font-weight:700;color:#888;margin-bottom:5px;text-transform:uppercase;letter-spacing:.5px}\r\n.field input,.field textarea{width:100%;padding:11px 13px;border:1.5px solid #ddd;border-radius:10px;font-size:16px;color:#1C1510;background:#fff;font-family:inherit}\r\n.field input:focus,.field textarea:focus{outline:none;border-color:#B8975A}\r\n.field textarea{min-height:65px;resize:none}\r\n.pay-row{display:flex;gap:8px}\r\n.pay-btn{flex:1;padding:11px;border-radius:10px;border:2px solid #ddd;background:#fff;font-size:15px;font-weight:600;cursor:pointer;color:#888}\r\n.pay-btn.sel-cash{border-color:#28A745;background:#E8F5E9;color:#155724}\r\n.pay-btn.sel-card{border-color:#1565C0;background:#E3F2FD;color:#0C447C}\r\n.mactions{display:flex;gap:8px;padding:4px 18px 12px}\r\n.btn-save{flex:1;padding:14px;border-radius:12px;background:#B8975A;color:#fff;font-size:16px;font-weight:700;border:none;cursor:pointer}\r\n.btn-clear-slot{padding:14px 14px;border-radius:12px;background:#FEE2E2;color:#DC3545;font-size:14px;font-weight:600;border:none;cursor:pointer}\r\n.botbar{position:fixed;bottom:0;left:0;right:0;z-index:100;display:flex;gap:8px;padding:10px 12px;padding-bottom:env(safe-area-inset-bottom,10px);background:#fff;border-top:1px solid #E8E4DC}\r\n.btn-exp{flex:1;padding:12px;border-radius:10px;background:#1C1510;color:#B8975A;font-size:14px;font-weight:700;border:none;cursor:pointer}\r\n.btn-nd{padding:12px 10px;border-radius:10px;background:#F5F3EF;color:#888;font-size:13px;font-weight:600;border:1px solid #ddd;cursor:pointer}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n<div class=\"topbar\">\r\n  <div style=\"display:flex;justify-content:space-between;align-items:center\">\r\n    <div class=\"logo\">\ud83c\udfd6 Boufos Beach<\/div>\r\n    <span style=\"color:#666;font-size:12px\" id=\"topDate\"><\/span>\r\n  <\/div>\r\n  <div class=\"tabs\">\r\n    <button class=\"tab active\" onclick=\"switchTab('left',this)\">LEFTSIDE<\/button>\r\n    <button class=\"tab\" onclick=\"switchTab('right',this)\">RIGHTSIDE<\/button>\r\n  <\/div>\r\n<\/div>\r\n<div class=\"stats\">\r\n  <div class=\"stat\"><div class=\"lbl\">Occupied<\/div><div class=\"val\" id=\"sOcc\">0<\/div><\/div>\r\n  <div class=\"stat gold\"><div class=\"lbl\">Revenue<\/div><div class=\"val\" id=\"sRev\">\u20ac0<\/div><\/div>\r\n  <div class=\"stat\"><div class=\"lbl\">Cash<\/div><div class=\"val\" id=\"sCash\">\u20ac0<\/div><\/div>\r\n  <div class=\"stat\"><div class=\"lbl\">Card<\/div><div class=\"val\" id=\"sCard\">\u20ac0<\/div><\/div>\r\n<\/div>\r\n<div class=\"panel active\" id=\"panel-left\"><\/div>\r\n<div class=\"panel\" id=\"panel-right\"><\/div>\r\n<div class=\"botbar\">\r\n  <button class=\"btn-exp\" onclick=\"exportData()\">\u2b07 Export<\/button>\r\n  <button class=\"btn-nd\" style=\"background:#1565C0;color:#fff;border:none\" onclick=\"shareData()\">\ud83d\udce4 Share<\/button>\r\n  <button class=\"btn-nd\" style=\"background:#28A745;color:#fff;border:none\" onclick=\"importData()\">\ud83d\udce5 Import<\/button>\r\n  <button class=\"btn-nd\" onclick=\"newDay()\">New Day<\/button>\r\n<\/div>\r\n<!-- MODAL -->\r\n<div class=\"moverlay\" id=\"mOverlay\">\r\n<div class=\"modal\">\r\n  <div class=\"mhandle\"><\/div>\r\n  <div class=\"mhdr\">\r\n    <div class=\"mtitle\" id=\"mTitle\">Set 1<\/div>\r\n    <div class=\"msub\" id=\"mSub\">2-bed \u00b7 \u20ac20<\/div>\r\n  <\/div>\r\n  <div class=\"slot-tabs\">\r\n    <button class=\"slot-tab active\" id=\"stab1\" onclick=\"switchSlot(1)\">Guest 1<\/button>\r\n    <button class=\"slot-tab\" id=\"stab2\" onclick=\"switchSlot(2)\">Guest 2<\/button>\r\n  <\/div>\r\n  <div class=\"mbody\">\r\n    <div class=\"field\"><label>Arrival time (IN)<\/label><input type=\"time\" id=\"mIn\"><\/div>\r\n    <div class=\"field\"><label>Amount paid (\u20ac)<\/label><input type=\"number\" id=\"mAmt\" step=\"0.50\" min=\"0\"><\/div>\r\n    <div class=\"field\"><label>Payment<\/label>\r\n      <div class=\"pay-row\">\r\n        <button class=\"pay-btn\" id=\"bCash\" onclick=\"setPay('cash')\">\ud83d\udcb5 Cash<\/button>\r\n        <button class=\"pay-btn\" id=\"bCard\" onclick=\"setPay('card')\">\ud83d\udcb3 Card<\/button>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"field\"><label>Notes<\/label><textarea id=\"mNotes\" placeholder=\"Guest name, requests...\"><\/textarea><\/div>\r\n  <\/div>\r\n  <div class=\"mactions\">\r\n    <button class=\"btn-save\" onclick=\"saveSlot()\">Save<\/button>\r\n    <button class=\"btn-clear-slot\" onclick=\"clearSlot()\">Clear slot<\/button>\r\n    <button class=\"btn-nd\" onclick=\"closeM()\" style=\"padding:14px 12px\">\u2715<\/button>\r\n  <\/div>\r\n<\/div>\r\n<\/div>\r\n<script>\r\n\/\/ \u2500\u2500 LAYOUT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\/\/ Boufos Beach: 48 sets, split into a left side (Linkerkant) and a right\r\n\/\/ side (Rechterkant), 6 sets per row, numbered left-to-right, top to bottom,\r\n\/\/ exactly like the notebook sketch.\r\nconst SECTIONS = [\r\n  { key:'left',  title:'Linkerkant', rows:[\r\n      [1,2,3,4,5,6],\r\n      [13,14,15,16,17,18],\r\n      [25,26,27,28,29,30],\r\n      [37,38,39,40,41,42]\r\n  ]},\r\n  { key:'right', title:'Rechterkant', rows:[\r\n      [7,8,9,10,11,12],\r\n      [19,20,21,22,23,24],\r\n      [31,32,33,34,35,36],\r\n      [43,44,45,46,47,48]\r\n  ]}\r\n];\r\n\/\/ which section a bed number belongs to, used to filter the stats bar per tab\r\nconst NUM_TO_SECTION = {};\r\nSECTIONS.forEach(s => s.rows.forEach(row => row.forEach(n => { NUM_TO_SECTION[n] = s.key; })));\r\nlet currentTab = 'left';\r\n\/\/ Every set is a standard 2-bed set at the same price. If some numbers\r\n\/\/ should be cabanas \/ doubles \/ a different price later, this is the only\r\n\/\/ place that needs to change.\r\nconst DEFAULT_PRICE = 20;\r\nfunction btype(){ return 'single2'; }\r\nfunction bprice(){ return DEFAULT_PRICE; }\r\nfunction blabel(n){ return String(n); }\r\nconst TMAP = { single2:'2-bed' };\r\n\/\/ \u2500\u2500 STATE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\/\/ data structure: { \"boufos-<num>\": { slot1:{time,amt,pay,notes}, slot2:{...} } }\r\nlet data = JSON.parse(localStorage.getItem('bb_data') || '{}');\r\nlet cur = {num:null, t:null, price:null, lbl:null};\r\nlet activeSlot = 1;\r\nlet pay = null;\r\nfunction now(){const d=new Date();return String(d.getHours()).padStart(2,'0')+':'+String(d.getMinutes()).padStart(2,'0');}\r\n\/\/ \u2500\u2500 RENDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction renderSection(section){\r\n  const el = document.getElementById('panel-'+section.key);\r\n  el.innerHTML = '';\r\n  section.rows.forEach(row => {\r\n    const g = document.createElement('div');\r\n    g.className = 'beach-row cols-6';\r\n    row.forEach(num => {\r\n      const k = 'boufos-'+num;\r\n      const e = data[k] || {};\r\n      const s1 = e.slot1, s2 = e.slot2;\r\n      const t = btype(num);\r\n      const p = bprice(num);\r\n      const l = blabel(num);\r\n      const card = document.createElement('div');\r\n      let cls = 'set';\r\n      if (s2 && s2.time) cls += ' has-slot2';\r\n      else if (s1 && s1.time) cls += ' has-slot1';\r\n      card.className = cls;\r\n      card.onclick = () => openM(num, t, p, l);\r\n      const s1note = s1&&s1.notes ? `<div class=\"slot-note s1n\">\ud83d\udcdd ${s1.notes}<\/div>` : '';\r\n      const s2note = s2&&s2.notes ? `<div class=\"slot-note s2n\">\ud83d\udcdd ${s2.notes}<\/div>` : '';\r\n      const s1txt = s1&&s1.time ? `<span class=\"slot-num s1\">1<\/span> ${s1.time} \u00b7 \u20ac${s1.amt||0} ${s1.pay==='cash'?'\ud83d\udcb5':'\ud83d\udcb3'}` : null;\r\n      const s2txt = s2&&s2.time ? `<span class=\"slot-num s2\">2<\/span> ${s2.time} \u00b7 \u20ac${s2.amt||0} ${s2.pay==='cash'?'\ud83d\udcb5':'\ud83d\udcb3'}` : null;\r\n      card.innerHTML = `\r\n        <div class=\"hdr\">\r\n          <span class=\"num\">${l}<\/span>\r\n          <span class=\"pr\">\u20ac${p%1===0?p:p.toFixed(2)}<\/span>\r\n        <\/div>\r\n        <div class=\"slots\">\r\n          ${s1note}${s2note}\r\n          ${s1txt ? `<div class=\"slot-row filled\">${s1txt}<\/div>` : `<div class=\"slot-empty\">Tap to check in<\/div>`}\r\n          ${s2txt ? `<div class=\"slot-row filled\">${s2txt}<\/div>` : (s1&&s1.time ? `<div class=\"slot-empty\" style=\"font-size:9px;color:#ccc\">+ Guest 2<\/div>` : '')}\r\n        <\/div>`;\r\n      g.appendChild(card);\r\n    });\r\n    el.appendChild(g);\r\n  });\r\n}\r\nfunction render(){\r\n  SECTIONS.forEach(section => renderSection(section));\r\n  updateStats();\r\n}\r\nfunction switchTab(t, btn){\r\n  currentTab = t;\r\n  document.querySelectorAll('.tab').forEach(b=>b.classList.remove('active'));\r\n  btn.classList.add('active');\r\n  document.querySelectorAll('.panel').forEach(p=>p.classList.remove('active'));\r\n  document.getElementById('panel-'+t).classList.add('active');\r\n  updateStats();\r\n}\r\nfunction updateStats(){\r\n  let occ=0, rev=0, cash=0, card=0;\r\n  Object.keys(data).forEach(k=>{\r\n    const num = +k.split('-')[1];\r\n    if (NUM_TO_SECTION[num] !== currentTab) return;\r\n    const e = data[k];\r\n    [e.slot1, e.slot2].forEach(s => {\r\n      if (!s || !s.time) return;\r\n      occ++;\r\n      const a = parseFloat(s.amt)||0;\r\n      rev += a;\r\n      if (s.pay==='cash') cash += a;\r\n      if (s.pay==='card') card += a;\r\n    });\r\n  });\r\n  document.getElementById('sOcc').textContent = occ;\r\n  document.getElementById('sRev').textContent = '\u20ac'+Math.round(rev);\r\n  document.getElementById('sCash').textContent = '\u20ac'+Math.round(cash);\r\n  document.getElementById('sCard').textContent = '\u20ac'+Math.round(card);\r\n}\r\n\/\/ \u2500\u2500 MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction openM(num, t, price, lbl){\r\n  cur = {num, t, price, lbl};\r\n  activeSlot = 1;\r\n  document.getElementById('mTitle').textContent = 'Set ' + lbl;\r\n  document.getElementById('mSub').textContent = TMAP[t] + ' \u00b7 \u20ac' + (price%1===0?price:price.toFixed(2));\r\n  updateSlotTabs();\r\n  loadSlot(1);\r\n  document.getElementById('mOverlay').classList.add('open');\r\n}\r\nfunction closeM(){\r\n  document.getElementById('mOverlay').classList.remove('open');\r\n}\r\nfunction switchSlot(n){\r\n  saveCurrentSlotData();\r\n  activeSlot = n;\r\n  updateSlotTabs();\r\n  loadSlot(n);\r\n}\r\nfunction updateSlotTabs(){\r\n  const k = 'boufos-'+cur.num;\r\n  const e = data[k] || {};\r\n  [1,2].forEach(n => {\r\n    const btn = document.getElementById('stab'+n);\r\n    btn.classList.toggle('active', activeSlot===n);\r\n    btn.classList.toggle('has-data', !!(e['slot'+n] && e['slot'+n].time));\r\n  });\r\n}\r\nfunction loadSlot(n){\r\n  const k = 'boufos-'+cur.num;\r\n  const e = (data[k] || {})['slot'+n];\r\n  document.getElementById('mIn').value = e?.time || now();\r\n  document.getElementById('mAmt').value = e?.amt !== undefined ? e.amt : cur.price;\r\n  document.getElementById('mNotes').value = e?.notes || '';\r\n  pay = e?.pay || null;\r\n  updatePayBtns();\r\n}\r\nfunction saveCurrentSlotData(){\r\n  const k = 'boufos-'+cur.num;\r\n  const timeVal = document.getElementById('mIn').value;\r\n  if (!timeVal) return;\r\n  if (!data[k]) data[k] = {};\r\n  data[k]['slot'+activeSlot] = {\r\n    time: timeVal,\r\n    amt: parseFloat(document.getElementById('mAmt').value)||0,\r\n    pay,\r\n    notes: document.getElementById('mNotes').value.trim()\r\n  };\r\n}\r\nfunction saveSlot(){\r\n  const k = 'boufos-'+cur.num;\r\n  const timeVal = document.getElementById('mIn').value;\r\n  if (!data[k]) data[k] = {};\r\n  data[k]['slot'+activeSlot] = {\r\n    time: timeVal,\r\n    amt: parseFloat(document.getElementById('mAmt').value)||0,\r\n    pay,\r\n    notes: document.getElementById('mNotes').value.trim()\r\n  };\r\n  localStorage.setItem('bb_data', JSON.stringify(data));\r\n  updateSlotTabs();\r\n  closeM();\r\n  render();\r\n}\r\nfunction clearSlot(){\r\n  const k = 'boufos-'+cur.num;\r\n  if (data[k]) {\r\n    delete data[k]['slot'+activeSlot];\r\n    if (!data[k].slot1 && !data[k].slot2) delete data[k];\r\n  }\r\n  localStorage.setItem('bb_data', JSON.stringify(data));\r\n  loadSlot(activeSlot);\r\n  updateSlotTabs();\r\n  render();\r\n}\r\nfunction setPay(p){ pay=p; updatePayBtns(); }\r\nfunction updatePayBtns(){\r\n  document.getElementById('bCash').className='pay-btn'+(pay==='cash'?' sel-cash':'');\r\n  document.getElementById('bCard').className='pay-btn'+(pay==='card'?' sel-card':'');\r\n}\r\n\/\/ \u2500\u2500 EXPORT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\nfunction exportData(){\r\n  const keys = Object.keys(data).sort();\r\n  if (!keys.length){ alert('No data yet.'); return; }\r\n  let csv = 'Set,Type,Slot,Time,Amount,Payment,Notes\\n';\r\n  let summary = '';\r\n  let totalRev=0, totalCash=0, totalCard=0, totalOcc=0;\r\n  keys.forEach(k => {\r\n    const num = k.split('-')[1];\r\n    const e = data[k];\r\n    const t = btype(+num);\r\n    const l = blabel(+num);\r\n    [1,2].forEach(n => {\r\n      const s = e['slot'+n];\r\n      if (!s || !s.time) return;\r\n      totalOcc++;\r\n      const a = parseFloat(s.amt)||0;\r\n      totalRev += a;\r\n      if(s.pay==='cash') totalCash+=a;\r\n      if(s.pay==='card') totalCard+=a;\r\n      csv += `${l},${TMAP[t]||t},${n},${s.time},${a},${s.pay||''},${(s.notes||'').replace(\/,\/g,' ')}\\n`;\r\n      summary += `BOUFOS ${l} | ${s.time} | \u20ac${a} ${s.pay==='cash'?'Cash':'Card'}${s.notes?' | '+s.notes:''}\\n`;\r\n    });\r\n  });\r\n  const header = `=== BOUFOS BEACH \u2014 ${new Date().toLocaleDateString('nl-NL')} ===\\nGuests: ${totalOcc} | Revenue: \u20ac${totalRev.toFixed(2)} | Cash: \u20ac${totalCash.toFixed(2)} | Card: \u20ac${totalCard.toFixed(2)}\\n\\n`;\r\n  summary = header + summary;\r\n  try{\r\n    const a=document.createElement('a');\r\n    a.href='data:text\/csv;charset=utf-8,'+encodeURIComponent(csv);\r\n    a.download=`boufos-beach-${new Date().toISOString().slice(0,10)}.csv`;\r\n    document.body.appendChild(a); a.click(); document.body.removeChild(a);\r\n  }catch(e){}\r\n  const ex=document.getElementById('exportPopup');if(ex)ex.remove();\r\n  const ov=document.createElement('div');\r\n  ov.id='exportPopup';\r\n  ov.style.cssText='position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:300;display:flex;align-items:flex-end;justify-content:center;';\r\n  ov.innerHTML=`<div style=\"background:#fff;border-radius:20px 20px 0 0;width:100%;max-width:500px;padding-bottom:20px;max-height:85vh;display:flex;flex-direction:column\">\r\n    <div style=\"width:36px;height:4px;border-radius:2px;background:#ddd;margin:12px auto 0;flex-shrink:0\"><\/div>\r\n    <div style=\"padding:14px 18px 10px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #eee;flex-shrink:0\">\r\n      <div style=\"font-size:18px;font-weight:800\">Export<\/div>\r\n      <button onclick=\"document.getElementById('exportPopup').remove()\" style=\"width:30px;height:30px;border-radius:50%;background:#f0f0f0;border:none;cursor:pointer;font-size:16px\">\u2715<\/button>\r\n    <\/div>\r\n    <div style=\"padding:12px 18px;overflow-y:auto;flex:1\">\r\n      <p style=\"font-size:12px;color:#888;margin-bottom:8px\">Press and hold \u2192 Select All \u2192 Copy \u2192 paste in Notes or WhatsApp<\/p>\r\n      <textarea id=\"expTxt\" readonly style=\"width:100%;min-height:200px;padding:12px;border:1.5px solid #ddd;border-radius:10px;font-size:12px;font-family:monospace;resize:none;background:#f9f9f9;color:#111\">${summary}<\/textarea>\r\n    <\/div>\r\n    <div style=\"padding:8px 18px;flex-shrink:0\">\r\n      <button onclick=\"const t=document.getElementById('expTxt');t.select();t.setSelectionRange(0,99999);navigator.clipboard.writeText(t.value).then(()=>alert('Copied!')).catch(()=>alert('Hold text \u2192 Select All \u2192 Copy'))\" style=\"width:100%;padding:14px;border-radius:12px;background:#B8975A;color:#fff;font-size:16px;font-weight:700;border:none;cursor:pointer\">Copy to clipboard<\/button>\r\n    <\/div>\r\n  <\/div>`;\r\n  document.body.appendChild(ov);\r\n  ov.addEventListener('click',e=>{if(e.target===ov)ov.remove();});\r\n  setTimeout(()=>{const t=document.getElementById('expTxt');if(t){t.focus();t.select();}},300);\r\n}\r\nfunction shareData(){\r\n  if(!Object.keys(data).length){ alert('No data to share yet.'); return; }\r\n  var lines = [];\r\n  Object.keys(data).sort().forEach(function(k){\r\n    var e = data[k];\r\n    var s1 = e.slot1, s2 = e.slot2;\r\n    if(!s1 || !s1.time) return;\r\n    var line = k\r\n      + '~' + (s1.time||'')\r\n      + '~' + (s1.amt||0)\r\n      + '~' + (s1.pay||'')\r\n      + '~' + (s1.notes||'').replace(\/~\/g,'').replace(\/\\|\/g,'');\r\n    if(s2 && s2.time){\r\n      line += '|'\r\n        + (s2.time||'')\r\n        + '~' + (s2.amt||0)\r\n        + '~' + (s2.pay||'')\r\n        + '~' + (s2.notes||'').replace(\/~\/g,'').replace(\/\\|\/g,'');\r\n    }\r\n    lines.push(line);\r\n  });\r\n  var code = 'BB:' + lines.join(';');\r\n  var ex = document.getElementById('sharePopup'); if(ex) ex.remove();\r\n  var ov = document.createElement('div');\r\n  ov.id = 'sharePopup';\r\n  ov.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:300;display:flex;align-items:flex-end;justify-content:center;';\r\n  ov.innerHTML = '<div style=\"background:#fff;border-radius:20px 20px 0 0;width:100%;max-width:500px;padding-bottom:20px\">'\r\n    + '<div style=\"width:36px;height:4px;border-radius:2px;background:#ddd;margin:12px auto 0\"><\/div>'\r\n    + '<div style=\"padding:14px 18px 10px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #eee\">'\r\n    + '<div><div style=\"font-size:18px;font-weight:800\">\ud83d\udce4 Share data<\/div>'\r\n    + '<div style=\"font-size:12px;color:#888;margin-top:2px\">' + lines.length + ' sets \u00b7 Send via Instagram or WhatsApp<\/div><\/div>'\r\n    + '<button onclick=\"document.getElementById(\\'sharePopup\\').remove()\" style=\"width:30px;height:30px;border-radius:50%;background:#f0f0f0;border:none;cursor:pointer;font-size:16px\">\u2715<\/button>'\r\n    + '<\/div>'\r\n    + '<div style=\"padding:14px 18px\">'\r\n    + '<p style=\"font-size:12px;color:#888;margin-bottom:8px\">1. Press Copy<br>2. Send via Instagram or WhatsApp<br>3. Colleague presses \ud83d\udce5 Import and pastes the code<\/p>'\r\n    + '<textarea id=\"shareCode\" readonly style=\"width:100%;height:90px;padding:10px;border:1.5px solid #ddd;border-radius:10px;font-size:11px;font-family:monospace;resize:none;background:#f9f9f9;word-break:break-all\">' + code + '<\/textarea>'\r\n    + '<\/div>'\r\n    + '<div style=\"padding:0 18px 8px;display:flex;gap:8px\">'\r\n    + '<button onclick=\"copyShareCode()\" style=\"flex:1;padding:14px;border-radius:12px;background:#1565C0;color:#fff;font-size:16px;font-weight:700;border:none;cursor:pointer\">Copy code<\/button>'\r\n    + '<button onclick=\"whatsappShare()\" style=\"padding:14px 16px;border-radius:12px;background:#25D366;color:#fff;font-size:14px;font-weight:700;border:none;cursor:pointer\">WhatsApp<\/button>'\r\n    + '<\/div><\/div>';\r\n  document.body.appendChild(ov);\r\n  ov.addEventListener('click', function(e){ if(e.target===ov) ov.remove(); });\r\n  setTimeout(function(){ var t=document.getElementById('shareCode'); if(t){t.focus();t.select();} }, 300);\r\n}\r\nfunction copyShareCode(){\r\n  var t = document.getElementById('shareCode');\r\n  if(!t) return;\r\n  t.select(); t.setSelectionRange(0, 99999);\r\n  navigator.clipboard.writeText(t.value)\r\n    .then(function(){ document.getElementById('sharePopup').remove(); alert('Copied! Paste in Instagram or WhatsApp.'); })\r\n    .catch(function(){ alert('Hold the code \u2192 Select All \u2192 Copy'); });\r\n}\r\nfunction whatsappShare(){\r\n  var t = document.getElementById('shareCode');\r\n  if(!t) return;\r\n  if(navigator.share){\r\n    navigator.share({title:'Boufos Beach', text:t.value})\r\n      .then(function(){ document.getElementById('sharePopup').remove(); });\r\n  } else {\r\n    alert('Use Copy code instead');\r\n  }\r\n}\r\nfunction importData(){\r\n  var code = prompt('Paste the code from your colleague:');\r\n  if(!code || !code.trim()) return;\r\n  code = code.trim();\r\n  try {\r\n    if(!code.startsWith('BB:')) throw new Error('bad');\r\n    var lines = code.slice(3).split(';');\r\n    lines.forEach(function(line){\r\n      if(!line) return;\r\n      var parts = line.split('|');\r\n      var s1parts = parts[0].split('~');\r\n      var key = s1parts[0];\r\n      if(!data[key]) data[key] = {};\r\n      data[key].slot1 = {time:s1parts[1]||'', amt:parseFloat(s1parts[2])||0, pay:s1parts[3]||'', notes:s1parts[4]||''};\r\n      if(parts[1]){\r\n        var s2parts = parts[1].split('~');\r\n        data[key].slot2 = {time:s2parts[0]||'', amt:parseFloat(s2parts[1])||0, pay:s2parts[2]||'', notes:s2parts[3]||''};\r\n      }\r\n    });\r\n    localStorage.setItem('bb_data', JSON.stringify(data));\r\n    render();\r\n    alert('Data imported! ' + lines.filter(function(l){return l;}).length + ' sets loaded.');\r\n  } catch(e) {\r\n    alert('Invalid code. Make sure the full code was copied.');\r\n  }\r\n}\r\nfunction newDay(){\r\n  const pw = prompt('Enter password to start a new day:');\r\n  if(pw === null) return;\r\n  if(pw !== '1'){\r\n    alert('Wrong password.');\r\n    return;\r\n  }\r\n  data={};\r\n  localStorage.removeItem('bb_data');\r\n  render();\r\n}\r\ndocument.getElementById('mOverlay').addEventListener('click',function(e){if(e.target===this)closeM();});\r\nconst d=new Date();\r\nconst days=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];\r\ndocument.getElementById('topDate').textContent=days[d.getDay()]+' '+d.getDate()+'\/'+(d.getMonth()+1);\r\nrender();\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Boufos Beach \ud83c\udfd6 Boufos Beach LEFTSIDE RIGHTSIDE Occupied0 Revenue\u20ac0 Cash\u20ac0 Card\u20ac0 \u2b07 Export \ud83d\udce4 Share \ud83d\udce5 Import New Day Set 1 2-bed \u00b7 \u20ac20 Guest 1 Guest 2 Arrival time (IN) Amount paid (\u20ac) Payment \ud83d\udcb5 Cash \ud83d\udcb3 Card Notes Save Clear slot \u2715<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-12","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=\/wp\/v2\/pages\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12"}],"version-history":[{"count":10,"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=\/wp\/v2\/pages\/12\/revisions"}],"predecessor-version":[{"id":28,"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=\/wp\/v2\/pages\/12\/revisions\/28"}],"wp:attachment":[{"href":"https:\/\/www.kallihospitality.gr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}