feat: add monthly budget field and statistics (#329)

This commit is contained in:
Miguel Ribeiro 2024-05-17 23:14:17 +02:00 committed by GitHub
parent e21500a719
commit b622434ca0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 286 additions and 14 deletions

57
endpoints/user/budget.php Normal file
View File

@ -0,0 +1,57 @@
<?php
require_once '../../includes/connect_endpoint.php';
require_once '../../includes/inputvalidation.php';
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
die(json_encode([
"success" => false,
"message" => translate('session_expired', $i18n)
]));
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$postData = file_get_contents("php://input");
$data = json_decode($postData, true);
if (
!isset($data["budget"]) || $data["budget"] == ""
) {
$response = [
"success" => false,
"message" => translate('fill_mandatory_fields', $i18n)
];
echo json_encode($response);
} else {
$budget = $data["budget"];
$userId = $_SESSION['userId'];
$sql = "UPDATE user SET budget = :budget WHERE id = :userId";
$stmt = $db->prepare($sql);
$stmt->bindValue(':budget', $budget, SQLITE3_TEXT);
$stmt->bindValue(':userId', $userId, SQLITE3_TEXT);
$result = $stmt->execute();
if ($result) {
$response = [
"success" => true,
"message" => translate('user_details_saved', $i18n)
];
echo json_encode($response);
} else {
$response = [
"success" => false,
"message" => translate('error_updating_user_data', $i18n)
];
echo json_encode($response);
}
}
}
?>

View File

