Show sourcecode
The following files exists in this folder. Click to view.
public_html/smartkortet/pages/
hem.php
historik.php
installningar.php
restauranger.php
statistik.php
hem.php
208 lines UTF-8 Windows (CRLF)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
<?php
declare(strict_types=1);
require_once __DIR__ . '/../includes/data.php';
$userId = (int) $user['id'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verifyCsrf();
$action = $_POST['action'] ?? '';
if ($action === 'save_budget') {
$startingBalance = parseAmount($_POST['starting_balance'] ?? '0');
$periodEnd = $_POST['period_end'] ?? '';
if ($startingBalance < 0 || $periodEnd === '') {
setFlash('error', 'Ange ett giltigt saldo och slutdatum.');
} else {
saveUserBudget($userId, $startingBalance, $periodEnd);
setFlash('success', 'Budgetperiod sparad.');
}
redirect('/index.php?tab=hem');
}
if ($action === 'add_spend') {
$amount = parseAmount($_POST['amount'] ?? '0');
$spentOn = normalizeIsoDate($_POST['spent_on'] ?? null, '');
$selectedPlace = normalizeNullableString($_POST['place_name'] ?? null);
$saveFavorite = isset($_POST['save_favorite']);
if ($amount < 0 || $amount > 90 || $spentOn === '') {
setFlash('error', 'Du kan registrera mellan 0 och 90 kr per dag.');
redirect('/index.php?tab=hem');
}
$todayDate = date('Y-m-d');
if ($spentOn === $todayDate) {
$budgetMetricsForValidation = calculateBudgetMetrics($userId);
$todayBudgetRemaining = (float) ($budgetMetricsForValidation['today_budget_remaining'] ?? 0.0);
if ($amount > $todayBudgetRemaining + 0.0001) {
setFlash(
'error',
sprintf('Köpet överskrider dagens kvarvarande budget (%s).', formatCurrency($todayBudgetRemaining))
);
redirect('/index.php?tab=hem');
}
}
addSpendEntry($userId, $amount, $spentOn, $selectedPlace);
if ($saveFavorite && $selectedPlace !== null) {
saveFavoritePlace($userId, $selectedPlace);
}
setFlash('success', 'Dagens köp är sparat.');
redirect('/index.php?tab=hem');
}
}
$budgetMetrics = calculateBudgetMetrics($userId);
$favorites = getFavoritePlaces($userId);
$allRestaurantNames = getMatkortRestaurantNames();
$flash = getFlash();
$favoriteNames = array_map(
static fn (array $favorite): string => (string) ($favorite['name'] ?? ''),
$favorites
);
$normalizeName = static function (string $value): string {
$trimmed = trim($value);
return function_exists('mb_strtolower') ? mb_strtolower($trimmed) : strtolower($trimmed);
};
$favoriteLookup = [];
foreach ($favoriteNames as $favoriteName) {
$favoriteLookup[$normalizeName($favoriteName)] = true;
}
$nonFavoriteRestaurantNames = array_values(array_filter(
$allRestaurantNames,
static fn (string $name): bool => !isset($favoriteLookup[$normalizeName($name)])
));
$periodEnd = (string) $budgetMetrics['period_end'];
$startingBalance = (float) $budgetMetrics['starting_balance'];
$remaining = (float) $budgetMetrics['remaining'];
$todaySpent = (float) $budgetMetrics['today_spent'];
$hasSpendEntryToday = (bool) $budgetMetrics['has_spend_entry_today'];
$daysLeft = (int) $budgetMetrics['days_left'];
$spendPerDayLeft = (float) $budgetMetrics['spend_per_day_left'];
$todayBudgetRemaining = (float) $budgetMetrics['today_budget_remaining'];
$daysLeftLabel = $hasSpendEntryToday ? 'Dagar kvar (exkl idag)' : 'Dagar kvar (inkl idag)';
$todayBudgetHint = 'Visar upp till 90 kr, eller lägre om saldo per dag är mindre, minus dagens spendering.';
$budgetPerDayHint = 'Saldo kvar fördelat på antalet dagar kvar i perioden.';
$daysLeftHint = $hasSpendEntryToday
? 'Antal vardagar kvar från i morgon till och med slutdatum.
Helger och helgdagar exkluderade.'
: 'Antal vardagar kvar från idag till och med slutdatum.
Helger och helgdagar exkluderade.';
?>
<article class="card panel hero-panel">
<div>
<p class="pill" title="<?= e($todayBudgetHint ) ?>" aria-label="<?= e($todayBudgetHint) ?>">Dagens budget</p>
<h2><?= e(formatCurrency($todayBudgetRemaining)) ?></h2>
</div>
<div class="kpi-grid">
<div class="kpi">
<span>Saldo kvar</span>
<strong><?= e(formatCurrency($remaining)) ?></strong>
</div>
<div class="kpi">
<span title="<?= e($budgetPerDayHint) ?>" aria-label="<?= e($budgetPerDayHint) ?>">Kan spendera / dag</span>
<strong><?= e(formatCurrency($spendPerDayLeft)) ?></strong>
</div>
<div class="kpi">
<span>Spenderat idag</span>
<strong><?= e(formatCurrency($todaySpent)) ?></strong>
</div>
<div class="kpi">
<span title="<?= e($daysLeftHint) ?>" aria-label="<?= e($daysLeftHint) ?>"><?= e($daysLeftLabel) ?></span>
<strong><?= e((string) $daysLeft) ?></strong>
</div>
</div>
</article>
<?php if ($flash): ?>
<div class="notice <?= e($flash['type']) ?>"><?= e($flash['message']) ?></div>
<?php endif; ?>
<article class="card panel">
<h3>Registrera köp</h3>
<form method="post" class="stack">
<input type="hidden" name="csrf_token" value="<?= e(csrfToken()) ?>">
<input type="hidden" name="action" value="add_spend">
<label class="field">
<span>Datum</span>
<input type="date" name="spent_on" value="<?= e(date('Y-m-d')) ?>" required>
</label>
<div>
<span class="field-label">Snabbval</span>
<div class="quick-amounts">
<button type="button" class="chip" data-amount="0">0 kr</button>
<button type="button" class="chip" data-amount="50">50 kr</button>
<button type="button" class="chip" data-amount="70">70 kr</button>
<button type="button" class="chip" data-amount="90">90 kr</button>
</div>
</div>
<label class="field">
<span>Exakt belopp (max 90 kr)</span>
<input id="amount-input" type="number" name="amount" min="0" max="90" step="0.01" value="0" required>
</label>
<label class="field">
<span>Välj restaurang/butik (valfritt)</span>
<select name="place_name">
<option value="">Välj...</option>
<?php if ($favoriteNames): ?>
<option value="" disabled>----- Favoriter -----</option>
<?php foreach ($favoriteNames as $favoriteName): ?>
<option value="<?= e($favoriteName) ?>"><?= e($favoriteName) ?></option>
<?php endforeach; ?>
<option value="" disabled>----- Alla restauranger och butiker -----</option>
<?php endif; ?>
<?php foreach ($nonFavoriteRestaurantNames as $restaurantName): ?>
<option value="<?= e($restaurantName) ?>"><?= e($restaurantName) ?></option>
<?php endforeach; ?>
</select>
</label>
<label class="checkbox-row">
<input type="checkbox" name="save_favorite" value="1">
<span>Spara platsen som favorit</span>
</label>
<div class="form-actions">
<button class="btn" type="submit">Spara köp</button>
</div>
</form>
</article>
<article class="card panel">
<h3>Ställ in saldo och slutdatum</h3>
<form method="post" class="form-grid">
<input type="hidden" name="csrf_token" value="<?= e(csrfToken()) ?>">
<input type="hidden" name="action" value="save_budget">
<label class="field">
<span>Startsaldo (kr)</span>
<input type="number" name="starting_balance" min="0" max="10000" step="0.01" required value="<?= e((string) $startingBalance) ?>">
</label>
<label class="field">
<span>Slutdatum</span>
<input type="date" name="period_end" required value="<?= e($periodEnd) ?>">
</label>
<div class="form-actions">
<button class="btn" type="submit">Spara period</button>
</div>
</form>
</article>