387 lines
15 KiB
PHP
387 lines
15 KiB
PHP
<?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'; ?>
|