Files
MyKeyser/events.php
T
Ty Clifford 354bb4255d - Rebuilt the CLI importer to use the official Facebook Graph API instead of HTML scraping.
Main changes:
Replaced 
[scripts/facebook-events-import.php](/Users/tyemeclifford/Documents/GH/MyKeyser/scripts/facebook-events-import.php) 
with a Graph API client.
It now supports --page-id, --pages-file, --event-id, --events-file, and 
optional area discovery via --discover-pages --center=LAT,LNG 
--query=....
Uses FACEBOOK_GRAPH_ACCESS_TOKEN or --access-token.
Pulls Graph fields for title, description, start/end time, 
place/location, ticket URI, and cover.source for the main photo.
Keeps the existing staged review/import workflow in 
/admin/event_imports.php.

- Implemented event detail pages and clickable event cards.
What changed:
Added [event.php](/Users/tyemeclifford/Documents/GH/MyKeyser/event.php) 
for individual event pages.
Made event cards clickable from 
[events.php](/Users/tyemeclifford/Documents/GH/MyKeyser/events.php), 
[index.php](/Users/tyemeclifford/Documents/GH/MyKeyser/index.php), and 
legacy 
[2index.php](/Users/tyemeclifford/Documents/GH/MyKeyser/2index.php).
Added large event photo display plus lightbox enlargement in 
[assets/css/style.css](/Users/tyemeclifford/Documents/GH/MyKeyser/assets/css/style.css) 
and 
[assets/js/app.js](/Users/tyemeclifford/Documents/GH/MyKeyser/assets/js/app.js).
Added eventUrl() and externalHref() helpers in 
[includes/functions.php](/Users/tyemeclifford/Documents/GH/MyKeyser/includes/functions.php).
Added copy-event-link support on event detail pages.
Updated README to list the new route.
2026-06-19 18:07:45 -04:00

140 lines
9.0 KiB
PHP

