Site Builder
Editing:
hours1.php
writable 0666
<?php /************************************************************************** * HOURS EDITOR – Admin side (USA time‑zone dropdown) * ---------------------------------------------------------------------- * • Weekly schedule, TZ selector (six U.S. zones + custom) * • Special‑dates editor now stacks cleanly (Date → Times → Note) * so nothing overflows on small screens. * © 2025 BestDealOn – PHP 8.1+ **************************************************************************/ require_once __DIR__.'/../lib/auth.php'; require_login(); $root = $_SERVER['DOCUMENT_ROOT']; $slug = preg_replace('/[^a-z0-9_]/i','', $_GET['user'] ?? ''); $ph = preg_replace('/\D/','', $_GET['ph'] ?? ''); if ($slug) { $dir = "$root/social/$slug"; $file = "$dir/hours.json"; $label = '@'.$slug; $viewUrl = "https://bestdealon.com/social/$slug/"; } elseif ($ph && strlen($ph)===10) { $dir = "$root/ph/$ph"; $file = "$dir/hours.json"; $label = $ph; $viewUrl = "https://bestdealon.com/$ph/"; } else { lookup(); } if (!is_dir($dir)) lookup('Profile not found.'); /* ---------- AJAX save ---------- */ if ($_SERVER['REQUEST_METHOD']==='POST'){ $json = file_get_contents('php://input'); if (!is_dir($dir)) mkdir($dir,0777,true); file_put_contents($file,$json,LOCK_EX); echo '{"success":true}'; exit; } /* ---------- load existing ---------- */ $data = is_file($file) ? json_decode(file_get_contents($file),true) : []; $tz = $data['timezone'] ?? ''; $weeklyArr = $data['weekly'] ?? []; $specialArr = $data['special'] ?? []; $days = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']; $weekly = []; foreach ($days as $d) { $row = array_values(array_filter($weeklyArr, fn($w)=>$w['day']===$d))[0] ?? [ 'day'=>$d,'open'=>'09:00','close'=>'17:00','closed'=>false ]; $weekly[] = $row; } /* ---------- US TZ options ---------- */ $tzOpts=[ 'Hawaii‑Aleutian Time (HAT)', 'Alaska Time (AKT)', 'Pacific Time (PT)', 'Mountain Time (MT)', 'Central Time (CT)', 'Eastern Time (ET)' ]; $tzInList = in_array($tz,$tzOpts,true); ?><!doctype html><html lang="en"><head> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <title>Edit Hours – <?= htmlspecialchars($label) ?></title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" referrerpolicy="no-referrer"> <style> :root{--bg:#f5f8fb;--fg:#234;--accent:#2357d7;--accent-dk:#1347c0;--warn:#c9302c} body{margin:0;font-family:system-ui,Arial,sans-serif;background:var(--bg);color:var(--fg)} .top{background:#eee;padding:.8em 1.2em;font-weight:900} .container{max-width:880px;margin:2rem auto;padding:0 1rem} section{background:#fff;border-radius:18px;padding:1.6rem 1.4rem;box-shadow:0 3px 18px #dde3fa50;margin-bottom:2rem} input[type=time],select{padding:.35em .4em;font-size:1rem} .week-row{display:grid;grid-template-columns:120px 120px 120px 80px;gap:1rem;align-items:center;margin:.5rem 0} .closedChk{transform:scale(1.2)} .btn{padding:.5em 1em;font-weight:700;border:none;border-radius:8px;cursor:pointer;font-size:1rem} .add{background:#aac8ff;color:#103e9d}.add:hover{background:#90b4ff} .save{background:var(--accent);color:#fff}.save:hover{background:var(--accent-dk)} .del{background:#ffd5d5;color:var(--warn)}.del:hover{background:#ffcbcb} #msg{font-weight:700;margin-top:1rem} /* === Special‑row grid === */ .special-row{ display:grid; grid-template-columns:1fr auto; /* content + delete btn */ grid-template-areas: "date del" "times del" "note del"; gap:.6rem;align-items:center;margin:.5rem 0;max-width:100%; } .special-row input[type=date]{grid-area:date;width:100%} .time-wrap{grid-area:times;display:flex;gap:.6rem} .time-wrap input{flex:1 1 50%;min-width:110px} .special-row input[type=text]{grid-area:note;width:100%} .special-row .btn.del{grid-area:del} /* ------------ mobile tweaks ------------ */ @media (max-width:600px){ /* weekly rows */ .week-row{display:flex;flex-wrap:wrap;gap:.6rem} .week-row>div:first-child{flex:1 1 100%;text-align:left} .week-row input[type=time]{min-width:110px;flex:1 1 calc(50% - .6rem)} .week-row label{white-space:nowrap} /* shrink time inputs slightly */ .time-wrap input{min-width:95px} } </style></head><body> <div class="top"><a href="/">BestDealOn</a> » <a href="/members/dashboard.php">Dashboard</a> » Hours Editor</div> <a href="<?= htmlspecialchars($viewUrl) ?>" style="float:right;margin:.6rem 1rem 0 0">View Page</a> <div class="container"> <h1><i class="fa-regular fa-clock"></i> Hours for <?= htmlspecialchars($label) ?></h1> <!-- Weekly schedule --> <section> <h2>Weekly Schedule</h2> <div id="weeklyWrap"> <?php foreach($weekly as $row): $d=$row['day']; ?> <div class="week-row" data-day="<?= $d ?>"> <div><strong><?= $d ?></strong></div> <div><input type="time" class="open" value="<?= htmlspecialchars($row['open']) ?>"></div> <div><input type="time" class="close" value="<?= htmlspecialchars($row['close']) ?>"></div> <div><label><input type="checkbox" class="closedChk" <?= !empty($row['closed'])?'checked':'' ?>> Closed</label></div> </div> <?php endforeach; ?> </div> </section> <!-- Time zone selector --> <section> <h2>Time Zone</h2> <?php if($tzInList): ?> <select id="tzSelect"> <option value="">— Choose Time Zone —</option> <?php foreach($tzOpts as $opt): ?> <option <?= $tz===$opt?'selected':'' ?>><?= $opt ?></option> <?php endforeach; ?> </select> <?php else: ?> <select id="tzSelect"> <option value="">— Choose Time Zone —</option> <?php foreach($tzOpts as $opt): ?> <option><?= $opt ?></option> <?php endforeach; ?> </select> <input type="text" id="tzCustom" placeholder="Or custom…" style="width:220px;margin-left:.6rem" value="<?= htmlspecialchars($tz) ?>"> <?php endif; ?> </section> <!-- Special dates --> <section> <h2>Special Dates <button id="addSpecial" class="btn add"><i class="fa fa-plus"></i> Add</button></h2> <div id="specialWrap"></div> </section> <div style="text-align:right"><button id="saveBtn" class="btn save"><i class="fa fa-floppy-disk"></i> Save All</button></div> <div id="msg"></div> </div> <script> const tzSelect = document.getElementById('tzSelect'); const tzCustom = document.getElementById('tzCustom'); const specialWrap = document.getElementById('specialWrap'); const specials = <?= json_encode($specialArr, JSON_UNESCAPED_SLASHES) ?>; renderSpecials(); function renderSpecials(){ specialWrap.innerHTML=''; specials.forEach((s,i)=>specialWrap.appendChild(makeSpRow(s,i))); } function makeSpRow(o,i){ const d=document.createElement('div');d.className='special-row';d.dataset.idx=i; d.innerHTML=` <input type="date" class="sp-date" value="${o.date||''}"> <div class="time-wrap"> <input type="time" class="sp-open" value="${o.open||''}"> <input type="time" class="sp-close" value="${o.close||''}"> </div> <input type="text" class="sp-note" placeholder="Note" value="${o.note||''}"> <button class="btn del">✖</button>`; return d; } document.getElementById('addSpecial').onclick=()=>{ specials.push({date:'',open:'09:00',close:'17:00',note:''}); renderSpecials(); }; specialWrap.addEventListener('click',e=>{ if(e.target.classList.contains('del')){ const i=e.target.parentElement.dataset.idx; specials.splice(i,1); renderSpecials(); } }); /* enable/disable times when closed */ [...document.querySelectorAll('.week-row')].forEach(r=>{ const chk=r.querySelector('.closedChk'); const o =r.querySelector('.open'); const c =r.querySelector('.close'); const toggle=()=>{o.disabled=c.disabled=chk.checked}; chk.onchange=toggle;toggle(); }); /* ---------- save ---------- */ async function save(){ const weekly=[...document.querySelectorAll('.week-row')].map(r=>({ day:r.dataset.day, open:r.querySelector('.open').value, close:r.querySelector('.close').value, closed:r.querySelector('.closedChk').checked })); const sp=[...document.querySelectorAll('.special-row')].map(r=>({ date:r.querySelector('.sp-date').value, open:r.querySelector('.sp-open').value, close:r.querySelector('.sp-close').value, note:r.querySelector('.sp-note').value })).filter(x=>x.date); let tz=tzSelect.value; if(!tz) tz=tzCustom?tzCustom.value.trim():''; const payload={timezone:tz,weekly:weekly,special:sp}; const resp=await fetch(location.href,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)}); const m=document.getElementById('msg'); m.textContent=resp.ok?'✅ Saved':'❌ Error'; m.style.color=resp.ok?'green':'#c9302c'; setTimeout(()=>m.textContent='',2300); } document.getElementById('saveBtn').onclick=save; </script> </body></html>
Save changes
Create folder
writable 0777
Create
Cancel