mirror of
https://github.com/myronblair/do-server-config
synced 2026-07-27 21:18:32 -05:00
178 lines
8.5 KiB
PHP
178 lines
8.5 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/functions.php';
|
|
|
|
$token = $_GET['t'] ?? '';
|
|
$worker = $token ? db()->fetch("SELECT * FROM workers WHERE entry_token = :t AND active = 1", ['t' => $token]) : null;
|
|
|
|
if (!$worker) {
|
|
http_response_code(404);
|
|
echo 'Link not found.';
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'set_day') {
|
|
$date = $_POST['date'] ?? '';
|
|
$status = $_POST['status'] ?? '';
|
|
$reason = trim($_POST['reason'] ?? '');
|
|
$location = trim($_POST['location'] ?? '');
|
|
$currentWeek = currentWeekStart();
|
|
// Only allow editing the current week's dates via this self-entry page
|
|
if (in_array($status, ['full', 'half', 'absent'], true) && in_array($date, getWeekDates($currentWeek), true)) {
|
|
db()->query("
|
|
INSERT INTO day_entries (worker_id, work_date, week_start, status, absence_reason, location)
|
|
VALUES (:wid, :date, :week, :status, :reason, :location)
|
|
ON DUPLICATE KEY UPDATE status = :status2, absence_reason = :reason2, location = :location2
|
|
", [
|
|
'wid' => $worker['id'], 'date' => $date, 'week' => $currentWeek,
|
|
'status' => $status, 'reason' => $reason ?: null, 'location' => $location ?: null,
|
|
'status2' => $status, 'reason2' => $reason ?: null, 'location2' => $location ?: null,
|
|
]);
|
|
}
|
|
header('Location: /w.php?t=' . urlencode($token));
|
|
exit;
|
|
}
|
|
|
|
$markPaidError = '';
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'mark_paid' && ($_POST['week_start'] ?? '') === currentWeekStart()) {
|
|
$weekStart = currentWeekStart();
|
|
$weekDates = getWeekDates($weekStart);
|
|
$ph = implode(',', array_fill(0, count($weekDates), '?'));
|
|
$weekEntries = db()->query("SELECT work_date FROM day_entries WHERE worker_id = ? AND work_date IN ({$ph})", array_merge([$worker['id']], $weekDates))->fetchAll();
|
|
$filledDates = array_column($weekEntries, 'work_date');
|
|
$missing = array_diff($weekDates, $filledDates);
|
|
|
|
if (!empty($missing)) {
|
|
$markPaidError = 'Cannot mark paid - ' . count($missing) . ' day(s) still need an entry.';
|
|
} else {
|
|
$existing = db()->fetch("SELECT * FROM week_settlements WHERE worker_id = :wid AND week_start = :w", ['wid' => $worker['id'], 'w' => $weekStart]);
|
|
if ($existing) {
|
|
db()->update('week_settlements', ['paid' => 1, 'paid_at' => date('Y-m-d H:i:s')], 'id = :id', ['id' => $existing['id']]);
|
|
} else {
|
|
db()->insert('week_settlements', ['worker_id' => $worker['id'], 'week_start' => $weekStart, 'paid' => 1, 'paid_at' => date('Y-m-d H:i:s')]);
|
|
}
|
|
header('Location: /w.php?t=' . urlencode($token));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$currentWeek = currentWeekStart();
|
|
$currentDates = getWeekDates($currentWeek);
|
|
|
|
$currentSettlement = db()->fetch("SELECT * FROM week_settlements WHERE worker_id = :wid AND week_start = :w", ['wid' => $worker['id'], 'w' => $currentWeek]);
|
|
$currentWeekPaid = $currentSettlement ? (bool) $currentSettlement['paid'] : false;
|
|
|
|
$allEntries = db()->fetchAll("SELECT * FROM day_entries WHERE worker_id = :wid ORDER BY work_date DESC", ['wid' => $worker['id']]);
|
|
$entriesByDate = [];
|
|
foreach ($allEntries as $en) { $entriesByDate[$en['work_date']] = $en; }
|
|
|
|
// Past 2 weeks (read-only), excluding current
|
|
$pastWeeks = [];
|
|
foreach ($allEntries as $en) {
|
|
if ($en['week_start'] !== $currentWeek && !in_array($en['week_start'], $pastWeeks, true)) {
|
|
$pastWeeks[] = $en['week_start'];
|
|
}
|
|
}
|
|
rsort($pastWeeks);
|
|
$pastWeeks = array_slice($pastWeeks, 0, 2);
|
|
|
|
$pageTitle = 'My Work Week - ChuckCo Time Keeper';
|
|
require_once __DIR__ . '/includes/header.php';
|
|
?>
|
|
<div class="topbar">
|
|
<h1>Hi, <?= e($worker['name']) ?></h1>
|
|
</div>
|
|
<div class="container">
|
|
|
|
<div class="card">
|
|
<div style="display:flex; justify-content:space-between; align-items:center;">
|
|
<h3 style="margin:0;">This Week — <?= e(dayLabel($currentWeek)) ?></h3>
|
|
<?php if ($currentWeekPaid): ?>
|
|
<span class="badge badge-full">Paid</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<?php if ($currentWeekPaid): ?>
|
|
<?php foreach ($currentDates as $date):
|
|
$entry = $entriesByDate[$date] ?? null;
|
|
if (!$entry) continue;
|
|
?>
|
|
<div class="screenshot-day">
|
|
<div>
|
|
<div class="date"><?= e(dayLabel($date)) ?></div>
|
|
<?php if (!empty($entry['location'])): ?>
|
|
<div class="reason-text"><?= e($entry['location']) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<span class="badge badge-<?= e($entry['status']) ?>"><?= ucfirst($entry['status']) ?></span>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<p class="text-muted" style="font-size:0.85rem; margin-top:0.75rem;">This week is locked in. Come back next week to enter new days.</p>
|
|
<?php else: ?>
|
|
<?php foreach ($currentDates as $date):
|
|
$entry = $entriesByDate[$date] ?? null;
|
|
$status = $entry['status'] ?? null;
|
|
$reason = $entry['absence_reason'] ?? '';
|
|
$location = $entry['location'] ?? '';
|
|
?>
|
|
<div class="day-tap" style="flex-wrap:wrap;">
|
|
<div style="flex:1; min-width:100%;">
|
|
<div class="date"><?= e(dayLabel($date)) ?></div>
|
|
</div>
|
|
<form method="POST" style="width:100%; margin-top:0.5rem;">
|
|
<input type="hidden" name="action" value="set_day">
|
|
<input type="hidden" name="date" value="<?= e($date) ?>">
|
|
<div class="day-btn-row">
|
|
<button type="submit" name="status" value="full" class="day-btn <?= $status === 'full' ? 'active-full' : '' ?>">Full Day</button>
|
|
<button type="submit" name="status" value="half" class="day-btn <?= $status === 'half' ? 'active-half' : '' ?>">Half Day</button>
|
|
<button type="submit" name="status" value="absent" class="day-btn <?= $status === 'absent' ? 'active-absent' : '' ?>">Off</button>
|
|
</div>
|
|
<div class="day-field-row">
|
|
<input type="text" name="location" class="form-input" placeholder="Location" value="<?= e($location) ?>">
|
|
</div>
|
|
<div class="day-field-row">
|
|
<input type="text" name="reason" class="form-input" placeholder="Reason if off (optional)" value="<?= e($reason) ?>">
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<?php if ($markPaidError): ?>
|
|
<div class="alert alert-error" style="margin-top:1rem;"><?= e($markPaidError) ?></div>
|
|
<?php endif; ?>
|
|
<form method="POST" style="margin-top:1rem;" onsubmit="return confirm('Time will be locked in and start new week. Are you sure?');">
|
|
<input type="hidden" name="action" value="mark_paid">
|
|
<input type="hidden" name="week_start" value="<?= e($currentWeek) ?>">
|
|
<button type="submit" class="btn btn-success btn-block">Mark Paid & Lock In Week</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
|
|
<div class="link-row" style="margin-top:0.75rem; justify-content:center;">
|
|
<a class="btn btn-sm btn-secondary" href="/w-history.php?t=<?= e($token) ?>">View History</a>
|
|
</div>
|
|
</div>
|
|
|
|
<?php foreach ($pastWeeks as $weekStart):
|
|
$dates = getWeekDates($weekStart);
|
|
?>
|
|
<div class="card">
|
|
<h3>Week of <?= e(dayLabel($weekStart)) ?></h3>
|
|
<?php foreach ($dates as $date):
|
|
$entry = $entriesByDate[$date] ?? null;
|
|
if (!$entry) continue;
|
|
?>
|
|
<div class="screenshot-day">
|
|
<div>
|
|
<div class="date"><?= e(dayLabel($date)) ?></div>
|
|
<?php if (!empty($entry['location'])): ?>
|
|
<div class="reason-text"><?= e($entry['location']) ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<span class="badge badge-<?= e($entry['status']) ?>"><?= ucfirst($entry['status']) ?></span>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
</div>
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|