- initial

This commit is contained in:
Ty Clifford
2026-04-24 08:41:52 -04:00
commit b57091e4ad
49 changed files with 7371 additions and 0 deletions
+386
View File
@@ -0,0 +1,386 @@
<?php
require_once __DIR__.'/includes/boot.php';
$slug = gs('slug');
$b = qone("
SELECT
b.id, b.name, b.slug, b.subcategory, b.description,
b.address, b.phone, b.email, b.website,
COALESCE(b.hours,'{}') AS hours,
b.lat, b.lng, b.is_active, b.is_featured, b.created_at,
b.category_id,
COALESCE(c.name,'Uncategorized') AS cat,
COALESCE(c.icon,'🏢') AS cat_icon,
COALESCE(AVG(CASE WHEN r.is_approved=1 THEN r.rating END), 0) AS avg,
COUNT(CASE WHEN r.is_approved=1 THEN r.id END) AS rcnt
FROM businesses b
LEFT JOIN categories c ON c.id = b.category_id
LEFT JOIN reviews r ON r.business_id = b.id
WHERE b.slug = ? AND b.is_active = 1
GROUP BY b.id
", [$slug]);
if (!$b) { flash('Business not found.','error'); go('/directory.php'); }
/* ── POST handlers ─────────────────────────────────────── */
if (isPost()) {
csrfCheck();
$act = p('_act');
if ($act === 'review' && authed()) {
$rating = max(1, min(5, (int)p('rating', 5)));
$title = ps('rtitle');
$body = ps('rbody');
$ex = qval("SELECT id FROM reviews WHERE business_id=? AND user_id=?", [$b['id'], uid()]);
if ($ex) {
qrun("UPDATE reviews SET rating=?,title=?,body=?,created_at=datetime('now') WHERE id=?",
[$rating, $title, $body, $ex]);
} else {
qrun("INSERT INTO reviews(business_id,user_id,rating,title,body)VALUES(?,?,?,?,?)",
[$b['id'], uid(), $rating, $title, $body]);
}
flash('Review saved!', 'success');
go("/business.php?slug=$slug");
}
if ($act === 'post_alert' && owns($b['id'])) {
$t = ps('atitle');
$body = ps('abody');
$type = p('atype', 'info');
if ($t && $body) {
qrun("INSERT INTO alerts(business_id,type,title,body)VALUES(?,?,?,?)",
[$b['id'], $type, $t, $body]);
flash('Alert posted!', 'success');
}
go("/business.php?slug=$slug");
}
if ($act === 'del_alert' && owns($b['id'])) {
qrun("DELETE FROM alerts WHERE id=? AND business_id=?", [(int)p('aid'), $b['id']]);
go("/business.php?slug=$slug");
}
if ($act === 'del_review' && isAdmin()) {
qrun("DELETE FROM reviews WHERE id=?", [(int)p('rid')]);
flash('Review deleted.', 'success');
go("/business.php?slug=$slug");
}
if ($act === 'report' && authed()) {
$rtype = p('rtype', 'correction');
$rmsg = ps('rmsg');
if ($rmsg) {
qrun("INSERT INTO reports(business_id,user_id,type,message)VALUES(?,?,?,?)",
[$b['id'], uid(), $rtype, $rmsg]);
flash('Report submitted. Thank you!', 'success');
}
go("/business.php?slug=$slug");
}
}
/* ── Page data ─────────────────────────────────────────── */
$pageTitle = e($b['name']) . ' — Keyser, WV';
$activeNav = 'dir';
$reviews = qall("
SELECT r.*, u.username
FROM reviews r
JOIN users u ON u.id = r.user_id
WHERE r.business_id = ? AND r.is_approved = 1
ORDER BY r.created_at DESC
", [$b['id']]);
$sects = qall("SELECT * FROM menu_sections WHERE business_id=? ORDER BY sort_order", [$b['id']]);
$mitems = [];
foreach ($sects as $s) {
$mitems[$s['id']] = qall(
"SELECT * FROM menu_items WHERE section_id=? AND is_available=1 ORDER BY sort_order",
[$s['id']]
);
}
$alerts = qall("SELECT * FROM alerts WHERE business_id=? AND is_active=1 ORDER BY created_at DESC", [$b['id']]);
$myrev = authed() ? qone("SELECT * FROM reviews WHERE business_id=? AND user_id=?", [$b['id'], uid()]) : null;
$hours = parseHours($b['hours']);
$isOwner = owns($b['id']);
$cat = (string)($b['cat'] ?? 'Uncategorized');
$catIcon = (string)($b['cat_icon'] ?? '🏢');
include __DIR__.'/includes/header.php';
?>
<div class="detail-hdr">
<div class="detail-hdr-inner">
<div class="breadcrumb">
<a href="/index.php">Home</a><span></span>
<a href="/directory.php">Directory</a><span></span>
<a href="/directory.php?cat=<?=urlencode($cat)?>"><?=e($catIcon.' '.$cat)?></a><span></span>
<?=e($b['name'])?>
</div>
<div class="cat-badge"><?=e($catIcon.' '.$cat)?><?= $b['subcategory'] ? ' · '.e($b['subcategory']) : '' ?></div>
<h1 style="font-size:clamp(1.9rem,4vw,2.9rem);margin:.4rem 0"><?=e($b['name'])?></h1>
<div class="flex-row" style="margin-top:.6rem;gap:.9rem">
<?=starDisplay((float)($b['avg'] ?? 0))?>
<span class="rat-score"><?=number_format((float)($b['avg'] ?? 0), 1)?></span>
<span class="rat-cnt">(<?=(int)($b['rcnt'] ?? 0)?> review<?=(int)($b['rcnt'] ?? 0) != 1 ? 's' : ''?>)</span>
<?php if ($b['is_featured']): ?><span class="featured-badge">★ FEATURED</span><?php endif; ?>
</div>
</div>
</div>
<div class="detail-body">
<div><!-- main col -->
<?php if ($alerts): ?>
<div style="margin-bottom:1.75rem">
<div class="eyebrow" style="margin-bottom:.6rem">📢 BUSINESS UPDATES</div>
<?php foreach ($alerts as $a): ?>
<div class="alert-item a-<?=e($a['type'] ?? 'info')?>">
<div class="alert-ico"><?=alertIcon($a['type'] ?? '')?></div>
<div style="flex:1">
<div class="alert-title"><?=e($a['title'] ?? '')?></div>
<div class="alert-body"><?=e($a['body'] ?? '')?></div>
<div class="alert-meta"><?=ago($a['created_at'] ?? '')?></div>
</div>
<?php if ($isOwner): ?>
<form method="POST" style="margin-left:.5rem">
<?=csrfField()?>
<input type="hidden" name="_act" value="del_alert">
<input type="hidden" name="aid" value="<?=(int)$a['id']?>">
<button class="btn btn-xs btn-danger" data-confirm="Delete this alert?">✕</button>
</form>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php if ($isOwner): ?>
<div class="ibox" style="border-color:var(--gold-d);margin-bottom:1.75rem">
<div class="ibox-title">📢 POST BUSINESS ALERT</div>
<form method="POST">
<?=csrfField()?>
<input type="hidden" name="_act" value="post_alert">
<div class="form-row" style="margin-bottom:.7rem">
<input type="text" name="atitle" class="finput" placeholder="Alert title" required>
<select name="atype" class="fselect">
<option value="info">️ Info</option>
<option value="news">📰 News</option>
<option value="event">🎉 Event</option>
<option value="warning">⚠️ Warning</option>
<option value="sale">🏷️ Sale / Promo</option>
</select>
</div>
<textarea name="abody" class="ftextarea" style="min-height:65px" placeholder="Alert details…" required></textarea>
<button type="submit" class="btn btn-primary btn-sm" style="margin-top:.65rem">Post Alert</button>
</form>
</div>
<?php endif; ?>
<div class="ibox" style="margin-bottom:1.75rem">
<div class="ibox-title">ABOUT <?=strtoupper(e($b['name']))?></div>
<p style="color:var(--text-m);line-height:1.85"><?=e($b['description'] ?? '')?></p>
</div>
<?php if ($sects): ?>
<div class="ibox" style="margin-bottom:1.75rem">
<div class="ibox-title">🍽️ MENU</div>
<?php foreach ($sects as $s): ?>
<div class="menu-sec">
<div class="menu-sec-name"><?=e($s['name'] ?? '')?></div>
<?php if (!empty($s['description'])): ?>
<div class="menu-sec-desc"><?=e($s['description'])?></div>
<?php endif; ?>
<?php foreach ($mitems[$s['id']] as $mi): ?>
<div class="menu-item">
<div class="mi-info">
<div class="mi-name"><?=e($mi['name'] ?? '')?></div>
<?php if (!empty($mi['description'])): ?>
<div class="mi-desc"><?=e($mi['description'])?></div>
<?php endif; ?>
</div>
<?php if ((float)($mi['price'] ?? 0) > 0): ?>
<div class="mi-price"><?=money((float)$mi['price'])?></div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
<?php if ($isOwner): ?>
<a href="/menu.php?id=<?=(int)$b['id']?>" class="btn btn-outline btn-sm">✏️ Manage Menu</a>
<?php endif; ?>
</div>
<?php elseif ($isOwner): ?>
<div style="margin-bottom:1.75rem">
<a href="/menu.php?id=<?=(int)$b['id']?>" class="btn btn-outline">+ Add Menu</a>
</div>
<?php endif; ?>
<h3 style="font-family:'Oswald',sans-serif;letter-spacing:.1em;font-size:1.05rem;color:var(--text);margin-bottom:1.1rem;padding-bottom:.6rem;border-bottom:1px solid var(--bdr)">
⭐ REVIEWS (<?=(int)($b['rcnt'] ?? 0)?>)
</h3>
<?php if (authed()): ?>
<div class="ibox" style="margin-bottom:1.5rem">
<div class="ibox-title"><?= $myrev ? 'UPDATE YOUR REVIEW' : 'WRITE A REVIEW' ?></div>
<form method="POST">
<?=csrfField()?>
<input type="hidden" name="_act" value="review">
<div class="fg">
<label class="flabel">YOUR RATING</label>
<?=starPicker('rating', (int)($myrev['rating'] ?? 0))?>
</div>
<div class="fg">
<label class="flabel">TITLE (optional)</label>
<input type="text" name="rtitle" class="finput"
value="<?=e($myrev['title'] ?? '')?>" placeholder="One-line summary…">
</div>
<div class="fg">
<label class="flabel">YOUR REVIEW</label>
<textarea name="rbody" class="ftextarea" placeholder="Share your experience…"><?=e($myrev['body'] ?? '')?></textarea>
</div>
<button type="submit" class="btn btn-primary btn-sm">Submit Review</button>
</form>
</div>
<?php else: ?>
<div style="background:var(--bg4);border:1px solid var(--bdr);border-radius:6px;padding:1.1rem;text-align:center;margin-bottom:1.4rem">
<a href="/login.php" class="btn btn-outline btn-sm">Login to Write a Review</a>
</div>
<?php endif; ?>
<?php foreach ($reviews as $r): ?>
<div class="rev-card">
<div class="rev-hdr">
<div>
<div class="rev-author"><?=e($r['username'] ?? 'Anonymous')?></div>
<?=starDisplay((float)($r['rating'] ?? 0))?>
</div>
<div class="flex-row" style="gap:.5rem">
<span class="rev-date"><?=ago($r['created_at'] ?? '')?></span>
<?php if (isAdmin()): ?>
<form method="POST">
<?=csrfField()?>
<input type="hidden" name="_act" value="del_review">
<input type="hidden" name="rid" value="<?=(int)$r['id']?>">
<button class="btn btn-xs btn-danger" data-confirm="Delete this review?">Delete</button>
</form>
<?php endif; ?>
</div>
</div>
<?php if (!empty($r['title'])): ?><div class="rev-title"><?=e($r['title'])?></div><?php endif; ?>
<?php if (!empty($r['body'])): ?><div class="rev-body"><?=e($r['body'])?></div><?php endif; ?>
</div>
<?php endforeach; ?>
<?php if (!$reviews): ?>
<p style="color:var(--text-d);font-size:.88rem">No reviews yet — be the first!</p>
<?php endif; ?>
<hr class="divider">
<?php if (authed()): ?>
<details>
<summary style="cursor:pointer;font-size:.82rem;color:var(--text-d);font-family:'Oswald',sans-serif;letter-spacing:.06em">
🚩 REPORT A LISTING ISSUE
</summary>
<div class="ibox" style="margin-top:.75rem">
<form method="POST">
<?=csrfField()?>
<input type="hidden" name="_act" value="report">
<div class="fg">
<label class="flabel">ISSUE TYPE</label>
<select name="rtype" class="fselect">
<option value="correction">Incorrect Information</option>
<option value="closed">Business Closed / Moved</option>
<option value="hours">Wrong Hours</option>
<option value="phone">Wrong Phone Number</option>
<option value="other">Other Issue</option>
</select>
</div>
<div class="fg">
<label class="flabel">DESCRIBE THE ISSUE</label>
<textarea name="rmsg" class="ftextarea" style="min-height:75px" required
placeholder="Please describe what needs correction…"></textarea>
</div>
<button type="submit" class="btn btn-secondary btn-sm">Submit Report</button>
</form>
</div>
</details>
<?php else: ?>
<p style="font-size:.82rem;color:var(--text-d)">
🚩 <a href="/login.php">Log in</a> to report a listing issue.
</p>
<?php endif; ?>
</div><!-- /main col -->
<div><!-- sidebar -->
<div class="ibox">
<div class="ibox-title">BUSINESS INFO</div>
<?php if (!empty($b['address'])): ?>
<div class="irow"><span class="irow-i">📍</span><span class="irow-v"><?=e($b['address'])?></span></div>
<?php endif; ?>
<?php if (!empty($b['phone'])): ?>
<div class="irow"><span class="irow-i">📞</span>
<a href="tel:<?=e($b['phone'])?>" class="irow-v" style="color:var(--gold)"><?=e($b['phone'])?></a>
</div>
<?php endif; ?>
<?php if (!empty($b['email'])): ?>
<div class="irow"><span class="irow-i">✉️</span>
<a href="mailto:<?=e($b['email'])?>" class="irow-v" style="color:var(--gold)"><?=e($b['email'])?></a>
</div>
<?php endif; ?>
<?php if (!empty($b['website'])): ?>
<div class="irow"><span class="irow-i">🌐</span>
<a href="https://<?=e($b['website'])?>" target="_blank" rel="noopener"
class="irow-v" style="color:var(--gold);word-break:break-all"><?=e($b['website'])?> ↗</a>
</div>
<?php endif; ?>
<div class="irow">
<span class="irow-i">🏷️</span>
<span class="irow-v"><?=e($cat)?><?= !empty($b['subcategory']) ? ' · '.e($b['subcategory']) : '' ?></span>
</div>
</div>
<?php if ($hours): ?>
<div class="ibox">
<div class="ibox-title">🕐 HOURS OF OPERATION</div>
<div class="hrs-grid">
<?php foreach ($hours as $day => $time): ?>
<div class="hrs-row">
<span class="hrs-day"><?=strtoupper(substr(e((string)$day), 0, 3))?></span>
<span class="hrs-time"><?=e((string)$time)?></span>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<?php if (!empty($b['address'])): ?>
<div class="ibox">
<div class="ibox-title">📍 LOCATION</div>
<div style="background:var(--bg4);border:1px dashed var(--bdr);border-radius:4px;padding:1.75rem;text-align:center">
<p style="font-size:.84rem;color:var(--text-m);margin-bottom:.75rem"><?=e($b['address'])?></p>
<a href="https://maps.google.com/?q=<?=urlencode($b['name'].' '.$b['address'])?>"
target="_blank" rel="noopener" class="btn btn-outline btn-sm">Open in Google Maps ↗</a>
</div>
</div>
<?php endif; ?>
<?php if ($isOwner): ?>
<div class="ibox" style="border-color:var(--gold-d)">
<div class="ibox-title">⚙️ OWNER CONTROLS</div>
<a href="/menu.php?id=<?=(int)$b['id']?>" class="btn btn-outline btn-sm btn-block"
style="margin-bottom:.5rem">🍽️ Manage Menu</a>
<?php if (isAdmin()): ?>
<a href="/admin/biz_edit.php?id=<?=(int)$b['id']?>" class="btn btn-secondary btn-sm btn-block">
✏️ Edit Listing
</a>
<?php endif; ?>
</div>
<?php endif; ?>
</div><!-- /sidebar -->
</div><!-- /detail-body -->
<?php include __DIR__.'/includes/footer.php'; ?>