<?php
require_once __DIR__.'/includes/boot.php';
$activeNav='events'; $pageTitle='Events — Keyser, WV';
$showForm=!empty($_GET['submit']);
$errors=[];
if(isPost()&&ps('_act')==='submit_event'){
csrfCheck();
if(!authed()){flash('Please log in to submit an event.','warning');go('/login.php?next=/events.php?submit=1');}
$title=ps('title');$desc=ps('description');$venue=ps('venue');$addr=ps('address');
$date=ps('event_date');$time=ps('event_time');$edate=ps('end_date');$etime=ps('end_time');
$cost=ps('cost');$web=ps('website');$cn=ps('contact_name');$ce=ps('contact_email');$cp=ps('contact_phone');
if(!$title) $errors[]='Event title is required.';
if(!$date) $errors[]='Event date is required.';
$imagePath = '';
if(!$errors){
$upload = storeSingleUpload(
'event_image',
'events',
imageExts(),
mbToBytes(setting('event_upload_max_mb','5'), 5),
[
'image_only' => true,
'resize_over_bytes' => mbToBytes(setting('forum_image_resize_threshold_mb','1'), 1),
'image_max_width' => (int)setting('forum_image_max_width','1600'),
'image_quality' => (int)setting('forum_image_quality','82'),
]
);
if (!$upload['ok']) $errors[] = $upload['error'];
else $imagePath = (string)($upload['path'] ?? '');
}
if(!$errors){
$status=setting('events_require_approval','1')==='1'?'pending':'approved';
qrun("INSERT INTO events(title,description,venue,address,event_date,event_time,end_date,end_time,cost,website,contact_name,contact_email,contact_phone,image_path,submitted_by,status)VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
[$title,$desc,$venue,$addr,$date,$time,$edate?:null,$etime,$cost,$web,$cn,$ce,$cp,$imagePath,uid(),$status]);
flash($status==='approved'?'Event submitted and published!':'Event submitted! It will appear after review.','success');
go('/events.php');
}
$showForm=true;
}
$page=max(1,iget('page')); $perPage=10;
$total=(int)qval("SELECT COUNT(*) FROM events WHERE status='approved' AND(event_date>=date('now') OR(end_date IS NOT NULL AND end_date>=date('now')))");
$pages=max(1,(int)ceil($total/$perPage)); $page=min($page,$pages); $offset=($page-1)*$perPage;
$events=qall("SELECT e.*,u.username submitter FROM events e LEFT JOIN users u ON u.id=e.submitted_by WHERE e.status='approved' AND(e.event_date>=date('now') OR(e.end_date IS NOT NULL AND e.end_date>=date('now'))) ORDER BY e.is_featured DESC,e.event_date ASC LIMIT $perPage OFFSET $offset");
include __DIR__.'/includes/header.php';
?>
<div class="page-hdr">
<div class="page-hdr-inner" style="display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:1rem">
<div>
<div class="eyebrow">COMMUNITY CALENDAR</div>
<h1 style="font-size:clamp(2rem,4vw,2.9rem);margin-bottom:.4rem">Events in Keyser, WV</h1>
<p style="color:var(--text-m)">Festivals, sports, community gatherings, arts, and more in Mineral County.</p>
</div>
<?php if(authed()): ?>
<a href="/events.php?submit=1" class="btn btn-primary">+ Submit Event</a>
<?php else: ?>
<a href="/login.php?next=/events.php?submit=1" class="btn btn-outline">Login to Submit Event</a>
<?php endif; ?>
</div>
</div>
<?php if($showForm&&authed()): ?>
<div class="section-sm" style="padding-bottom:0">
<div class="ibox" style="border-color:var(--gold-d)">
<div class="ibox-title">📅 SUBMIT A COMMUNITY EVENT</div>
<?php if($errors): ?><div class="err-box"><?=implode('<br>',array_map('e',$errors))?></div><?php endif; ?>
<form method="POST" enctype="multipart/form-data"><?=csrfField()?><input type="hidden" name="_act" value="submit_event">
<div class="fg"><label class="flabel">EVENT TITLE *</label><input type="text" name="title" class="finput" value="<?=e($_POST['title']??'')?>" required></div>
<div class="fg"><label class="flabel">DESCRIPTION</label><textarea name="description" class="ftextarea" style="min-height:110px"><?=e($_POST['description']??'')?></textarea></div>
<div class="form-row">
<div class="fg"><label class="flabel">VENUE / LOCATION</label><input type="text" name="venue" class="finput" value="<?=e($_POST['venue']??'')?>"></div>
<div class="fg"><label class="flabel">ADDRESS</label><input type="text" name="address" class="finput" value="<?=e($_POST['address']??'')?>"></div>
</div>
<div class="form-row">
<div class="fg"><label class="flabel">START DATE *</label><input type="date" name="event_date" class="finput" value="<?=e($_POST['event_date']??'')?>" required></div>
<div class="fg"><label class="flabel">START TIME</label><input type="text" name="event_time" class="finput" value="<?=e($_POST['event_time']??'')?>" placeholder="e.g. 7:00 PM"></div>
</div>
<div class="form-row">
<div class="fg"><label class="flabel">END DATE (if multi-day)</label><input type="date" name="end_date" class="finput" value="<?=e($_POST['end_date']??'')?>"></div>
<div class="fg"><label class="flabel">END TIME</label><input type="text" name="end_time" class="finput" value="<?=e($_POST['end_time']??'')?>" placeholder="e.g. 10:00 PM"></div>
</div>
<div class="form-row">
<div class="fg"><label class="flabel">COST / ADMISSION</label><input type="text" name="cost" class="finput" value="<?=e($_POST['cost']??'Free')?>" placeholder="Free, $10, Varies…"></div>
<div class="fg"><label class="flabel">WEBSITE</label><input type="text" name="website" class="finput" value="<?=e($_POST['website']??'')?>" placeholder="example.com"></div>
</div>
<div class="fg">
<label class="flabel">EVENT IMAGE</label>
<input type="file" name="event_image" class="finput" accept="image/*">
<div class="fhint">Optional JPG, PNG, GIF, or WebP. Max <?=e(setting('event_upload_max_mb','5'))?> MB.</div>
</div>
<div class="form-row">
<div class="fg"><label class="flabel">CONTACT NAME</label><input type="text" name="contact_name" class="finput" value="<?=e($_POST['contact_name']??'')?>"></div>
<div class="fg"><label class="flabel">CONTACT PHONE</label><input type="text" name="contact_phone" class="finput" value="<?=e($_POST['contact_phone']??'')?>"></div>
</div>
<div class="flex-row">
<button type="submit" class="btn btn-primary">Submit Event</button>
<a href="/events.php" class="btn btn-secondary">Cancel</a>
</div>
<?php if(setting('events_require_approval','1')==='1'): ?><p class="fhint" style="margin-top:.65rem">Events are reviewed by an administrator before appearing publicly.</p><?php endif; ?>
</form>
</div>
</div>
<?php elseif(!empty($_GET['submit'])&&!authed()): ?>
<div style="text-align:center;padding:3rem;color:var(--text-m)"><p>Please <a href="/login.php?next=/events.php?submit=1">log in</a> to submit an event.</p></div>
<?php endif; ?>
<div class="section">
<?php if($events): ?>
<?php foreach($events as $ev): ?>
<a href="<?=e(eventUrl($ev))?>" class="evt-card evt-link-card">
<?php if(!empty($ev['image_path'])): ?>
<div class="evt-image-wrap"><img src="<?=e($ev['image_path'])?>" alt="<?=e($ev['title'])?>" class="evt-image"></div>
<?php endif; ?>
<div class="evt-date-box">
<div class="evt-mon"><?=strtoupper(date('M',strtotime($ev['event_date'])))?></div>
<div class="evt-day"><?=date('j',strtotime($ev['event_date']))?></div>
<div class="evt-yr"><?=date('Y',strtotime($ev['event_date']))?></div>
</div>
<div class="evt-body">
<div class="evt-title"><?=e($ev['title'])?><?php if($ev['is_featured']): ?> <span class="featured-badge" style="margin-left:.5rem">★ FEATURED</span><?php endif; ?></div>
<div class="evt-meta">
<?php if($ev['venue']): ?><span>📍 <?=e($ev['venue'])?></span><?php endif; ?>
<?php if($ev['event_time']): ?><span>🕐 <?=e($ev['event_time'])?></span><?php endif; ?>
<?php if($ev['end_date']&&$ev['end_date']!==$ev['event_date']): ?><span>📅 thru <?=fdate($ev['end_date'])?></span><?php endif; ?>
<span>💰 <?=e($ev['cost'])?></span>
<?php if($ev['contact_phone']): ?><span>📞 <?=e($ev['contact_phone'])?></span><?php endif; ?>
</div>
<div class="evt-desc"><?=e($ev['description'])?></div>
<div class="evt-actions"><span class="btn btn-outline btn-sm">View Event</span></div>
</div>
</a>
<?php endforeach; ?>
<?php if($pages>1): ?><div style="display:flex;justify-content:center;gap:.5rem;margin-top:2rem;flex-wrap:wrap"><?php for($i=1;$i<=$pages;$i++): ?><a href="?page=<?=$i?>" class="btn btn-sm<?=$i===$page?' btn-primary':' btn-outline'?>"><?=$i?></a><?php endfor; ?></div><?php endif; ?>
<?php else: ?>
<div class="empty"><div class="empty-ico">📅</div><h3>No upcoming events listed</h3><p style="margin-top:.5rem">Be the first to submit a community event!</p><?php if(authed()): ?><a href="/events.php?submit=1" class="btn btn-primary" style="margin-top:1.5rem">Submit an Event</a><?php endif; ?></div>
<?php endif; ?>
</div>
<?php include __DIR__.'/includes/footer.php'; ?>