@ -12,6 +12,8 @@
if ($userData === false) {
header('Location: logout.php');
exit();
} else {
$_SESSION['userId'] = $userData['id'];
}
if ($userData['avatar'] == "") {
@ -55,6 +57,7 @@
$_SESSION['token'] = $token;
$_SESSION['loggedin'] = true;
$_SESSION['main_currency'] = $main_currency;
$_SESSION['userId'] = $userId;
} else {
$db->close();
header("Location: logout.php");

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Durchschnittliche monatliche Kosten",
'most_expensive' => "Kosten des teuersten Abonnements",
'amount_due' => "Diesen Monat fällige Summe",
'percentage_budget_used' => "Prozentualer Anteil des Budgets genutzt",
'budget_remaining' => "Verbleibendes Budget",
'amount_over_budget' => "Überzogenes Budget",
'monthly_savings' => "Monatliche Ersparnisse (bei inaktiven Abonnements)",
'yearly_savings' => "Jährliche Ersparnisse (bei inaktiven Abonnements)",
'split_views' => "Aufgeteilte Ansichten",
'category_split' => "Kategorien",
'household_split' => "Haushalt",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Avatar hochladen",
'file_type_error' => "Dateityp nicht unterstützt",
'user_details' => "Benutzerdetails",
"household" => "Haushalt",
"monthly_budget" => "Monatliches Budget",
"budget_info" => "Das monatliche Budget wird für die Berechnung der Statistiken verwendet.",
"household" => "Haushalt",
"save_member" => "Mitglied speichern",
"delete_member" => "Mitglied löschen",
"cant_delete_member" => "Hauptmitglied kann nicht gelöscht werden",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Μέσο μηνιαίο κόστος συνδρομής",
'most_expensive' => "Πιο ακριβό κόστος συνδρομής",
'amount_due' => "Ποσό που οφείλεται αυτόν τον μήνα",
'percentage_budget_used' => "Ποσοστό προϋπολογισμού που χρησιμοποιείται",
'budget_remaining' => "Υπόλοιπο προϋπολογισμού",
'amount_over_budget' => "Ποσό πάνω από τον προϋπολογισμό",
'monthly_savings' => "Μηνιαίες εξοικονομήσεις (σε ανενεργές συνδρομές)",
'yearly_savings' => "Ετήσιες εξοικονομήσεις (σε ανενεργές συνδρομές)",
'split_views' => "Διαχωρισμένες προβολές",
'category_split' => "Διαχωρισμός κατηγορίας",
'household_split' => "Διαχωρισμός νοικοκυριού",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "μεταφόρτωση άβαταρ",
'file_type_error' => "Το αρχείο πρέπει να είναι τύπου jpg, jpeg, png, webp ή gif",
'user_details' => "Λεπτομέρειες χρήστη",
"household" => "Νοικοκυριό",
"monthly_budget" => "Μηνιαίος προϋπολογισμός",
"budget_info" => "Ο μηνιαίος προϋπολογισμός χρησιμοποιείται για τον υπολογισμό των στατιστικών",
"household" => "Νοικοκυριό",
"save_member" => "Αποθήκευση μέλους",
"delete_member" => "Διαγραφή μέλους",
"cant_delete_member" => "Δεν ειναι δυνατή η διαγραφή του βασικού μέλους",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Average Monthly Subscription Cost",
'most_expensive' => "Most Expensive Subscription Cost",
'amount_due' => "Amount due this month",
'percentage_budget_used' => "Percentage of budget used",
'budget_remaining' => "Budget Remaining",
'amount_over_budget' => "Amount over budget",
'monthly_savings' => "Monthly Savings (on inactive subscriptions)",
'yearly_savings' => "Yearly Savings (on inactive subscriptions)",
'split_views' => "Split Views",
'category_split' => "Category Split",
'household_split' => "Household Split",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Upload Avatar",
'file_type_error' => "The file type supplied is not supported.",
'user_details' => "User Details",
"household" => "Household",
"monthly_budget" => "Monthly Budget",
"budget_info" => "Monthly budget is used to calculate statistics",
"household" => "Household",
"save_member" => "Save Member",
"delete_member" => "Delete Member",
"cant_delete_member" => "Can't delete main member",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Costo Promedio Mensual de Suscripción",
'most_expensive' => "Costo de Suscripción Más Caro",
'amount_due' => "Monto a pagar este mes",
'percentage_budget_used' => "Porcentaje del presupuesto utilizado",
'budget_remaining' => "Presupuesto Restante",
'amount_over_budget' => "Monto sobre el presupuesto",
'monthly_savings' => "Ahorro Mensual (en suscripciones inactivas)",
'yearly_savings' => "Ahorro Anual (en suscripciones inactivas)",
'split_views' => "Vistas Divididas",
'category_split' => "División por Categoría",
'household_split' => "División por Hogar",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Subir avatar",
'file_type_error' => "El archivo debe ser una imagen en formato PNG, JPG, WEBP o SVG",
'user_details' => "Detalles del Usuario",
"household" => "Hogar",
"monthly_budget" => "Presupuesto Mensual",
"budget_info" => "El presupuesto mensual se utiliza para calcular las estadísticas. Si no deseas utilizar esta función, déjalo en 0.",
"household" => "Hogar",
"save_member" => "Guardar Miembro",
"delete_member" => "Eliminar Miembro",
"cant_delete_member" => "No se puede eliminar el miembro principal",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Coût moyen mensuel de l'abonnement",
'most_expensive' => "Coût d'abonnement le plus élevé",
'amount_due' => "Montant dû ce mois-ci",
'percentage_budget_used' => "Pourcentage du budget utilisé",
'budget_remaining' => "Budget restant",
'amount_over_budget' => "Montant dépassant le budget",
'monthly_savings' => "Économies mensuelles (sur les abonnements inactifs)",
'yearly_savings' => "Économies annuelles (sur les abonnements inactifs)",
'split_views' => "Vues partagées",
'category_split' => "Répartition par catégorie",
'household_split' => "Répartition du ménage",
@ -101,6 +105,8 @@ $i18n = [
'upload_avatar' => "Télécharger un Avatar",
'file_type_error' => "Le type de fichier n'est pas pris en charge",
'user_details' => "Détails de l'utilisateur",
"monthly_budget" => "Budget mensuel",
"budget_info" => "Le budget mensuel est utilisé pour calculer les statistiques. Laissez vide pour désactiver.",
"household" => "Ménage",
"save_member" => "Enregistrer le membre",
"delete_member" => "Supprimer le membre",

View File

@ -88,7 +88,11 @@ $i18n = [
'average_monthly' => "Costo medio mensile dell'abbonamento",
'most_expensive' => "Costo dell'abbonamento più elevato",
'amount_due' => 'Importo dovuto questo mese',
'percentage_budget_used' => 'Percentuale del budget utilizzata',
'budget_remaining' => 'Budget rimanente',
'amount_over_budget' => 'Importo oltre il budget',
'monthly_savings' => 'Risparmi mensili (su abbonamenti inattivi)',
'yearly_savings' => 'Risparmi annuali (su abbonamenti inattivi)',
'split_views' => 'Visualizzazioni con grafici',
'category_split' => 'Suddivisione per categoria',
'household_split' => 'Suddivisione per nucleo familiare',
@ -106,6 +110,8 @@ $i18n = [
'upload_avatar' => 'Carica avatar',
'file_type_error' => 'Il tipo di file fornito non è supportato.',
'user_details' => 'Dettagli utente',
"monthly_budget" => "Budget mensile",
"budget_info" => "Il budget mensile viene utilizzato per calcolare le statistiche. Se non si desidera utilizzare questa funzionalità, impostare il budget su 0.",
'household' => 'Nucleo familiare',
'save_member' => 'Salva membro',
'delete_member' => 'Elimina membro',

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "月額平均費用",
'most_expensive' => "最も高額な定期購入費用",
'amount_due' => "今月の支払額",
'percentage_budget_used' => "予算使用率",
'budget_remaining' => "予算残高",
'amount_over_budget' => "予算オーバー",
'monthly_savings' => "月間節約 (非アクティブな定期購入)",
'yearly_savings' => "年間節約 (非アクティブな定期購入)",
'split_views' => "分割表示",
'category_split' => "カテゴリ別",
'household_split' => "世帯別",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "アバターをアップロードする",
'file_type_error' => "ファイルタイプが許可されていません",
'user_details' => "ユーザー詳細",
"household" => "世帯",
"monthly_budget" => "月間予算",
"budget_info" => "予算を設定すると、統計ページで予算と実際の支出を比較できます。",
"household" => "世帯",
"save_member" => "世帯員を保存",
"delete_member" => "世帯員を削除",
"cant_delete_member" => "世帯主は削除出ません",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "월별 평균 구독 비용",
'most_expensive' => "최고가 구독 비용",
'amount_due' => "이달의 결제 비용",
'percentage_budget_used' => "예산 사용률",
'budget_remaining' => "남은 예산",
'amount_over_budget' => "예산 초과",
'monthly_savings' => "월간 절약 (비활성 구독)",
'yearly_savings' => "연간 절약 (비활성 구독)",
'split_views' => "분할 표시",
'category_split' => "카테고리별",
'household_split' => "가구별",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "아바타 업로드",
'file_type_error' => "제공된 파일이 지원하지 않는 타입입니다.",
'user_details' => "유저 상세",
"household" => "가구",
"monthly_budget" => "월간 예산",
"budget_info" => "예산을 설정하면 통계 페이지에서 예산과 실제 지출을 비교할 수 있습니다.",
"household" => "가구",
"save_member" => "구성원 저장",
"delete_member" => "구성원 삭제",
"cant_delete_member" => "메인 구성원은 삭제할 수 없습니다",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Średni miesięczny koszt subskrypcji",
'most_expensive' => "Najdroższy koszt subskrypcji",
'amount_due' => "Kwota należna w tym miesiącu",
'percentage_budget_used' => "Procent wykorzystania budżetu",
'budget_remaining' => "Pozostały budżet",
'amount_over_budget' => "Kwota przekraczająca budżet",
'monthly_savings' => "Miesięczne oszczędności (w przypadku nieaktywnych subskrypcji)",
'yearly_savings' => "Roczne oszczędności (w przypadku nieaktywnych subskrypcji)",
'split_views' => "Podziel widoki",
'category_split' => "Podział kategorii",
'household_split' => "Podział gospodarstwa domowego",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Prześlij awatar",
'file_type_error' => "Podany typ pliku nie jest obsługiwany.",
'user_details' => "Szczegóły użytkownika",
"household" => "Gospodarstwo domowe",
"monthly_budget" => "Miesięczny budżet",
"budget_info" => "Jeśli ustawisz budżet, zobaczysz pasek postępu na stronie głównej.",
"household" => "Gospodarstwo domowe",
"save_member" => "Zapisz użytkownika",
"delete_member" => "Usuń użytkownika",
"cant_delete_member" => "Nie można usunąć głównego użytkownika",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Custo Mensal Médio das Subscrições",
'most_expensive' => "Custo da Subscrição Mais Cara",
'amount_due' => "Quantia em dívida este mês",
'percentage_budget_used' => "Percentagem do orçamento usada",
'budget_remaining' => "Orçamento Restante",
'amount_over_budget' => "Quantia acima do orçamento",
'monthly_savings' => "Poupança Mensal (em subscrições inactivas)",
'yearly_savings' => "Poupança Anual (em subscrições inactivas)",
'split_views' => "Vistas Divididas",
'category_split' => "Por Categoria",
'household_split' => "Por Membro",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Enviar avatar",
'file_type_error' => "Tipo de ficheiro não permitido",
'user_details' => "Detalhes do utilizador",
"household" => "Agregado",
"monthly_budget" => "Orçamento Mensal",
"budget_info" => "Ao definir um orçamento pode comparar com os gastos reais na página de estatísticas.",
"household" => "Agregado",
"save_member" => "Guardar Membro",
"delete_member" => "Apagar Membro",
"cant_delete_member" => "Não pode apagar o membro principal",

View File

@ -83,7 +83,11 @@ $i18n = [
'average_monthly' => "Custom médio mensal",
'most_expensive' => "Assinatura mais cara",
'amount_due' => "Valor devido nesse mês",
'percentage_budget_used' => "Porcentagem do orçamento utilizado",
'budget_remaining' => "Orçamento restante",
'amount_over_budget' => "Valor acima do orçamento",
'monthly_savings' => "Economia mensal (em assinaturas inativas)",
'yearly_savings' => "Economia anual (em assinaturas inativas)",
'split_views' => "Visualizações",
'category_split' => "Por categoria",
'household_split' => "Por membro",
@ -99,7 +103,9 @@ $i18n = [
'upload_avatar' => "Carregar avatar",
'file_type_error' => "Tipo de arquivo não permitido",
'user_details' => "Informações do Usuário",
"household" => "Membros",
"monthly_budget" => "Orçamento mensal",
"budget_info" => "O orçamento mensal é usado para calcular estatísticas",
"household" => "Membros",
"save_member" => "Salvar membro",
"delete_member" => "Excluir membro",
"cant_delete_member" => "Não é possível excluir o membro principal",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Средняя ежемесячная стоимость подписки",
'most_expensive' => "Самая дорогая стоимость подписки",
'amount_due' => "Сумма к оплате в этом месяце",
'percentage_budget_used' => "Процент использования бюджета",
'budget_remaining' => "Оставшийся бюджет",
'amount_over_budget' => "Сумма превышения бюджета",
'monthly_savings' => "Ежемесячная экономия (при неактивных подписках)",
'yearly_savings' => "Годовая экономия (при неактивных подписках)",
'split_views' => "Подробная статистика",
'category_split' => "По категориям",
'household_split' => "По членам семьи",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Загрузить аватар",
'file_type_error' => "Указанный тип файла не поддерживается.",
'user_details' => "Данные пользователя",
"household" => "Семья",
"monthly_budget" => "Ежемесячный бюджет",
"budget_info" => "Если вы укажете бюджет, Wallos будет отображать вашу текущую стоимость подписок в сравнении с вашим бюджетом.",
"household" => "Семья",
"save_member" => "Сохранить члена семьи",
"delete_member" => "Удалить члена семьи",
"cant_delete_member" => "Не могу удалить основного члена семьи",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Просечни месечни трошак претплате",
'most_expensive' => "Најскупља претплата",
'amount_due' => "Износ за уплату овог месеца",
'percentage_budget_used' => "Проценат искоришћеног буџета",
'budget_remaining' => "Преостали буџет",
'amount_over_budget' => "Износ преко буџета",
'monthly_savings' => "Месечне уштеде (на неактивним претплатама)",
'yearly_savings' => "Годишње уштеде (на неактивним претплатама)",
'split_views' => "Подељени прикази",
'category_split' => "Подела по категоријама",
'household_split' => "Подела по домаћинству",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Постави аватар",
'file_type_error' => "Датотека није у подржаном формату.",
'user_details' => "Кориснички детаљи",
"household" => "Домаћинство",
"monthly_budget" => "Месечни буџет",
"budget_info" => "Унесите месечни буџет да бисте видели препоручену максималну цену претплате на почетној страници.",
"household" => "Домаћинство",
"save_member" => "Сачувај члана",
"delete_member" => "Обриши члана",
"cant_delete_member" => "Главни члан не може бити обрисан",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Prosečni mesečni trošak pretplate",
'most_expensive' => "Najskuplja pretplata",
'amount_due' => "Iznos za plaćanje ovog meseca",
'percentage_budget_used' => "Procenat budžeta iskorišćen",
'budget_remaining' => "Preostali budžet",
'amount_over_budget' => "Iznos preko budžeta",
'monthly_savings' => "Mesečne uštede (na neaktivnim pretplatama)",
'yearly_savings' => "Godišnje uštede (na neaktivnim pretplatama)",
'split_views' => "Podeljene statistike",
'category_split' => "Podela po kategorijama",
'household_split' => "Podela po domaćinstvima",
@ -101,7 +105,9 @@ $i18n = [
'upload_avatar' => "Učitaj avatar",
'file_type_error' => "Tip datoteke koji ste priložili nije podržan.",
'user_details' => "Detalji korisnika",
"household" => "Domaćinstvo",
"monthly_budget" => "Mesečni budžet",
"budget_info" => "Ovo je vaš mesečni budžet za sve pretplate. Ovo je samo informativno i ne ograničava vas.",
"household" => "Domaćinstvo",
"save_member" => "Sačuvaj člana",
"delete_member" => "Izbriši člana",
"cant_delete_member" => "Nemoguće brisanje glavnog člana",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "Ortalama Aylık Abonelik Maliyeti",
'most_expensive' => "En Pahalı Abonelik Maliyeti",
'amount_due' => "Bu ay ödenecek miktar",
'percentage_budget_used' => "Bütçe Kullanımı",
'budget_remaining' => "Kalan Bütçe",
'amount_over_budget' => "Bütçe Aşımı",
'monthly_savings' => "Aylık Tasarruf (aktif olmayan aboneliklerde)",
'yearly_savings' => "Yıllık Tasarruf (aktif olmayan aboneliklerde)",
'split_views' => "Bölünmüş Görünümler",
'category_split' => "Kategori Bölümü",
'household_split' => "Hane Bölümü",
@ -101,6 +105,8 @@ $i18n = [
'upload_avatar' => "Avatarı yükle",
'file_type_error' => "Dosya türü izin verilmiyor",
'user_details' => "Kullanıcı Detayları",
"monthly_budget" => "Aylık Bütçe",
"budget_info" => "Bir bütçe belirlemek, istatistik sayfasında bütçe ve gerçek harcamaları karşılaştırmanıza olanak tanır.",
"household" => "Hane",
"save_member" => "Üyeyi Kaydet",
"delete_member" => "Üyeyi Sil",

View File

@ -90,7 +90,11 @@ $i18n = [
'average_monthly' => "平均每月订阅费用",
'most_expensive' => "最昂贵订阅费用",
'amount_due' => "本月应付金额",
'percentage_budget_used' => "预算使用百分比",
'budget_remaining' => "剩余预算",
'amount_over_budget' => "超出预算",
'monthly_savings' => "每月节省",
'yearly_savings' => "每年节省",
'split_views' => "拆分视图",
'category_split' => "分类视图",
'household_split' => "家庭视图",
@ -108,6 +112,8 @@ $i18n = [
'upload_avatar' => "上传头像",
'file_type_error' => "文件类型不允许",
'user_details' => "用户详情",
"monthly_budget" => "每月预算",
"budget_info" => "设置预算后,您可以在统计页面上比较预算和实际支出。",
"household" => "家庭",
"save_member" => "保存成员",
"delete_member" => "删除成员",

View File

@ -85,7 +85,11 @@ $i18n = [
'average_monthly' => "平均每月訂閱費用",
'most_expensive' => "最高的訂閱費用",
'amount_due' => "本月應付金額",
'percentage_budget_used' => "預算使用率",
'budget_remaining' => "剩餘預算",
'amount_over_budget' => "預算超支",
'monthly_savings' => "每月節省",
'yearly_savings' => "每年節省",
'split_views' => "分割檢視",
'category_split' => "類別分割",
'household_split' => "家庭分割",
@ -101,6 +105,8 @@ $i18n = [
'upload_avatar' => "上传头像",
'file_type_error' => "文件类型不允许",
'user_details' => "使用者詳細資訊",
"monthly_budget" => "每月預算",
"budget_info" => "設定預算後,您可以在統計頁面上比較預算和實際支出。",
"household" => "家庭",
"save_member" => "儲存成員",
"delete_member" => "刪除成員",

View File

@ -51,6 +51,7 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = true;
$_SESSION['main_currency'] = $main_currency;
$_SESSION['userId'] = $userId;
$cookieExpire = time() + (30 * 24 * 60 * 60);
setcookie('language', $language, $cookieExpire);
if ($rememberMe) {

15
migrations/000018.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/*
This migration adds a column to the users table to store a monthly budget that will be used to calculate statistics
*/
/** @noinspection PhpUndefinedVariableInspection */
$columnQuery = $db->query("SELECT * FROM pragma_table_info('users') where name='budget'");
$columnRequired = $columnQuery->fetchArray(SQLITE3_ASSOC) === false;
if ($columnRequired) {
$db->exec('ALTER TABLE user ADD COLUMN budget INTEGER DEFAULT 0');
}
?>

View File

@ -69,6 +69,35 @@ function deleteAvatar(path) {
});
}
function saveBudget() {
const button = document.getElementById("saveBudget");
button.disabled = true;
const budget = document.getElementById("budget").value;
fetch('endpoints/user/budget.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ budget: budget })
})
.then(response => response.json())
.then(data => {
if (data.success) {
showSuccessMessage(data.message);
} else {
showErrorMessage(data.message);
}
button.disabled = false;
})
.catch(error => {
showErrorMessage(translate('unknown_error'));
button.disabled = false;
});
}
function addMemberButton(memberId) {
document.getElementById("addMember").disabled = true;
const url = 'endpoints/household/household.php?action=add';

View File

@ -74,13 +74,18 @@
$currencyId = $row['id'];
$currencies[$currencyId] = $row;
}
$userData['currency_symbol'] = "";
?>
<div class="form-group">
<label for="currency"><?= translate('main_currency', $i18n) ?>:</label>
<select id="currency" name="main_currency" placeholder="Currency">
<?php
foreach ($currencies as $currency) {
$selected = ($currency['id'] == $userData['main_currency']) ? 'selected' : '';
$selected = "";
if ($currency['id'] == $userData['main_currency']) {
$selected = "selected";
$userData['currency_symbol'] = $currency['symbol'];
}
?>
<option value="<?= $currency['id'] ?>" <?= $selected ?>><?= $currency['name'] ?></option>
<?php
@ -111,6 +116,24 @@
</section>
<section class="account-section">
<header>
<h2><?= translate('monthly_budget', $i18n) ?></h2>
</header>
<div class="account-budget">
<div class="form-group-inline">
<label for="budget"><?= $userData['currency_symbol'] ?></label>
<input type="number" id="budget" name="budget" value="<?= $userData['budget'] ?>" placeholder="Budget">
<input type="submit" value="<?= translate('save', $i18n) ?>" id="saveBudget" onClick="saveBudget()"/>
</div>
<div class="settings-notes">
<p>
<i class="fa-solid fa-circle-info"></i> <?= translate('budget_info', $i18n) ?></p>
<p>
</div>
</div>
</section>
<?php
$sql = "SELECT * FROM household";
$result = $db->query($sql);

View File

@ -199,6 +199,17 @@ if ($result) {
}
}
if (isset($userData['budget']) && $userData['budget'] > 0) {
$budget = $userData['budget'];
$budgetLeft = $budget - $totalCostPerMonth;
$budgetLeft = $budgetLeft < 0 ? 0 : $budgetLeft;
$budgetUsed = ($totalCostPerMonth / $budget) * 100;
$budgetUsed = $budgetUsed > 100 ? 100 : $budgetUsed;
if ($totalCostPerMonth > $budget) {
$overBudgetAmount = $totalCostPerMonth - $budget;
}
}
$numberOfElements = 6;
?>
<section class="contain">
@ -333,8 +344,35 @@ $numberOfElements = 6;
<div class="title"><?= translate('amount_due', $i18n) ?></div>
</div>
<?php
if (isset($budgetUsed)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= number_format($budgetUsed, 2) ?>%</span>
<div class="title"><?= translate('percentage_budget_used', $i18n) ?></div>
</div>
<?php
}
if (isset($budgetLeft)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= CurrencyFormatter::format($budgetLeft, $code) ?></span>
<div class="title"><?= translate('budget_remaining', $i18n) ?></div>
</div>
<?php
}
if (isset($overBudgetAmount)) {
$numberOfElements += 1;
?>
<div class="statistic">
<span><?= CurrencyFormatter::format($overBudgetAmount, $code) ?></span>
<div class="title"><?= translate('amount_over_budget', $i18n) ?></div>
</div>
<?php
}
if ($inactiveSubscriptions > 0) {
$numberOfElements = 8;
$numberOfElements += 3;
?>
<div class="statistic">
<span><?= $inactiveSubscriptions ?></span>
@ -344,6 +382,10 @@ $numberOfElements = 6;
<span><?= CurrencyFormatter::format($totalSavingsPerMonth, $code) ?></span>
<div class="title"><?= translate('monthly_savings', $i18n) ?></div>
</div>
<div class="statistic">
<span><?= CurrencyFormatter::format($totalSavingsPerMonth * 12, $code) ?></span>
<div class="title"><?= translate('yearly_savings', $i18n) ?></div>
</div>
<?php
}