Siteβ―Builder
Editing:
addbusiness.php
writable 0666
<?php $phDir = $_SERVER['DOCUMENT_ROOT'] . '/ph/'; $templateFile = $_SERVER['DOCUMENT_ROOT'] . '/ph/profile-index.php'; // <-- Make sure this exists! $msg = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['phone'], $_POST['name'])) { $phone = preg_replace('/\D/', '', $_POST['phone']); $phone10 = substr($phone, -10); $dir = $phDir . $phone10; if (is_dir($dir)) { $msg = "β That business already exists! <a href='/ph/$phone10/'>View page</a>"; } else { mkdir($dir, 0777, true); $data = [ 'name' => trim($_POST['name']), 'slogan' => trim($_POST['slogan']), 'description' => trim($_POST['description']), 'address' => trim($_POST['address']), 'city' => trim($_POST['city']), 'state' => trim($_POST['state']), 'zip' => trim($_POST['zip']), 'phone' => $phone10, 'website' => trim($_POST['website']), 'tags' => array_filter(array_map('trim', explode(',', $_POST['tags'] ?? ''))), 'location_tags' => array_filter(array_map('trim', explode(',', $_POST['location_tags'] ?? ''))), 'lat' => trim($_POST['lat'] ?? ''), 'lon' => trim($_POST['lon'] ?? ''), ]; file_put_contents("$dir/new-business.json", json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE)); if (is_readable($templateFile)) copy($templateFile, "$dir/index.php"); $msg = "β Business added! <a href='/ph/$phone10/'>View your business page</a>"; } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Add Your Business | BestDealOn</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="robots" content="noindex,follow"> <style> body {background:#f5f8fb;font-family:system-ui,Arial,sans-serif;margin:0;color:#234;} h1 {text-align:center;color:#2257a2;} .wrap {max-width:520px;margin:2.7em auto;background:#fff;padding:2em 2em 2em 2em;border-radius:17px;box-shadow:0 2px 18px #dde3fa33;} .cta {background:#ecfbf1;border-radius:10px;padding:1em 1.1em;margin-bottom:2em;font-size:1.08em;color:#175e35;text-align:center;} input[type=text],input[type=tel],textarea,select { width:100%;padding:.7em;border-radius:7px;border:1.4px solid #b7c2df;margin-bottom:1.13em;font-size:1.08em;} input[type=submit],button {padding:.7em 1.4em;font-size:1.1em;font-weight:700;background:#2357d7;color:#fff;border:none;border-radius:8px;cursor:pointer;transition:background .16s;} input[type=submit]:hover:enabled, button:hover:enabled {background:#0a3798;} input[type=submit]:disabled, button:disabled { background: #8ba0c5 !important; color: #dbe7fa !important; cursor: not-allowed !important; opacity: .72; } .lab {font-weight:600;margin-bottom:.2em;display:block;} .msg {text-align:center;margin-bottom:1.4em;font-size:1.07em;} .location-tag {display:inline-block;background:#e6f0fa;color:#17468d;border-radius:14px;padding:.22em .85em;margin:.08em .2em .18em 0;font-size:.99em;position:relative;} .location-tag .del {cursor:pointer;color:#c63c27;font-size:1.13em;margin-left:.22em;} .location-tag .del:hover {color:#d80d19;} #addTag {margin-bottom:1.1em;} @media (max-width:600px){.wrap{padding:1em .1em 1em .1em;max-width:99vw;}} </style> <script> let userLat = '', userLon = '', userState = '', userCity = '', userCitiesList = []; let tags = []; let phoneAvailable = false; function locateMe() { if (!navigator.geolocation) { alert("Geolocation not supported."); return; } document.getElementById('geo-status').textContent = "Locating..."; navigator.geolocation.getCurrentPosition(function(pos) { userLat = pos.coords.latitude; userLon = pos.coords.longitude; document.getElementById('lat').value = userLat; document.getElementById('lon').value = userLon; fetch('/geo/json-data/states-bounds.json').then(r=>r.json()).then(bounds=>{ let st = ''; bounds.forEach(function(b){ if (userLat >= b.minLat && userLat <= b.maxLat && userLon >= b.minLon && userLon <= b.maxLon) st=b.state; }); if(st) { userState = st; document.getElementById('state').value = st; fetch('/geo/json-data/'+st+'.json').then(r=>r.json()).then(cities=>{ let nearest = null, bestDist = 1e9; userCitiesList = cities; cities.forEach(c=>{ let d = Math.hypot(userLat-c.lat, userLon-c.lon); if (d < bestDist) { bestDist = d; nearest = c; } }); if (nearest) { userCity = nearest.city; document.getElementById('city').value = nearest.city; document.getElementById('lat').value = nearest.lat; document.getElementById('lon').value = nearest.lon; document.getElementById('geo-status').innerHTML = "Location found: <b>" + nearest.city + ", " + st + "</b>."; let dists = cities.map(c=>({city:c.city, d:Math.hypot(userLat-c.lat,userLon-c.lon)})); dists.sort((a,b)=>a.d-b.d); let preTags = [nearest.city, st]; for (let i=1; i<7 && i<dists.length; ++i) preTags.push(dists[i].city); setTags(preTags); document.getElementById('business-form').style.display = ''; checkFormReady(); } }); } else { document.getElementById('geo-status').textContent = "Not in USA/States."; } }); }, function(){ document.getElementById('geo-status').textContent = "Failed."; }); } function setTags(arr) { tags = [...new Set(arr)]; renderChips(); } function renderChips() { const wrap = document.getElementById('location-tags'); wrap.innerHTML = ''; tags.forEach((tag, idx) => { let chip = document.createElement('span'); chip.className = 'location-tag'; chip.dataset.val = tag; chip.textContent = tag; let btn = document.createElement('span'); btn.className = 'del'; btn.innerHTML = '×'; btn.onclick = () => { tags.splice(idx, 1); renderChips(); checkFormReady(); }; chip.appendChild(btn); wrap.appendChild(chip); }); document.getElementById('location_tags').value = tags.join(', '); checkFormReady(); } function addTagsFromInput() { const input = document.getElementById('addTag'); let newTags = input.value.split(',').map(s=>s.trim()).filter(Boolean); let changed = false; newTags.forEach(tag=>{ if(tag && !tags.includes(tag)){ tags.push(tag); changed=true; } }); if (changed) renderChips(); input.value = ''; checkFormReady(); } // ----------- Lat/Lon auto-update on City/State manual edits ----------- function updateLatLonFromCityState() { const state = document.getElementById('state').value.trim().toUpperCase(); const city = document.getElementById('city').value.trim(); if (state && city) { fetch('/geo/json-data/' + state + '.json') .then(r => r.json()) .then(cities => { const match = cities.find(c => c.city.toLowerCase() === city.toLowerCase()); if (match) { document.getElementById('lat').value = match.lat; document.getElementById('lon').value = match.lon; } }); } } window.addEventListener('DOMContentLoaded', function() { document.getElementById('business-form').style.display = 'none'; document.getElementById('locateBtn').addEventListener('click', function() { locateMe(); }); document.getElementById('addTag').addEventListener('keydown', function(e){ if(e.key === "Enter" || e.key === "," ) { e.preventDefault(); addTagsFromInput(); } if(e.key==='Backspace' && this.value===''){ if(tags.length){ tags.pop(); renderChips(); checkFormReady();} } }); document.getElementById('addTag').addEventListener('blur', function(e){ addTagsFromInput(); }); // Phone field, formatting, check via AJAX to check.php document.getElementById('phone').addEventListener('input', function(e) { let nums = this.value.replace(/\D/g,'').slice(0,10); let out = nums; if(nums.length > 6) out = `(${nums.substr(0,3)})-${nums.substr(3,3)}-${nums.substr(6,4)}`; else if(nums.length > 3) out = `(${nums.substr(0,3)})-${nums.substr(3)}`; this.value = out; document.getElementById('business-id').textContent = nums; if(nums.length === 10) { fetch('/ph/check.php?phone='+nums).then(r=>r.json()).then(data=>{ if (data.exists) { document.getElementById('phone-status').innerHTML = '<span style="color:#d92c2c;font-weight:700;">β Already exists</span>'; phoneAvailable = false; document.getElementById('addBtn').disabled = true; } else { document.getElementById('phone-status').innerHTML = '<span style="color:#20b934;font-weight:700;">β Available to claim!</span>'; phoneAvailable = true; checkFormReady(); } }); } else { document.getElementById('phone-status').innerHTML = ''; phoneAvailable = false; document.getElementById('addBtn').disabled = true; } }); // Lat/Lon always sync with manual city/state change document.getElementById('city').addEventListener('input', updateLatLonFromCityState); document.getElementById('state').addEventListener('input', updateLatLonFromCityState); Array.from(document.querySelectorAll('#business-form input, #business-form textarea')).forEach(i=>{ i.addEventListener('input', checkFormReady); }); }); function checkFormReady() { let phoneOk = phoneAvailable; let ready = ( phoneOk && document.getElementById('phone').value.replace(/\D/g,'').length === 10 && document.getElementById('name').value.trim() && document.getElementById('description').value.trim() && document.getElementById('address').value.trim() && document.getElementById('city').value.trim() && document.getElementById('state').value.trim() && document.getElementById('zip').value.trim() && tags.length >= 2 && document.getElementById('phone-status').innerHTML.indexOf('Available')!==-1 ); document.getElementById('addBtn').disabled = !ready; } </script> </head> <body> <div class="wrap"> <h1>Add Your Business</h1> <div class="cta"> <b>Step 1: Click "Locate Me" to begin</b><br> <button type="button" id="locateBtn">π Locate Me</button> <span id="geo-status" style="margin-left:.8em;color:#1067a8;"></span> </div> <?php if($msg): ?><div class="msg" style="color:<?=strpos($msg,'β ')!==false?'green':'red'?>"><?= $msg ?></div><?php endif; ?> <form id="business-form" method="post" autocomplete="off" style="display:none;"> <input type="hidden" id="lat" name="lat"> <input type="hidden" id="lon" name="lon"> <label class="lab" for="phone">Business Phone (10 digits)</label> <input type="text" id="phone" name="phone" maxlength="16" placeholder="(727)-610-1111" required autocomplete="off"> <div style="margin-bottom:.6em;"> <span>Business ID: <span id="business-id" style="font-family:monospace;font-size:1.04em;"></span></span> <span id="phone-status" style="margin-left:.8em;"></span> </div> <label class="lab" for="name">Business Name</label> <input type="text" id="name" name="name" maxlength="80" required> <label class="lab" for="slogan">Slogan (optional)</label> <input type="text" id="slogan" name="slogan" maxlength="120"> <label class="lab" for="description">Description</label> <textarea id="description" name="description" maxlength="500" required></textarea> <label class="lab" for="address">Street Address</label> <input type="text" id="address" name="address" maxlength="120" required> <div style="display:flex;gap:1.1em;"> <div style="flex:2"> <label class="lab" for="city">City</label> <input type="text" id="city" name="city" maxlength="40" required> </div> <div style="flex:1.1"> <label class="lab" for="state">State (2-letter)</label> <input type="text" id="state" name="state" maxlength="2" required> </div> <div style="flex:1.2"> <label class="lab" for="zip">ZIP Code</label> <input type="text" id="zip" name="zip" maxlength="12" required> </div> </div> <label class="lab" for="website">Website (optional)</label> <input type="text" id="website" name="website" maxlength="120"> <label class="lab" for="tags">Business Tags (comma separated)</label> <input type="text" id="tags" name="tags" maxlength="120" placeholder="e.g. Restaurant, Pizza, Delivery"> <label class="lab" for="location-tags">Location Tags</label> <div id="location-tags" style="margin-bottom:.5em;"></div> <input type="hidden" id="location_tags" name="location_tags"> <input type="text" id="addTag" placeholder="Add more tags (comma separated)" autocomplete="off"> <input type="submit" id="addBtn" value="Add My Business π" disabled> </form> </div> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel