Siteβ―Builder
Editing:
categories.php
writable 0666
<?php $jsonFile = __DIR__ . '/allcategories.json'; $categories = file_exists($jsonFile) ? json_decode(file_get_contents($jsonFile), true) : []; $country = isset($_GET['country']) ? preg_replace('/[^A-Za-z]/','',$_GET['country']) : 'USA'; $state = isset($_GET['state']) ? preg_replace('/[^A-Za-z]/','',$_GET['state']) : 'FL'; $city = isset($_GET['city']) ? preg_replace('/[^A-Za-z0-9\- ]/','',$_GET['city']) : 'Seminole'; $letters = range('A','Z'); $letter = isset($_GET['letter']) && in_array($_GET['letter'], $letters) ? $_GET['letter'] : 'A'; function slugify($cat) { return strtolower(trim(preg_replace('/[^a-z0-9]+/i', '-', $cat), '-')); } function city_folder($city) { return ucfirst(strtolower(str_replace(' ', '-', $city))); } $pageTitle = "Categories Starting with $letter - " . ucwords(str_replace('-', ' ', $city)) . ", $state"; $pageDesc = "Browse all business categories starting with $letter in " . ucwords(str_replace('-', ' ', $city)) . ", $state. Click any category to find local businesses or get listed!"; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title><?= htmlspecialchars($pageTitle) ?> | BestDealOn</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content="<?= htmlspecialchars($pageDesc) ?>"> <style> body { background: #f5f8fb; font-family: system-ui,Arial,sans-serif; margin:0; color:#095a76;} .main { max-width:1200px; margin:2.5em auto 1em; padding:0 1em;} h1 { text-align:center; font-size:2.3rem; color:#016285; margin-bottom:.5em; margin-top:0;} .aznav { text-align:center; margin-bottom:2em; font-size:1.22em; } .aznav a, .aznav strong { color:#014b85; text-decoration:none; font-weight:700; margin:0 .09em; display:inline-block;} .aznav a:hover { color:#e11e9c; text-decoration:underline;} .geoinfo { text-align:center; margin-bottom:.7em; } .geo-bar { display:inline-block; background:#d7ebfd; border-radius:12px; padding:.5em 1.1em; font-size:.97em; font-weight:500; color:#015c92; margin:0 auto 1.5em auto;} .geobutton { background:#5b36ff; color:#fff; border:none; border-radius:6px; font-size:.98em; font-weight:600; padding:.36em 1em; margin-left:1.1em; cursor:pointer;} .geobutton:hover{background:#3b289b;} .catcols { display:flex; flex-wrap:wrap; gap:2em; justify-content:center; margin-top:1.6em; } .catcol { flex:1 1 240px; min-width:220px; max-width:350px;} .catcol ul { list-style:none; margin:0; padding:0; } .catcol li { margin-bottom:.38em; } .catcol a { color:#015c92; text-decoration:underline; font-size:1.05em;} .catcol a:hover { color:#ee2266; } @media(max-width:1000px){ .catcols{flex-direction:column; gap:.2em;} .catcol{max-width:none;} } @media(max-width:600px){ h1{font-size:1.26em;} .main{padding:0 .15em;} } .nearby-block {margin:1.2em auto 1.2em auto; max-width:660px; text-align:center; background:#fffbe9; border:1.2px solid #f5c867; border-radius:11px; padding:.9em .7em;} .nearby-block .title {font-weight:700; color:#ce980c; margin-bottom:.2em;} .nearby-block .citylinks a {margin:0 .7em 0 0; color:#384bb6; text-decoration:underline;} .nearby-block .citylinks a:hover {color:#e11e9c;} .toggle-bar {text-align:center; margin-top:.7em; margin-bottom:.7em;} .toggle-linktype { display:inline-block; padding:.42em 1.5em; font-size:1.08em; font-weight:700; color:#fff; background:#5b36ff; border:none; border-radius:8px; cursor:pointer; box-shadow:0 2px 8px #aebfff22; } .toggle-linktype.bbb { background:#2579b5; } .toggle-linktype:not(.active) { opacity:.65; } .toggle-linktype.active { border:2px solid #2630c0; } </style> </head> <body> <div class="main"> <h1>Categories Starting with <?= htmlspecialchars($letter) ?> - <?= ucwords(str_replace('-', ' ', $city)) ?>, <?= $state ?></h1> <div class="aznav"> <?php foreach($letters as $az): ?> <?= ($az === $letter) ? "<strong>$az</strong>" : '<a href="?country='.urlencode($country).'&state='.urlencode($state).'&city='.urlencode($city).'&letter='.$az.'">'.$az.'</a>' ?> <?php endforeach; ?> </div> <div class="toggle-bar"> <button class="toggle-linktype active" id="bdo-toggle" onclick="switchLinks('bdo')">BestDealOn Links</button> <button class="toggle-linktype bbb" id="bbb-toggle" onclick="switchLinks('bbb')">BBB Links</button> </div> <div class="geoinfo"> <span class="geo-bar"> Current Location: <?= htmlspecialchars(ucwords(str_replace('-', ' ', $city))) ?>, <?= htmlspecialchars($state) ?>, <?= htmlspecialchars($country) ?> <button class="geobutton" onclick="locateMeCategories('<?= $letter ?>')">Geolocate Me</button> </span> <span id="geo-status" style="color:#333;margin-left:.8em;"></span> </div> <div id="nearby-cities"></div> <?php $colCount = 3; $cats = isset($categories[$letter]) ? $categories[$letter] : []; $num = count($cats); $perCol = ceil($num/$colCount); $chunks = array_chunk($cats, $perCol); $cityFolder = city_folder($city); $bdoBase = "/geo/$country/$state/$cityFolder/business.php?type="; $bbbBase = "https://www.bbb.org/us/" . strtolower($state) . "/" . strtolower(str_replace(' ', '-', $city)) . "/category/"; ?> <div class="catcols" id="catcols"> <?php foreach($chunks as $col): ?> <div class="catcol"> <ul> <?php foreach($col as $cat): $slug = slugify($cat['name']); $bdoHref = $bdoBase . urlencode($slug); $bbbHref = $bbbBase . urlencode($slug); ?> <li> <a href="<?= htmlspecialchars($bdoHref) ?>" data-bdo="<?= htmlspecialchars($bdoHref) ?>" data-bbb="<?= htmlspecialchars($bbbHref) ?>" target="_self"><?= htmlspecialchars($cat['name']) ?></a> </li> <?php endforeach; ?> </ul> </div> <?php endforeach; ?> </div> </div> <script> const STATES_BOUNDS_URL = '/geo/json-data/states-bounds.json'; const CITY_LIST_BASE = '/geo/json-data/'; function findStateByLatLon(lat, lon, stateBounds) { for(let i=0;i<stateBounds.length;i++){ let st = stateBounds[i]; if(lat >= st.minLat && lat <= st.maxLat && lon >= st.minLon && lon <= st.maxLon) return st.state; } return ''; } function showNearbyCitiesAndChoose(state, userLat, userLon, letter, country, curCity) { fetch(CITY_LIST_BASE + state + '.json') .then(r=>r.json()).then(cities=>{ let dists = cities.map(c => { let d = Math.hypot(userLat - c.lat, userLon - c.lon); return { city: c.city, state: state, country: country, d }; }); dists.sort((a, b) => a.d - b.d); let [nearest, ...nearby] = dists; let filtered = [nearest].concat( nearby.filter(nb => nb.city.toLowerCase() !== (curCity||'').toLowerCase()).slice(0,5) ); let html = '<div class="nearby-block"><div class="title">Choose your city below:</div><div class="citylinks">' + filtered.map(nb => { let href = '?country='+encodeURIComponent(nb.country)+'&state='+encodeURIComponent(state)+'&city='+encodeURIComponent(nb.city)+'&letter='+encodeURIComponent(letter); return '<a href="'+href+'">'+nb.city+'</a>'; }).join('') + '</div></div>'; document.getElementById('nearby-cities').innerHTML = html; document.getElementById('geo-status').textContent = ''; }); } function locateMeCategories(letter) { if (!navigator.geolocation) { alert("Geolocation not supported."); return; } document.getElementById('geo-status').textContent = 'Detecting...'; navigator.geolocation.getCurrentPosition(function(pos) { let lat = pos.coords.latitude, lon = pos.coords.longitude; fetch(STATES_BOUNDS_URL).then(r=>r.json()).then(stateBounds=>{ let state = findStateByLatLon(lat, lon, stateBounds); if(!state) { alert('State not detected from location.'); document.getElementById('geo-status').textContent = ''; return; } showNearbyCitiesAndChoose(state, lat, lon, letter, 'USA'); }); }, function(){ alert("Geolocation failed."); document.getElementById('geo-status').textContent = ''; }); } // --- Link Toggle --- function switchLinks(type) { document.getElementById('bdo-toggle').classList.toggle('active', type==='bdo'); document.getElementById('bbb-toggle').classList.toggle('active', type==='bbb'); var links = document.querySelectorAll('#catcols a[data-bdo]'); links.forEach(function(link){ link.href = type === 'bdo' ? link.getAttribute('data-bdo') : link.getAttribute('data-bbb'); link.target = (type === 'bdo') ? '_self' : '_blank'; }); } </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel