Files
Wallos/index.php
Miguel Ribeiro 27ac805141 feat: make container shutdown instant & graceful
feat: make container shutdown instant & graceful  (#916)
feat: add pushplus notification service  (#911)
feat: option to delete ai recommendations
fix: parsing ai recommendations from gemini (#909)
2025-09-14 16:46:42 +02:00

367 lines
18 KiB
PHP

<?php
require_once 'includes/header.php';
require_once 'includes/getdbkeys.php';
function formatPrice($price, $currencyCode, $currencies)
{
$formattedPrice = CurrencyFormatter::format($price, $currencyCode);
if (strstr($formattedPrice, $currencyCode)) {
$symbol = $currencyCode;
foreach ($currencies as $currency) {
if ($currency['code'] === $currencyCode) {
if ($currency['symbol'] != "") {
$symbol = $currency['symbol'];
}
break;
}
}
$formattedPrice = str_replace($currencyCode, $symbol, $formattedPrice);
}
return $formattedPrice;
}
function formatDate($date, $lang = 'en')
{
$currentYear = date('Y');
$dateYear = date('Y', strtotime($date));
// Determine the date format based on whether the year matches the current year
$dateFormat = ($currentYear == $dateYear) ? 'MMM d' : 'MMM yyyy';
// Validate the locale and fallback to 'en' if unsupported
if (!in_array($lang, ResourceBundle::getLocales(''))) {
$lang = 'en'; // Fallback to English
}
// Create an IntlDateFormatter instance for the specified language
$formatter = new IntlDateFormatter(
$lang,
IntlDateFormatter::SHORT,
IntlDateFormatter::NONE,
null,
null,
$dateFormat
);
// Format the date
$formattedDate = $formatter->format(new DateTime($date));
return $formattedDate;
}
// Get the first name of the user
$stmt = $db->prepare("SELECT username, firstname FROM user WHERE id = :userId");
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$user = $result->fetchArray(SQLITE3_ASSOC);
$first_name = $user['firstname'] ?? $user['username'] ?? '';
// Fetch the next 3 enabled subscriptions up for payment
$stmt = $db->prepare("SELECT id, logo, name, price, currency_id, next_payment, inactive FROM subscriptions WHERE user_id = :userId AND next_payment >= date('now') AND inactive = 0 ORDER BY next_payment ASC LIMIT 3");
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$upcomingSubscriptions = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$upcomingSubscriptions[] = $row;
}
// Fetch enabled subscriptions with manual renewal that are overdue
$stmt = $db->prepare("SELECT id, logo, name, price, currency_id, next_payment, inactive, auto_renew FROM subscriptions WHERE user_id = :userId AND next_payment < date('now') AND auto_renew = 0 AND inactive = 0 ORDER BY next_payment ASC");
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$overdueSubscriptions = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$overdueSubscriptions[] = $row;
}
$hasOverdueSubscriptions = !empty($overdueSubscriptions);
require_once 'includes/stats_calculations.php';
// Get AI Recommendations for user
$stmt = $db->prepare("SELECT * FROM ai_recommendations WHERE user_id = :userId");
$stmt->bindValue(':userId', $userId, SQLITE3_INTEGER);
$result = $stmt->execute();
$aiRecommendations = [];
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$aiRecommendations[] = $row;
}
?>
<section class="contain dashboard">
<h1><?= translate('hello', $i18n) ?> <?= htmlspecialchars($first_name) ?></h1>
<?php
// If there are overdue subscriptions, display them
if ($hasOverdueSubscriptions) {
?>
<div class="overdue-subscriptions">
<h2><?= translate('overdue_renewals', $i18n) ?></h2>
<div class="dashboard-subscriptions-container">
<div class="dashboard-subscriptions-list">
<?php
foreach ($overdueSubscriptions as $subscription) {
$subscriptionLogo = "images/uploads/logos/" . $subscription['logo'];
$subscriptionName = htmlspecialchars($subscription['name']);
$subscriptionPrice = $subscription['price'];
$subscriptionCurrency = $subscription['currency_id'];
$subscriptionNextPayment = $subscription['next_payment'];
$subscriptionDisplayNextPayment = date('F j', strtotime($subscriptionNextPayment));
$subscriptionDisplayPrice = formatPrice($subscriptionPrice, $currencies[$subscriptionCurrency]['code'], $currencies);
?>
<div class="subscription-item">
<?php
if (empty($subscription['logo'])) {
?>
<p class="subscription-item-title"><?= $subscriptionName ?></p>
<?php
} else {
?>
<img src="<?= $subscriptionLogo ?>" alt="<?= $subscriptionName ?> logo"
class="subscription-item-logo" title="<?= $subscriptionName ?>">
<?php
}
?>
<div class="subscription-item-info">
<p class="subscription-item-date"> <?= formatDate($subscriptionDisplayNextPayment, $lang) ?>
</p>
<p class="subscription-item-price"> <?= $subscriptionDisplayPrice ?></p>
</div>
</div>
<?php
}
?>
</div>
</div>
</div>
<?php
}
?>
<div class="upcoming-subscriptions">
<h2><?= translate('upcoming_payments', $i18n) ?></h2>
<div class="dashboard-subscriptions-container">
<div class="dashboard-subscriptions-list">
<?php
if (empty($upcomingSubscriptions)) {
?>
<p><?= translate('no_upcoming_payments', $i18n) ?></p>
<?php
} else {
foreach ($upcomingSubscriptions as $subscription) {
$subscriptionLogo = "images/uploads/logos/" . $subscription['logo'];
$subscriptionName = htmlspecialchars($subscription['name']);
$subscriptionPrice = $subscription['price'];
$subscriptionCurrency = $subscription['currency_id'];
$subscriptionNextPayment = $subscription['next_payment'];
$subscriptionDisplayNextPayment = date('F j', strtotime($subscriptionNextPayment));
$subscriptionDisplayPrice = formatPrice($subscriptionPrice, $currencies[$subscriptionCurrency]['code'], $currencies);
?>
<div class="subscription-item">
<?php
if (empty($subscription['logo'])) {
?>
<p class="subscription-item-title"><?= $subscriptionName ?></p>
<?php
} else {
?>
<img src="<?= $subscriptionLogo ?>" alt="<?= $subscriptionName ?> logo"
class="subscription-item-logo" title="<?= $subscriptionName ?>">
<?php
}
?>
<div class="subscription-item-info">
<p class="subscription-item-date"> <?= formatDate($subscriptionDisplayNextPayment, $lang) ?></p>
<p class="subscription-item-price"> <?= $subscriptionDisplayPrice ?></p>
</div>
</div>
<?php
}
}
?>
</div>
</div>
<?php if (!empty($aiRecommendations)) { ?>
<div class="ai-recommendations">
<h2><?= translate('ai_recommendations', $i18n) ?></h2>
<div class="ai-recommendations-container">
<ul class="ai-recommendations-list">
<?php
foreach ($aiRecommendations as $key => $recommendation) { ?>
<li class="ai-recommendation-item" data-id="<?= $recommendation['id'] ?>">
<div class="ai-recommendation-header">
<h3>
<span><?= ($key + 1) . ". " ?></span>
<?= htmlspecialchars($recommendation['title']) ?>
</h3>
<span class="item-arrow-down fa fa-caret-down"></span>
</div>
<p class="collapsible"><?= htmlspecialchars($recommendation['description']) ?></p>
<p class="ai-recommendation-savings">
<?= htmlspecialchars($recommendation['savings']) ?>
<span>
<a href="#" class="delete-ai-recommendation" title="<?= translate('delete', $i18n) ?>">
<i class="fa fa-trash"></i>
</a>
</span>
</p>
</li>
<?php } ?>
</ul>
</div>
</div>
<?php } ?>
<?php if (isset($amountDueThisMonth) || isset($budget) || isset($budgetUsed) || isset($budgetLeft) || isset($overBudgetAmount)) { ?>
<div class="budget-subscriptions">
<h2><?= translate('your_budget', $i18n) ?></h2>
<div class="dashboard-subscriptions-container">
<div class="dashboard-subscriptions-list">
<?php if (isset($amountDueThisMonth)) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate("amount_due", $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= CurrencyFormatter::format($amountDueThisMonth, $currencies[$userData['main_currency']]['code']) ?>
</p>
</div>
</div>
<?php } ?>
<?php if (isset($budget) && $budget > 0) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate("budget", $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= formatPrice($budget, $currencies[$userData['main_currency']]['code'], $currencies) ?>
</p>
</div>
</div>
<?php } ?>
<?php if (isset($budgetUsed)) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate("budget_used", $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= number_format($budgetUsed, 2) ?>%
</p>
</div>
</div>
<?php } ?>
<?php if (isset($budgetLeft)) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate("budget_remaining", $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= formatPrice($budgetLeft, $currencies[$userData['main_currency']]['code'], $currencies) ?>
</p>
</div>
</div>
<?php } ?>
<?php if (isset($overBudgetAmount) && $overBudgetAmount > 0) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate("over_budget", $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= formatPrice($overBudgetAmount, $currencies[$userData['main_currency']]['code'], $currencies) ?>
</p>
</div>
</div>
<?php } ?>
</div>
</div>
</div>
<?php } ?>
</div>
<?php if (isset($activeSubscriptions) && $activeSubscriptions > 0) { ?>
<div class="current-subscriptions">
<h2><?= translate('your_subscriptions', $i18n) ?></h2>
<div class="dashboard-subscriptions-container">
<div class="dashboard-subscriptions-list">
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate('active_subscriptions', $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value"><?= $activeSubscriptions ?></p>
</div>
</div>
<?php if (isset($totalCostPerMonth)) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate('monthly_cost', $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= CurrencyFormatter::format($totalCostPerMonth, $currencies[$userData['main_currency']]['code']) ?>
</p>
</div>
</div>
<?php } ?>
<?php if (isset($totalCostPerYear)) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate('yearly_cost', $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= CurrencyFormatter::format($totalCostPerYear, $currencies[$userData['main_currency']]['code']) ?>
</p>
</div>
</div>
<?php } ?>
</div>
</div>
</div>
<?php } ?>
<?php if (isset($inactiveSubscriptions) && $inactiveSubscriptions > 0) { ?>
<div class="savings-subscriptions">
<h2><?= translate('your_savings', $i18n) ?></h2>
<div class="dashboard-subscriptions-container">
<div class="dashboard-subscriptions-list">
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate('inactive_subscriptions', $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value"><?= $inactiveSubscriptions ?></p>
</div>
</div>
<?php if (isset($totalSavingsPerMonth) && $totalSavingsPerMonth > 0) { ?>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate('monthly_savings', $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= CurrencyFormatter::format($totalSavingsPerMonth, $currencies[$userData['main_currency']]['code']) ?>
</p>
</div>
</div>
<div class="subscription-item thin">
<p class="subscription-item-title"><?= translate('yearly_savings', $i18n) ?></p>
<div class="subscription-item-info">
<p class="subscription-item-value">
<?= CurrencyFormatter::format($totalSavingsPerMonth * 12, $currencies[$userData['main_currency']]['code']) ?>
</p>
</div>
</div>
<?php } ?>
</div>
</div>
</div>
<?php } ?>
</section>
<script src="scripts/dashboard.js?<?= $version ?>"></script>
<?php
require_once 'includes/footer.php';
?>