feat: allow sorting of categories in settings
feat: add filters to statistics page feat: allow renaming / translation of payment methods feat: allow deletion of the default payment methods
This commit is contained in:
parent
d7e050b868
commit
83234ab8cd
34
endpoints/categories/sort.php
Normal file
34
endpoints/categories/sort.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once '../../includes/connect_endpoint.php';
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
|
||||||
|
$categories = $_POST['categoryIds'];
|
||||||
|
$order = 2;
|
||||||
|
|
||||||
|
foreach ($categories as $categoryId) {
|
||||||
|
$sql = "UPDATE categories SET `order` = :order WHERE id = :categoryId";
|
||||||
|
$stmt = $db->prepare($sql);
|
||||||
|
$stmt->bindParam(':order', $order, SQLITE3_INTEGER);
|
||||||
|
$stmt->bindParam(':categoryId', $categoryId, SQLITE3_INTEGER);
|
||||||
|
$result = $stmt->execute();
|
||||||
|
$order++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
"success" => true,
|
||||||
|
"message" => translate("sort_order_saved", $i18n)
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
} else {
|
||||||
|
$response = [
|
||||||
|
"success" => false,
|
||||||
|
"errorMessage" => translate("session_expired", $i18n)
|
||||||
|
];
|
||||||
|
echo json_encode($response);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
@ -39,7 +39,7 @@ if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
|
|||||||
<?= $payment['name'] ?>
|
<?= $payment['name'] ?>
|
||||||
</span>
|
</span>
|
||||||
<?php
|
<?php
|
||||||
if ($payment['id'] > 31 && !$inUse) {
|
if (!$inUse) {
|
||||||
?>
|
?>
|
||||||
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>" onclick="deletePaymentMethod(<?= $payment['id'] ?>)">
|
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>" onclick="deletePaymentMethod(<?= $payment['id'] ?>)">
|
||||||
x
|
x
|
||||||
|
|||||||
41
endpoints/payments/rename.php
Normal file
41
endpoints/payments/rename.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once '../../includes/connect_endpoint.php';
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
|
||||||
|
die(json_encode([
|
||||||
|
"success" => false,
|
||||||
|
"message" => translate('session_expired', $i18n)
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['paymentId']) || !isset($_POST['name']) || $_POST['paymentId'] === '' || $_POST['name'] === '') {
|
||||||
|
die(json_encode([
|
||||||
|
"success" => false,
|
||||||
|
"message" => translate('fields_missing', $i18n)
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$paymentId = $_POST['paymentId'];
|
||||||
|
$name = $_POST['name'];
|
||||||
|
|
||||||
|
$sql = "UPDATE payment_methods SET name = :name WHERE id = :paymentId";
|
||||||
|
$stmt = $db->prepare($sql);
|
||||||
|
$stmt->bindParam(':name', $name, SQLITE3_TEXT);
|
||||||
|
$stmt->bindParam(':paymentId', $paymentId, SQLITE3_INTEGER);
|
||||||
|
$result = $stmt->execute();
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
echo json_encode([
|
||||||
|
"success" => true,
|
||||||
|
"message" => translate('payment_renamed', $i18n)
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
echo json_encode([
|
||||||
|
"success" => false,
|
||||||
|
"message" => translate('payment_not_renamed', $i18n)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
BIN
images/siteicons/draggable.png
Normal file
BIN
images/siteicons/draggable.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 987 B |
@ -26,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$categories = array();
|
$categories = array();
|
||||||
$query = "SELECT * FROM categories";
|
$query = "SELECT * FROM categories ORDER BY `order` ASC";
|
||||||
$result = $db->query($query);
|
$result = $db->query($query);
|
||||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
$categoryId = $row['id'];
|
$categoryId = $row['id'];
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Experimentelle Einstellungen funktionieren möglicherweise nicht perfekt.",
|
"experimental_info" => "Experimentelle Einstellungen funktionieren möglicherweise nicht perfekt.",
|
||||||
"payment_methods" => "Zahlungsmethoden",
|
"payment_methods" => "Zahlungsmethoden",
|
||||||
"payment_methods_info" => "Zahlungsmethode zum (de-)aktivieren anklicken.",
|
"payment_methods_info" => "Zahlungsmethode zum (de-)aktivieren anklicken.",
|
||||||
|
"rename_payment_methods_info" => "Klicken Sie auf den Namen einer Zahlungsmethode, um sie umzubenennen",
|
||||||
"cant_delete_payment_method_in_use" => "Genutzte Zahlungsmethoden können nicht deaktiviert werden",
|
"cant_delete_payment_method_in_use" => "Genutzte Zahlungsmethoden können nicht deaktiviert werden",
|
||||||
"add_custom_payment" => "Eigene Zahlungsmethode hinzufügen",
|
"add_custom_payment" => "Eigene Zahlungsmethode hinzufügen",
|
||||||
"payment_method_name" => "Name der Zahlungsmethode",
|
"payment_method_name" => "Name der Zahlungsmethode",
|
||||||
"payment_method_added_successfuly" => "Zahlungsmethode erfolgreich hinzugefügt",
|
"payment_method_added_successfuly" => "Zahlungsmethode erfolgreich hinzugefügt",
|
||||||
"disable" => "Deaktivieren",
|
"disable" => "Deaktivieren",
|
||||||
"enable" => "Aktivieren",
|
"enable" => "Aktivieren",
|
||||||
|
"rename_payment_method" => "Zahlungsmethode umbenennen",
|
||||||
|
"payment_renamed" => "Zahlungsmethode umbenannt",
|
||||||
|
"payment_not_renamed" => "Zahlungsmethode konnte nicht umbenannt werden",
|
||||||
"test" => "Test",
|
"test" => "Test",
|
||||||
"add" => "Hinzufügen",
|
"add" => "Hinzufügen",
|
||||||
"save" => "Speichern",
|
"save" => "Speichern",
|
||||||
"export_subscriptions" => "Abonnements exportieren",
|
"export_subscriptions" => "Abonnements exportieren",
|
||||||
"export_to_json" => "Nach JSON exportieren",
|
"export_to_json" => "Nach JSON exportieren",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "Filter",
|
||||||
|
"clear" => "Leeren",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Erfolgreich",
|
"success" => "Erfolgreich",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Kategorie konnte nicht gelöscht werden",
|
"failed_remove_category" => "Kategorie konnte nicht gelöscht werden",
|
||||||
"category_saved" => "Kategorie gespeichert",
|
"category_saved" => "Kategorie gespeichert",
|
||||||
"category_removed" => "Kategorie gelöscht",
|
"category_removed" => "Kategorie gelöscht",
|
||||||
|
"sort_order_saved" => "Sortierung gespeichert",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "wurde gespeichert.",
|
"currency_saved" => "wurde gespeichert.",
|
||||||
"error_adding_currency" => "Fehler beim hinzufügen der Währung.",
|
"error_adding_currency" => "Fehler beim hinzufügen der Währung.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Οι πειραματικές ρυθμίσεις πιθανότατα δεν θα λειτουργούν τέλεια.",
|
"experimental_info" => "Οι πειραματικές ρυθμίσεις πιθανότατα δεν θα λειτουργούν τέλεια.",
|
||||||
"payment_methods" => "Τρόποι πληρωμής",
|
"payment_methods" => "Τρόποι πληρωμής",
|
||||||
"payment_methods_info" => "Κάνε κλικ σε μια μέθοδο πληρωμής για να την απενεργοποιήσεις/ενεργοποιήσεις.",
|
"payment_methods_info" => "Κάνε κλικ σε μια μέθοδο πληρωμής για να την απενεργοποιήσεις/ενεργοποιήσεις.",
|
||||||
|
"rename_payment_methods_info" => "Κάντε κλικ στο όνομα μιας μεθόδου πληρωμής για να τη μετονομάσετε.",
|
||||||
"cant_delete_payment_method_in_use" => "Δεν είναι εφικτό να απενεργοποιηθεί η χρησιμοποιούμενη μέθοδο πληρωμής",
|
"cant_delete_payment_method_in_use" => "Δεν είναι εφικτό να απενεργοποιηθεί η χρησιμοποιούμενη μέθοδο πληρωμής",
|
||||||
"add_custom_payment" => "Προσθήκη προσαρμοσμένης μεθόδου πληρωμής",
|
"add_custom_payment" => "Προσθήκη προσαρμοσμένης μεθόδου πληρωμής",
|
||||||
"payment_method_name" => "Όνομα μεθόδου πληρωμής",
|
"payment_method_name" => "Όνομα μεθόδου πληρωμής",
|
||||||
"payment_method_added_successfuly" => "Η μέθοδος πληρωμής προστέθηκε με επιτυχία",
|
"payment_method_added_successfuly" => "Η μέθοδος πληρωμής προστέθηκε με επιτυχία",
|
||||||
"disable" => "Ανενεργό",
|
"disable" => "Ανενεργό",
|
||||||
"enable" => "Ενεργό",
|
"enable" => "Ενεργό",
|
||||||
|
"rename_payment_method" => "Μετονομασία μεθόδου πληρωμής",
|
||||||
|
"payment_renamed" => "Η μέθοδος πληρωμής μετονομάστηκε",
|
||||||
|
"payment_not_renamed" => "Η μέθοδος πληρωμής δεν μετονομάστηκε",
|
||||||
"test" => "Δοκιμή",
|
"test" => "Δοκιμή",
|
||||||
"add" => "Προσθήκη",
|
"add" => "Προσθήκη",
|
||||||
"save" => "Αποθήκευση",
|
"save" => "Αποθήκευση",
|
||||||
"export_subscriptions" => "Εξαγωγή συνδρομών",
|
"export_subscriptions" => "Εξαγωγή συνδρομών",
|
||||||
"export_to_json" => "Εξαγωγή σε JSON",
|
"export_to_json" => "Εξαγωγή σε JSON",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "Φίλτρο",
|
||||||
|
"clear" => "Καθαρισμός",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Επιτυχία",
|
"success" => "Επιτυχία",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Απέτυχε η διαγραφή κατηγορίας",
|
"failed_remove_category" => "Απέτυχε η διαγραφή κατηγορίας",
|
||||||
"category_saved" => "Αποθήκευση κατηγορίας",
|
"category_saved" => "Αποθήκευση κατηγορίας",
|
||||||
"category_removed" => "Διαγραφή κατηγορίας",
|
"category_removed" => "Διαγραφή κατηγορίας",
|
||||||
|
"sort_order_saved" => "Η ταξινόμηση αποθηκεύτηκε",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "αποθηκεύτηκε.",
|
"currency_saved" => "αποθηκεύτηκε.",
|
||||||
"error_adding_currency" => "Error adding currency entry.",
|
"error_adding_currency" => "Error adding currency entry.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Experimental settings will probably not work perfectly.",
|
"experimental_info" => "Experimental settings will probably not work perfectly.",
|
||||||
"payment_methods" => "Payment Methods",
|
"payment_methods" => "Payment Methods",
|
||||||
"payment_methods_info" => "Click a payment method to disable / enable it.",
|
"payment_methods_info" => "Click a payment method to disable / enable it.",
|
||||||
|
"rename_payment_methods_info" => "Click the name on a payment method to rename it.",
|
||||||
"cant_delete_payment_method_in_use" => "Can't disable used payment method",
|
"cant_delete_payment_method_in_use" => "Can't disable used payment method",
|
||||||
"add_custom_payment" => "Add Custom Payment Method",
|
"add_custom_payment" => "Add Custom Payment Method",
|
||||||
"payment_method_name" => "Payment Method Name",
|
"payment_method_name" => "Payment Method Name",
|
||||||
"payment_method_added_successfuly" => "Payment method added successfully",
|
"payment_method_added_successfuly" => "Payment method added successfully",
|
||||||
"disable" => "Disable",
|
"disable" => "Disable",
|
||||||
"enable" => "Enable",
|
"enable" => "Enable",
|
||||||
|
"rename_payment_method" => "Rename Payment Method",
|
||||||
|
"payment_renamed" => "Payment method renamed",
|
||||||
|
"payment_not_renamed" => "Payment method not renamed",
|
||||||
"test" => "Test",
|
"test" => "Test",
|
||||||
"add" => "Add",
|
"add" => "Add",
|
||||||
"save" => "Save",
|
"save" => "Save",
|
||||||
"export_subscriptions" => "Export Subscriptions",
|
"export_subscriptions" => "Export Subscriptions",
|
||||||
"export_to_json" => "Export to JSON",
|
"export_to_json" => "Export to JSON",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "Filter",
|
||||||
|
"clear" => "Clear",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Success",
|
"success" => "Success",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Failed to remove category",
|
"failed_remove_category" => "Failed to remove category",
|
||||||
"category_saved" => "Category saved",
|
"category_saved" => "Category saved",
|
||||||
"category_removed" => "Category removed",
|
"category_removed" => "Category removed",
|
||||||
|
"sort_order_saved" => "Sort order saved",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "was saved.",
|
"currency_saved" => "was saved.",
|
||||||
"error_adding_currency" => "Error adding currency entry.",
|
"error_adding_currency" => "Error adding currency entry.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Las configuraciones experimentales probablemente no funcionarán perfectamente.",
|
"experimental_info" => "Las configuraciones experimentales probablemente no funcionarán perfectamente.",
|
||||||
"payment_methods" => "Métodos de Pago",
|
"payment_methods" => "Métodos de Pago",
|
||||||
"payment_methods_info" => "Haz clic en un método de pago para deshabilitarlo/habilitarlo.",
|
"payment_methods_info" => "Haz clic en un método de pago para deshabilitarlo/habilitarlo.",
|
||||||
|
"rename_payment_methods_info" => "Haz clic en el nombre de un método de pago para cambiarle el nombre.",
|
||||||
"cant_delete_payment_method_in_use" => "No se puede desactivar el método de pago utilizado",
|
"cant_delete_payment_method_in_use" => "No se puede desactivar el método de pago utilizado",
|
||||||
"add_custom_payment" => "Añadir método de pago personalizado",
|
"add_custom_payment" => "Añadir método de pago personalizado",
|
||||||
"payment_method_name" => "Nombre del método de pago",
|
"payment_method_name" => "Nombre del método de pago",
|
||||||
"payment_method_added_successfuly" => "Método de pago añadido con éxito",
|
"payment_method_added_successfuly" => "Método de pago añadido con éxito",
|
||||||
"disable" => "Desactivar",
|
"disable" => "Desactivar",
|
||||||
"enable" => "Activar",
|
"enable" => "Activar",
|
||||||
|
"rename_payment_method" => "Renombrar método de pago",
|
||||||
|
"payment_renamed" => "Método de pago renombrado",
|
||||||
|
"payment_not_renamed" => "Error al renombrar el método de pago",
|
||||||
"test" => "Probar",
|
"test" => "Probar",
|
||||||
"add" => "Agregar",
|
"add" => "Agregar",
|
||||||
"save" => "Guardar",
|
"save" => "Guardar",
|
||||||
"export_subscriptions" => "Exportar suscripciones",
|
"export_subscriptions" => "Exportar suscripciones",
|
||||||
"export_to_json" => "Exportar a JSON",
|
"export_to_json" => "Exportar a JSON",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "Filtrar",
|
||||||
|
"clear" => "Limpiar",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Éxito",
|
"success" => "Éxito",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Error al eliminar la categoría",
|
"failed_remove_category" => "Error al eliminar la categoría",
|
||||||
"category_saved" => "Categoría guardada",
|
"category_saved" => "Categoría guardada",
|
||||||
"category_removed" => "Categoría eliminada",
|
"category_removed" => "Categoría eliminada",
|
||||||
|
"sort_order_saved" => "Orden de clasificación guardado",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "fue guardada.",
|
"currency_saved" => "fue guardada.",
|
||||||
"error_adding_currency" => "Error al añadir la entrada de la moneda.",
|
"error_adding_currency" => "Error al añadir la entrada de la moneda.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Les paramètres expérimentaux ne fonctionneront probablement pas parfaitement.",
|
"experimental_info" => "Les paramètres expérimentaux ne fonctionneront probablement pas parfaitement.",
|
||||||
"payment_methods" => "Méthodes de paiement",
|
"payment_methods" => "Méthodes de paiement",
|
||||||
"payment_methods_info" => "Cliquez sur une méthode de paiement pour la désactiver / l'activer.",
|
"payment_methods_info" => "Cliquez sur une méthode de paiement pour la désactiver / l'activer.",
|
||||||
|
"rename_payment_methods_info" => "Cliquez sur le nom d'un mode de paiement pour le renommer.",
|
||||||
"cant_delete_payment_method_in_use" => "Impossible de désactiver la méthode de paiement utilisée",
|
"cant_delete_payment_method_in_use" => "Impossible de désactiver la méthode de paiement utilisée",
|
||||||
"add_custom_payment" => "Ajouter un paiement personnalisé",
|
"add_custom_payment" => "Ajouter un paiement personnalisé",
|
||||||
"payment_method_name" => "Nom de la méthode de paiement",
|
"payment_method_name" => "Nom de la méthode de paiement",
|
||||||
"payment_method_added_successfuly" => "Méthode de paiement ajoutée avec succès",
|
"payment_method_added_successfuly" => "Méthode de paiement ajoutée avec succès",
|
||||||
"disable" => "Désactiver",
|
"disable" => "Désactiver",
|
||||||
"enable" => "Activer",
|
"enable" => "Activer",
|
||||||
|
"rename_payment_method" => "Renommer la méthode de paiement",
|
||||||
|
"payment_renamed" => "Méthode de paiement renommée",
|
||||||
|
"payment_not_renamed" => "La méthode de paiement n'a pas été renommée",
|
||||||
"test" => "Test",
|
"test" => "Test",
|
||||||
"add" => "Ajouter",
|
"add" => "Ajouter",
|
||||||
"save" => "Enregistrer",
|
"save" => "Enregistrer",
|
||||||
"export_subscriptions" => "Exporter les abonnements",
|
"export_subscriptions" => "Exporter les abonnements",
|
||||||
"export_to_json" => "Exporter en JSON",
|
"export_to_json" => "Exporter en JSON",
|
||||||
|
// Menu des filtes
|
||||||
|
"filter" => "Filtre",
|
||||||
|
"clear" => "Effacer",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Succès",
|
"success" => "Succès",
|
||||||
// Réponses de l'API
|
// Réponses de l'API
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Échec de la suppression de la catégorie",
|
"failed_remove_category" => "Échec de la suppression de la catégorie",
|
||||||
"category_saved" => "Catégorie enregistrée",
|
"category_saved" => "Catégorie enregistrée",
|
||||||
"category_removed" => "Catégorie supprimée",
|
"category_removed" => "Catégorie supprimée",
|
||||||
|
"sort_order_saved" => "L'ordre de tri a été enregistré",
|
||||||
// Devise
|
// Devise
|
||||||
"currency_saved" => "a été enregistrée.",
|
"currency_saved" => "a été enregistrée.",
|
||||||
"error_adding_currency" => "Erreur lors de l'ajout de l'entrée de devise.",
|
"error_adding_currency" => "Erreur lors de l'ajout de l'entrée de devise.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "実験的な設定は、おそらく完全には機能しません。",
|
"experimental_info" => "実験的な設定は、おそらく完全には機能しません。",
|
||||||
"payment_methods" => "支払い方法",
|
"payment_methods" => "支払い方法",
|
||||||
"payment_methods_info" => "支払い方法をクリックして無効/有効を切り替えます。",
|
"payment_methods_info" => "支払い方法をクリックして無効/有効を切り替えます。",
|
||||||
|
"rename_payment_methods_info" => "支払い方法の名前をクリックして、名前を変更します。",
|
||||||
"cant_delete_payment_method_in_use" => "支払い方法が使用中のため無効にできません。",
|
"cant_delete_payment_method_in_use" => "支払い方法が使用中のため無効にできません。",
|
||||||
"add_custom_payment" => "カスタム支払い方法を追加",
|
"add_custom_payment" => "カスタム支払い方法を追加",
|
||||||
"payment_method_name" => "支払い方法名",
|
"payment_method_name" => "支払い方法名",
|
||||||
"payment_method_added_successfuly" => "支払い方法が追加されました",
|
"payment_method_added_successfuly" => "支払い方法が追加されました",
|
||||||
"disable" => "無効",
|
"disable" => "無効",
|
||||||
"enable" => "有効",
|
"enable" => "有効",
|
||||||
|
"rename_payment_method" => "支払い方法の名前を変更",
|
||||||
|
"payment_renamed" => "支払い方法が変更されました",
|
||||||
|
"payment_not_renamed" => "支払い方法が変更されませんでした",
|
||||||
"test" => "テスト",
|
"test" => "テスト",
|
||||||
"add" => "追加",
|
"add" => "追加",
|
||||||
"save" => "保存",
|
"save" => "保存",
|
||||||
"export_subscriptions" => "購読をエクスポート",
|
"export_subscriptions" => "購読をエクスポート",
|
||||||
"export_to_json" => "JSONにエクスポート",
|
"export_to_json" => "JSONにエクスポート",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "フィルタ",
|
||||||
|
"clear" => "クリア",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "成功",
|
"success" => "成功",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "カテゴリの削除に失敗",
|
"failed_remove_category" => "カテゴリの削除に失敗",
|
||||||
"category_saved" => "カテゴリの保存",
|
"category_saved" => "カテゴリの保存",
|
||||||
"category_removed" => "カテゴリの削除",
|
"category_removed" => "カテゴリの削除",
|
||||||
|
"sort_order_saved" => "並べ替え順が保存されました",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "通貨を保存",
|
"currency_saved" => "通貨を保存",
|
||||||
"error_adding_currency" => "通貨エントリの追加エラー.",
|
"error_adding_currency" => "通貨エントリの追加エラー.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Definições experimentais provavelmente não funcionarão correctamente.",
|
"experimental_info" => "Definições experimentais provavelmente não funcionarão correctamente.",
|
||||||
"payment_methods" => "Métodos de Pagamento",
|
"payment_methods" => "Métodos de Pagamento",
|
||||||
"payment_methods_info" => "Clique num método de pagamento para o activar / desactivar.",
|
"payment_methods_info" => "Clique num método de pagamento para o activar / desactivar.",
|
||||||
|
"rename_payment_methods_info" => "Clique no nome do método de pagamento para o renomear.",
|
||||||
"cant_delete_payment_method_in_use" => "Não pode desactivar metodo de pagamento em uso",
|
"cant_delete_payment_method_in_use" => "Não pode desactivar metodo de pagamento em uso",
|
||||||
"add_custom_payment" => "Adicionar método de pagamento personalizado",
|
"add_custom_payment" => "Adicionar método de pagamento personalizado",
|
||||||
"payment_method_name" => "Nome do método de pagamento",
|
"payment_method_name" => "Nome do método de pagamento",
|
||||||
"payment_method_added_successfuly" => "Método de pagamento adicionado com sucesso",
|
"payment_method_added_successfuly" => "Método de pagamento adicionado com sucesso",
|
||||||
"disable" => "Desactivar",
|
"disable" => "Desactivar",
|
||||||
"enable" => "Activar",
|
"enable" => "Activar",
|
||||||
|
"rename_payment_method" => "Renomear método de pagamento",
|
||||||
|
"payment_renamed" => "Método de pagamento renomeado",
|
||||||
|
"payment_not_renamed" => "Método de pagamento não renomeado",
|
||||||
"test" => "Testar",
|
"test" => "Testar",
|
||||||
"add" => "Adicionar",
|
"add" => "Adicionar",
|
||||||
"save" => "Guardar",
|
"save" => "Guardar",
|
||||||
"export_subscriptions" => "Exportar Subscrições",
|
"export_subscriptions" => "Exportar Subscrições",
|
||||||
"export_to_json" => "Exportar para JSON",
|
"export_to_json" => "Exportar para JSON",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "Filtro",
|
||||||
|
"clear" => "Limpar",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Sucesso",
|
"success" => "Sucesso",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Erro ao remover categoria",
|
"failed_remove_category" => "Erro ao remover categoria",
|
||||||
"category_saved" => "Categoria guardada",
|
"category_saved" => "Categoria guardada",
|
||||||
"category_removed" => "Categoria removida",
|
"category_removed" => "Categoria removida",
|
||||||
|
"sort_order_saved" => "Ordenação guardada",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "guardada.",
|
"currency_saved" => "guardada.",
|
||||||
"error_adding_currency" => "Erro ao adicionar moeda.",
|
"error_adding_currency" => "Erro ao adicionar moeda.",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "Deneysel ayarlar muhtemelen mükemmel çalışmayacak.",
|
"experimental_info" => "Deneysel ayarlar muhtemelen mükemmel çalışmayacak.",
|
||||||
"payment_methods" => "Ödeme Yöntemleri",
|
"payment_methods" => "Ödeme Yöntemleri",
|
||||||
"payment_methods_info" => "Bir ödeme yöntemini devre dışı bırakmak / etkinleştirmek için tıklayın.",
|
"payment_methods_info" => "Bir ödeme yöntemini devre dışı bırakmak / etkinleştirmek için tıklayın.",
|
||||||
|
"rename_payment_methods_info" => "Yeniden adlandırmak için bir ödeme yönteminin adına tıklayın.",
|
||||||
"cant_delete_payment_method_in_use" => "Kullanımda olan ödeme yöntemini devre dışı bırakamazsınız",
|
"cant_delete_payment_method_in_use" => "Kullanımda olan ödeme yöntemini devre dışı bırakamazsınız",
|
||||||
"add_custom_payment" => "Özel ödeme yöntemi ekle",
|
"add_custom_payment" => "Özel ödeme yöntemi ekle",
|
||||||
"payment_method_name" => "Ödeme Yöntemi Adı",
|
"payment_method_name" => "Ödeme Yöntemi Adı",
|
||||||
"payment_method_added_successfuly" => "Ödeme yöntemi başarıyla eklendi",
|
"payment_method_added_successfuly" => "Ödeme yöntemi başarıyla eklendi",
|
||||||
"disable" => "Devre Dışı Bırak",
|
"disable" => "Devre Dışı Bırak",
|
||||||
"enable" => "Etkinleştir",
|
"enable" => "Etkinleştir",
|
||||||
|
"rename_payment_method" => "Ödeme yöntemi adını değiştir",
|
||||||
|
"payment_renamed" => "Ödeme yöntemi adı değiştirildi",
|
||||||
|
"payment_not_renamed" => "Ödeme yöntemi adı değiştirilemedi",
|
||||||
"test" => "Test Et",
|
"test" => "Test Et",
|
||||||
"add" => "Ekle",
|
"add" => "Ekle",
|
||||||
"save" => "Kaydet",
|
"save" => "Kaydet",
|
||||||
"export_subscriptions" => "Abonelikleri Dışa Aktar",
|
"export_subscriptions" => "Abonelikleri Dışa Aktar",
|
||||||
"export_to_json" => "JSON'a dışa aktar",
|
"export_to_json" => "JSON'a dışa aktar",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "Filtre",
|
||||||
|
"clear" => "Temizle",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "Başarılı",
|
"success" => "Başarılı",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "Kategori kaldırılamadı",
|
"failed_remove_category" => "Kategori kaldırılamadı",
|
||||||
"category_saved" => "Kategori kaydedildi",
|
"category_saved" => "Kategori kaydedildi",
|
||||||
"category_removed" => "Kategori kaldırıldı",
|
"category_removed" => "Kategori kaldırıldı",
|
||||||
|
"sort_order_saved" => "Sıralama düzeni kaydedildi",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "kaydedildi.",
|
"currency_saved" => "kaydedildi.",
|
||||||
"error_adding_currency" => "Para birimi girişi eklenirken hata oluştu.",
|
"error_adding_currency" => "Para birimi girişi eklenirken hata oluştu.",
|
||||||
|
|||||||
@ -143,17 +143,25 @@ $i18n = [
|
|||||||
"experimental_info" => "实验性设置,可能存在问题。",
|
"experimental_info" => "实验性设置,可能存在问题。",
|
||||||
"payment_methods" => "支付方式",
|
"payment_methods" => "支付方式",
|
||||||
"payment_methods_info" => "点击支付方式以禁用/启用。",
|
"payment_methods_info" => "点击支付方式以禁用/启用。",
|
||||||
|
"rename_payment_methods_info" => "点击付款方式名称,重新命名该付款方式。"
|
||||||
"cant_delete_payment_method_in_use" => "不能禁用正在使用的支付方式",
|
"cant_delete_payment_method_in_use" => "不能禁用正在使用的支付方式",
|
||||||
"add_custom_payment" => "添加自定义支付方式",
|
"add_custom_payment" => "添加自定义支付方式",
|
||||||
"payment_method_name" => "支付方式名称",
|
"payment_method_name" => "支付方式名称",
|
||||||
"payment_method_added_successfuly" => "支付方式已成功添加",
|
"payment_method_added_successfuly" => "支付方式已成功添加",
|
||||||
"disable" => "禁用",
|
"disable" => "禁用",
|
||||||
"enable" => "启用",
|
"enable" => "启用",
|
||||||
|
"rename_payment_method" => "重命名支付方式",
|
||||||
|
"payment_renamed" => "支付方式已重命名",
|
||||||
|
"payment_not_renamed" => "支付方式未重命名",
|
||||||
"test" => "测试",
|
"test" => "测试",
|
||||||
"add" => "添加",
|
"add" => "添加",
|
||||||
"save" => "保存",
|
"save" => "保存",
|
||||||
"export_subscriptions" => "导出订阅",
|
"export_subscriptions" => "导出订阅",
|
||||||
"export_to_json" => "导出为 JSON",
|
"export_to_json" => "导出为 JSON",
|
||||||
|
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "筛选",
|
||||||
|
"clear" => "清除",
|
||||||
|
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "成功",
|
"success" => "成功",
|
||||||
@ -172,6 +180,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "移除分类失败",
|
"failed_remove_category" => "移除分类失败",
|
||||||
"category_saved" => "分类已保存",
|
"category_saved" => "分类已保存",
|
||||||
"category_removed" => "分类已移除",
|
"category_removed" => "分类已移除",
|
||||||
|
"sort_order_saved" => "排序顺序已保存",
|
||||||
|
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "货币已保存。",
|
"currency_saved" => "货币已保存。",
|
||||||
|
|||||||
@ -136,17 +136,24 @@ $i18n = [
|
|||||||
"experimental_info" => "實驗性設定,可能存在問題。",
|
"experimental_info" => "實驗性設定,可能存在問題。",
|
||||||
"payment_methods" => "付款方式",
|
"payment_methods" => "付款方式",
|
||||||
"payment_methods_info" => "點選付款方式以停用/啟用。",
|
"payment_methods_info" => "點選付款方式以停用/啟用。",
|
||||||
|
"rename_payment_methods_info" => "點選付款方式的名稱可對其進行重新命名。",
|
||||||
"cant_delete_payment_method_in_use" => "無法停用正在使用的付款方式",
|
"cant_delete_payment_method_in_use" => "無法停用正在使用的付款方式",
|
||||||
"add_custom_payment" => "新增自訂付款方式",
|
"add_custom_payment" => "新增自訂付款方式",
|
||||||
"payment_method_name" => "付款方式名稱",
|
"payment_method_name" => "付款方式名稱",
|
||||||
"payment_method_added_successfuly" => "付款方式已成功新增",
|
"payment_method_added_successfuly" => "付款方式已成功新增",
|
||||||
"disable" => "停用",
|
"disable" => "停用",
|
||||||
"enable" => "啟用",
|
"enable" => "啟用",
|
||||||
|
"rename_payment_method" => "更改付款方式名稱",
|
||||||
|
"payment_renamed" => "付款方式名稱已更改",
|
||||||
|
"payment_not_renamed" => "付款方式名稱未更改",
|
||||||
"test" => "測試",
|
"test" => "測試",
|
||||||
"add" => "新增",
|
"add" => "新增",
|
||||||
"save" => "儲存",
|
"save" => "儲存",
|
||||||
"export_subscriptions" => "匯出訂閱",
|
"export_subscriptions" => "匯出訂閱",
|
||||||
"export_to_json" => "匯出為 JSON 檔案",
|
"export_to_json" => "匯出為 JSON 檔案",
|
||||||
|
// Filters menu
|
||||||
|
"filter" => "篩選",
|
||||||
|
"clear" => "清除",
|
||||||
// Toast
|
// Toast
|
||||||
"success" => "成功",
|
"success" => "成功",
|
||||||
// Endpoint responses
|
// Endpoint responses
|
||||||
@ -162,6 +169,7 @@ $i18n = [
|
|||||||
"failed_remove_category" => "移除分類失敗",
|
"failed_remove_category" => "移除分類失敗",
|
||||||
"category_saved" => "分類已儲存",
|
"category_saved" => "分類已儲存",
|
||||||
"category_removed" => "分類已移除",
|
"category_removed" => "分類已移除",
|
||||||
|
"sort_order_saved" => "排序順序已儲存",
|
||||||
// Currency
|
// Currency
|
||||||
"currency_saved" => "已儲存。",
|
"currency_saved" => "已儲存。",
|
||||||
"error_adding_currency" => "新增貨幣時發生錯誤。",
|
"error_adding_currency" => "新增貨幣時發生錯誤。",
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
$version = "v1.11.3";
|
$version = "v1.12.0";
|
||||||
?>
|
?>
|
||||||
14
migrations/000010.php
Normal file
14
migrations/000010.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
// This migration adds a "order" column to the categories table so that they can be sorted and initializes all values to their id.
|
||||||
|
|
||||||
|
/** @noinspection PhpUndefinedVariableInspection */
|
||||||
|
$columnQuery = $db->query("SELECT * FROM pragma_table_info('categories') WHERE name='order'");
|
||||||
|
$columnRequired = $columnQuery->fetchArray(SQLITE3_ASSOC) === false;
|
||||||
|
|
||||||
|
if ($columnRequired) {
|
||||||
|
$db->exec('ALTER TABLE categories ADD COLUMN `order` INTEGER DEFAULT 0');
|
||||||
|
$db->exec('UPDATE categories SET `order` = id');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
2
scripts/libs/sortable.min.js
vendored
Normal file
2
scripts/libs/sortable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -165,9 +165,12 @@ function addCategoryButton(categoryId) {
|
|||||||
if(responseData.success) {
|
if(responseData.success) {
|
||||||
const newCategoryId = responseData.categoryId;;
|
const newCategoryId = responseData.categoryId;;
|
||||||
let container = document.getElementById("categories");
|
let container = document.getElementById("categories");
|
||||||
let div = document.createElement("div");
|
let row = document.createElement("li");
|
||||||
div.className = "form-group-inline";
|
row.className = "form-group-inline";
|
||||||
div.dataset.categoryid = newCategoryId;
|
row.dataset.categoryid = newCategoryId;
|
||||||
|
|
||||||
|
let dragIcon = document.createElement("div");
|
||||||
|
dragIcon.className = "drag-icon";
|
||||||
|
|
||||||
let input = document.createElement("input");
|
let input = document.createElement("input");
|
||||||
input.type = "text";
|
input.type = "text";
|
||||||
@ -201,11 +204,12 @@ function addCategoryButton(categoryId) {
|
|||||||
|
|
||||||
deleteLink.appendChild(deleteImage);
|
deleteLink.appendChild(deleteImage);
|
||||||
|
|
||||||
div.appendChild(input);
|
row.appendChild(dragIcon);
|
||||||
div.appendChild(editLink);
|
row.appendChild(input);
|
||||||
div.appendChild(deleteLink);
|
row.appendChild(editLink);
|
||||||
|
row.appendChild(deleteLink);
|
||||||
|
|
||||||
container.appendChild(div);
|
container.appendChild(row);
|
||||||
} else {
|
} else {
|
||||||
showErrorMessage(responseData.errorMessage);
|
showErrorMessage(responseData.errorMessage);
|
||||||
}
|
}
|
||||||
@ -246,6 +250,7 @@ function removeCategory(categoryId) {
|
|||||||
function editCategory(categoryId) {
|
function editCategory(categoryId) {
|
||||||
var saveButton = document.querySelector(`div[data-categoryid="${categoryId}"] button[name="save"]`);
|
var saveButton = document.querySelector(`div[data-categoryid="${categoryId}"] button[name="save"]`);
|
||||||
var inputElement = document.querySelector(`div[data-categoryid="${categoryId}"] input[name="category"]`);
|
var inputElement = document.querySelector(`div[data-categoryid="${categoryId}"] input[name="category"]`);
|
||||||
|
console.log(saveButton);
|
||||||
saveButton.classList.add("disabled");
|
saveButton.classList.add("disabled");
|
||||||
saveButton.disabled = true;
|
saveButton.disabled = true;
|
||||||
if (inputElement) {
|
if (inputElement) {
|
||||||
@ -424,7 +429,7 @@ function togglePayment(paymentId) {
|
|||||||
const element = document.querySelector(`div[data-paymentid="${paymentId}"]`);
|
const element = document.querySelector(`div[data-paymentid="${paymentId}"]`);
|
||||||
|
|
||||||
if (element.dataset.inUse === 'yes') {
|
if (element.dataset.inUse === 'yes') {
|
||||||
return showErrorMessage(translate(cant_disable_payment_in_use));
|
return showErrorMessage(translate('cant_disable_payment_in_use'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const newEnabledState = element.dataset.enabled === '1' ? '0' : '1';
|
const newEnabledState = element.dataset.enabled === '1' ? '0' : '1';
|
||||||
@ -449,6 +454,69 @@ function togglePayment(paymentId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.body.addEventListener('click', function(e) {
|
||||||
|
let targetElement = e.target;
|
||||||
|
do {
|
||||||
|
if (targetElement.classList && targetElement.classList.contains('payments-payment')) {
|
||||||
|
let targetChild = e.target;
|
||||||
|
do {
|
||||||
|
if (targetChild.classList && targetChild.classList.contains('payment-name')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
targetChild = targetChild.parentNode;
|
||||||
|
} while (targetChild && targetChild !== targetElement);
|
||||||
|
|
||||||
|
const paymentId = targetElement.dataset.paymentid;
|
||||||
|
togglePayment(paymentId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
targetElement = targetElement.parentNode;
|
||||||
|
} while (targetElement);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.addEventListener('blur', function(e) {
|
||||||
|
let targetElement = e.target;
|
||||||
|
if (targetElement.classList && targetElement.classList.contains('payment-name')) {
|
||||||
|
const paymentId = targetElement.closest('.payments-payment').dataset.paymentid;
|
||||||
|
const newName = targetElement.textContent;
|
||||||
|
renamePayment(paymentId, newName);
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
function renamePayment(paymentId, newName) {
|
||||||
|
const name = newName.trim();
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('paymentId', paymentId);
|
||||||
|
formData.append('name', name);
|
||||||
|
fetch('endpoints/payments/rename.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
}).then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(translate('network_response_error'));
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}).then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showSuccessMessage(`${newName} ${data.message}`);
|
||||||
|
} else {
|
||||||
|
showErrorMessage(data.message);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
showErrorMessage(translate('unknown_error'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.addEventListener('keypress', function(e) {
|
||||||
|
let targetElement = e.target;
|
||||||
|
if (targetElement.classList && targetElement.classList.contains('payment-name')) {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
targetElement.blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function handleFileSelect(event) {
|
function handleFileSelect(event) {
|
||||||
const fileInput = event.target;
|
const fileInput = event.target;
|
||||||
const iconPreview = document.querySelector('.icon-preview');
|
const iconPreview = document.querySelector('.icon-preview');
|
||||||
@ -843,3 +911,41 @@ function setRemoveBackground() {
|
|||||||
function exportToJson() {
|
function exportToJson() {
|
||||||
window.location.href = "endpoints/subscriptions/export.php";
|
window.location.href = "endpoints/subscriptions/export.php";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveCategorySorting() {
|
||||||
|
const categories = document.getElementById('categories');
|
||||||
|
const categoryIds = Array.from(categories.children).map(category => category.dataset.categoryid);
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
categoryIds.forEach(categoryId => {
|
||||||
|
formData.append('categoryIds[]', categoryId);
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch('endpoints/categories/sort.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showSuccessMessage(data.message);
|
||||||
|
} else {
|
||||||
|
showErrorMessage(data.errorMessage);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
showErrorMessage(translate('unknown_error'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var el = document.getElementById('categories');
|
||||||
|
var sortable = Sortable.create(el, {
|
||||||
|
handle: '.drag-icon',
|
||||||
|
ghostClass: 'sortable-ghost',
|
||||||
|
delay: 500,
|
||||||
|
delayOnTouchOnly: true,
|
||||||
|
touchStartThreshold: 5,
|
||||||
|
onEnd: function (evt) {
|
||||||
|
saveCategorySorting();
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -25,3 +25,91 @@ function loadGraph(container, dataPoints, currency, run) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closeSubMenus() {
|
||||||
|
var subMenus = document.querySelectorAll('.filtermenu-submenu-content');
|
||||||
|
subMenus.forEach(subMenu => {
|
||||||
|
subMenu.classList.remove('is-open');
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
var filtermenu = document.querySelector('#filtermenu-button');
|
||||||
|
filtermenu.addEventListener('click', function() {
|
||||||
|
this.parentElement.querySelector('.filtermenu-content').classList.toggle('is-open');
|
||||||
|
closeSubMenus();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
var filtermenuContent = document.querySelector('.filtermenu-content');
|
||||||
|
if (filtermenuContent.classList.contains('is-open')) {
|
||||||
|
var subMenus = document.querySelectorAll('.filtermenu-submenu');
|
||||||
|
var clickedInsideSubmenu = Array.from(subMenus).some(subMenu => subMenu.contains(e.target) || subMenu === e.target);
|
||||||
|
|
||||||
|
if (!filtermenu.contains(e.target) && !clickedInsideSubmenu) {
|
||||||
|
closeSubMenus();
|
||||||
|
filtermenuContent.classList.remove('is-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleSubMenu(subMenu) {
|
||||||
|
var subMenu = document.getElementById("filter-" + subMenu);
|
||||||
|
if (subMenu.classList.contains("is-open")) {
|
||||||
|
closeSubMenus();
|
||||||
|
} else {
|
||||||
|
closeSubMenus();
|
||||||
|
subMenu.classList.add("is-open");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.filter-item').forEach(function(item) {
|
||||||
|
item.addEventListener('click', function(e) {
|
||||||
|
if (this.hasAttribute('data-categoryid')) {
|
||||||
|
const categoryId = this.getAttribute('data-categoryid');
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
let newUrl = 'stats.php?';
|
||||||
|
|
||||||
|
if (urlParams.get('category') === categoryId) {
|
||||||
|
urlParams.delete('category');
|
||||||
|
} else {
|
||||||
|
urlParams.set('category', categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
newUrl += urlParams.toString();
|
||||||
|
window.location.href = newUrl;
|
||||||
|
} else if (this.hasAttribute('data-memberid')) {
|
||||||
|
const memberId = this.getAttribute('data-memberid');
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
let newUrl = 'stats.php?';
|
||||||
|
|
||||||
|
if (urlParams.get('member') === memberId) {
|
||||||
|
urlParams.delete('member');
|
||||||
|
} else {
|
||||||
|
urlParams.set('member', memberId);
|
||||||
|
}
|
||||||
|
|
||||||
|
newUrl += urlParams.toString();
|
||||||
|
window.location.href = newUrl;
|
||||||
|
} else if (this.hasAttribute('data-paymentid')) {
|
||||||
|
const paymentId = this.getAttribute('data-paymentid');
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
let newUrl = 'stats.php?';
|
||||||
|
|
||||||
|
if (urlParams.get('payment') === paymentId) {
|
||||||
|
urlParams.delete('payment');
|
||||||
|
} else {
|
||||||
|
urlParams.set('payment', paymentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
newUrl += urlParams.toString();
|
||||||
|
window.location.href = newUrl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function clearFilters() {
|
||||||
|
window.location.href = 'stats.php';
|
||||||
|
}
|
||||||
@ -33,6 +33,7 @@ self.addEventListener('install', function(event) {
|
|||||||
'scripts/i18n/zh_tw.js',
|
'scripts/i18n/zh_tw.js',
|
||||||
'scripts/i18n/getlang.js',
|
'scripts/i18n/getlang.js',
|
||||||
'scripts/libs/chart.js',
|
'scripts/libs/chart.js',
|
||||||
|
'scripts/libs/sortable.min.js',
|
||||||
'images/icon/favicon.ico',
|
'images/icon/favicon.ico',
|
||||||
'images/wallossolid.png',
|
'images/wallossolid.png',
|
||||||
'images/wallossolidwhite.png',
|
'images/wallossolidwhite.png',
|
||||||
|
|||||||
19
settings.php
19
settings.php
@ -2,6 +2,7 @@
|
|||||||
require_once 'includes/header.php';
|
require_once 'includes/header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<script src="scripts/libs/sortable.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.logo-preview:after {
|
.logo-preview:after {
|
||||||
content: '<?= translate('upload_logo', $i18n) ?>';
|
content: '<?= translate('upload_logo', $i18n) ?>';
|
||||||
@ -238,7 +239,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$sql = "SELECT * FROM categories";
|
$sql = "SELECT * FROM categories ORDER BY `order` ASC";
|
||||||
$result = $db->query($sql);
|
$result = $db->query($sql);
|
||||||
|
|
||||||
if ($result) {
|
if ($result) {
|
||||||
@ -254,7 +255,7 @@
|
|||||||
<h2><?= translate('categories', $i18n) ?></h2>
|
<h2><?= translate('categories', $i18n) ?></h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="account-categories">
|
<div class="account-categories">
|
||||||
<div id="categories">
|
<div id="categories" class="sortable-list">
|
||||||
<?php
|
<?php
|
||||||
foreach ($categories as $category) {
|
foreach ($categories as $category) {
|
||||||
if ($category['id'] != 1) {
|
if ($category['id'] != 1) {
|
||||||
@ -272,6 +273,7 @@
|
|||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<div class="form-group-inline" data-categoryid="<?= $category['id'] ?>">
|
<div class="form-group-inline" data-categoryid="<?= $category['id'] ?>">
|
||||||
|
<div class="drag-icon"></div>
|
||||||
<input type="text" name="category" value="<?= $category['name'] ?>" placeholder="Category">
|
<input type="text" name="category" value="<?= $category['name'] ?>" placeholder="Category">
|
||||||
<button class="image-button medium" onClick="editCategory(<?= $category['id'] ?>)" name="save">
|
<button class="image-button medium" onClick="editCategory(<?= $category['id'] ?>)" name="save">
|
||||||
<img src="images/siteicons/save.png" title="<?= translate('save_category', $i18n) ?>">
|
<img src="images/siteicons/save.png" title="<?= translate('save_category', $i18n) ?>">
|
||||||
@ -497,14 +499,11 @@
|
|||||||
data-enabled="<?= $payment['enabled']; ?>"
|
data-enabled="<?= $payment['enabled']; ?>"
|
||||||
data-in-use="<?= $inUse ? 'yes' : 'no' ?>"
|
data-in-use="<?= $inUse ? 'yes' : 'no' ?>"
|
||||||
data-paymentid="<?= $payment['id'] ?>"
|
data-paymentid="<?= $payment['id'] ?>"
|
||||||
title="<?= $inUse ? translate('cant_delete_payment_method_in_use', $i18n) : ($payment['enabled'] ? translate('disable', $i18n) : translate('enable', $i18n)) ?>"
|
title="<?= $inUse ? translate('cant_delete_payment_method_in_use', $i18n) : ($payment['enabled'] ? translate('disable', $i18n) : translate('enable', $i18n)) ?>">
|
||||||
onClick="togglePayment(<?= $payment['id'] ?>)">
|
|
||||||
<img src="<?= $paymentIconFolder.$payment['icon'] ?>" alt="Logo" />
|
<img src="<?= $paymentIconFolder.$payment['icon'] ?>" alt="Logo" />
|
||||||
<span class="payment-name">
|
<span class="payment-name" contenteditable="true" title="<?= translate("rename_payment_method", $i18n) ?>"><?= $payment['name'] ?></span>
|
||||||
<?= $payment['name'] ?>
|
|
||||||
</span>
|
|
||||||
<?php
|
<?php
|
||||||
if ($payment['id'] > 31 && !$inUse) {
|
if (!$inUse) {
|
||||||
?>
|
?>
|
||||||
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>">x</div>
|
<div class="delete-payment-method" title="<?= translate('delete', $i18n) ?>" data-paymentid="<?= $payment['id'] ?>">x</div>
|
||||||
<?php
|
<?php
|
||||||
@ -520,6 +519,10 @@
|
|||||||
<i class="fa-solid fa-circle-info"></i>
|
<i class="fa-solid fa-circle-info"></i>
|
||||||
<?= translate('payment_methods_info', $i18n) ?>
|
<?= translate('payment_methods_info', $i18n) ?>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<i class="fa-solid fa-circle-info"></i>
|
||||||
|
<?= translate('rename_payment_methods_info', $i18n) ?>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<header>
|
<header>
|
||||||
<h2 class="second-header"><?= translate("add_custom_payment", $i18n) ?></h2>
|
<h2 class="second-header"><?= translate("add_custom_payment", $i18n) ?></h2>
|
||||||
|
|||||||
281
stats.php
281
stats.php
@ -51,7 +51,7 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
|||||||
|
|
||||||
// Get categories
|
// Get categories
|
||||||
$categories = array();
|
$categories = array();
|
||||||
$query = "SELECT * FROM categories";
|
$query = "SELECT * FROM categories ORDER BY 'order' ASC";
|
||||||
$result = $db->query($query);
|
$result = $db->query($query);
|
||||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
$categoryId = $row['id'];
|
$categoryId = $row['id'];
|
||||||
@ -61,7 +61,7 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get payment methods
|
// Get payment methods
|
||||||
$categories = array();
|
$paymentMethodCount = array();
|
||||||
$query = "SELECT * FROM payment_methods WHERE enabled = 1";
|
$query = "SELECT * FROM payment_methods WHERE enabled = 1";
|
||||||
$result = $db->query($query);
|
$result = $db->query($query);
|
||||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
@ -89,8 +89,41 @@ $amountDueThisMonth = 0;
|
|||||||
$totalCostPerMonth = 0;
|
$totalCostPerMonth = 0;
|
||||||
$totalSavingsPerMonth = 0;
|
$totalSavingsPerMonth = 0;
|
||||||
|
|
||||||
|
$statsSubtitleParts = [];
|
||||||
$query = "SELECT name, price, frequency, cycle, currency_id, next_payment, payer_user_id, category_id, payment_method_id, inactive FROM subscriptions";
|
$query = "SELECT name, price, frequency, cycle, currency_id, next_payment, payer_user_id, category_id, payment_method_id, inactive FROM subscriptions";
|
||||||
$result = $db->query($query);
|
$conditions = [];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
if (isset($_GET['member'])) {
|
||||||
|
$conditions[] = "payer_user_id = :member";
|
||||||
|
$params[':member'] = $_GET['member'];
|
||||||
|
$statsSubtitleParts[] = $members[$_GET['member']]['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['category'])) {
|
||||||
|
$conditions[] = "category_id = :category";
|
||||||
|
$params[':category'] = $_GET['category'];
|
||||||
|
$statsSubtitleParts[] = $categories[$_GET['category']]['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['payment'])) {
|
||||||
|
$conditions[] = "payment_method_id = :payment";
|
||||||
|
$params[':payment'] = $_GET['payment'];
|
||||||
|
$statsSubtitleParts[] = $paymentMethodCount[$_GET['payment']]['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($conditions)) {
|
||||||
|
$query .= " WHERE " . implode(' AND ', $conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $db->prepare($query);
|
||||||
|
$statsSubtitle = !empty($statsSubtitleParts) ? '(' . implode(', ', $statsSubtitleParts) . ')' : "";
|
||||||
|
|
||||||
|
foreach ($params as $key => $value) {
|
||||||
|
$stmt->bindValue($key, $value, SQLITE3_INTEGER);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $stmt->execute();
|
||||||
if ($result) {
|
if ($result) {
|
||||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||||
$subscriptions[] = $row;
|
$subscriptions[] = $row;
|
||||||
@ -160,7 +193,97 @@ if ($result) {
|
|||||||
$numberOfElements = 6;
|
$numberOfElements = 6;
|
||||||
?>
|
?>
|
||||||
<section class="contain">
|
<section class="contain">
|
||||||
<h2><?= translate('general_statistics', $i18n) ?></h2>
|
<div class="split-header">
|
||||||
|
<h2>
|
||||||
|
<?= translate('general_statistics', $i18n) ?> <span class="header-subtitle"><?= $statsSubtitle ?></span>
|
||||||
|
</h2>
|
||||||
|
<div class="filtermenu">
|
||||||
|
<button class="button" id="filtermenu-button">
|
||||||
|
<i class="fa-solid fa-filter"></i>
|
||||||
|
<?= translate("filter", $i18n) ?>
|
||||||
|
</button>
|
||||||
|
<div class="filtermenu-content">
|
||||||
|
<?php
|
||||||
|
if (count($members) > 1) {
|
||||||
|
?>
|
||||||
|
<div class="filtermenu-submenu">
|
||||||
|
<div class="filter-title" onClick="toggleSubMenu('member')"><?= translate("member", $i18n) ?></div>
|
||||||
|
<div class="filtermenu-submenu-content" id="filter-member">
|
||||||
|
<?php
|
||||||
|
foreach ($members as $member) {
|
||||||
|
$selectedClass = '';
|
||||||
|
if (isset($_GET['member']) && $_GET['member'] == $member['id']) {
|
||||||
|
$selectedClass = 'selected';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="filter-item <?= $selectedClass ?>" data-memberid="<?= $member['id'] ?>"><?= $member['name'] ?></div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
if (count($categories) > 1) {
|
||||||
|
?>
|
||||||
|
<div class="filtermenu-submenu">
|
||||||
|
<div class="filter-title" onClick="toggleSubMenu('category')"><?= translate("category", $i18n) ?></div>
|
||||||
|
<div class="filtermenu-submenu-content" id="filter-category">
|
||||||
|
<?php
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$selectedClass = '';
|
||||||
|
if (isset($_GET['category']) && $_GET['category'] == $category['id']) {
|
||||||
|
$selectedClass = 'selected';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="filter-item <?= $selectedClass ?>" data-categoryid="<?= $category['id'] ?>"><?= $category['name'] ?></div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
if (count($paymentMethodCount) > 1) {
|
||||||
|
?>
|
||||||
|
<div class="filtermenu-submenu">
|
||||||
|
<div class="filter-title" onClick="toggleSubMenu('payment')"><?= translate("payment_method", $i18n) ?></div>
|
||||||
|
<div class="filtermenu-submenu-content" id="filter-payment">
|
||||||
|
<?php
|
||||||
|
foreach ($paymentMethodCount as $payment) {
|
||||||
|
$selectedClass = '';
|
||||||
|
if (isset($_GET['payment']) && $_GET['payment'] == $payment['id']) {
|
||||||
|
$selectedClass = 'selected';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="filter-item <?= $selectedClass ?>" data-paymentid="<?= $payment['id'] ?>"><?= $payment['name'] ?></div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
if (isset($_GET['member']) || isset($_GET['category']) || isset($_GET['payment'])) {
|
||||||
|
?>
|
||||||
|
<div class="filtermenu-submenu">
|
||||||
|
<div class="filter-title filter-clear" onClick="clearFilters()">
|
||||||
|
<i class="fa-solid fa-times-circle"></i> <?= translate("clear", $i18n) ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="statistics">
|
<div class="statistics">
|
||||||
<div class="statistic">
|
<div class="statistic">
|
||||||
<span><?= $activeSubscriptions ?></span>
|
<span><?= $activeSubscriptions ?></span>
|
||||||
@ -208,86 +331,92 @@ $numberOfElements = 6;
|
|||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
<h2><?= translate('split_views', $i18n) ?></h2>
|
<?php
|
||||||
<div class="graphs">
|
$categoryDataPoints = [];
|
||||||
<?php
|
foreach ($categoryCost as $category) {
|
||||||
$categoryDataPoints = [];
|
if ($category['cost'] != 0) {
|
||||||
foreach ($categoryCost as $category) {
|
$categoryDataPoints[] = [
|
||||||
if ($category['cost'] != 0) {
|
"label" => $category['name'],
|
||||||
$categoryDataPoints[] = [
|
"y" => $category["cost"],
|
||||||
"label" => $category['name'],
|
];
|
||||||
"y" => $category["cost"],
|
}
|
||||||
];
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$showCategoryCostGraph = count($categoryDataPoints) > 1;
|
$showCategoryCostGraph = count($categoryDataPoints) > 1;
|
||||||
|
|
||||||
$memberDataPoints = [];
|
$memberDataPoints = [];
|
||||||
foreach ($memberCost as $member) {
|
foreach ($memberCost as $member) {
|
||||||
if ($member['cost'] != 0) {
|
if ($member['cost'] != 0) {
|
||||||
$memberDataPoints[] = [
|
$memberDataPoints[] = [
|
||||||
"label" => $member['name'],
|
"label" => $member['name'],
|
||||||
"y" => $member["cost"],
|
"y" => $member["cost"],
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$showMemberCostGraph = count($memberDataPoints) > 1;
|
$showMemberCostGraph = count($memberDataPoints) > 1;
|
||||||
|
|
||||||
$paymentMethodDataPoints = [];
|
$paymentMethodDataPoints = [];
|
||||||
foreach ($paymentMethodCount as $paymentMethod) {
|
foreach ($paymentMethodCount as $paymentMethod) {
|
||||||
if ($paymentMethod['count'] != 0) {
|
if ($paymentMethod['count'] != 0) {
|
||||||
$paymentMethodDataPoints[] = [
|
$paymentMethodDataPoints[] = [
|
||||||
"label" => $paymentMethod['name'],
|
"label" => $paymentMethod['name'],
|
||||||
"y" => $paymentMethod["count"],
|
"y" => $paymentMethod["count"],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$showPaymentMethodCountGraph = count($paymentMethodDataPoints) > 1;
|
|
||||||
|
|
||||||
if ($showMemberCostGraph) {
|
|
||||||
?>
|
|
||||||
<section class="graph">
|
|
||||||
<header>
|
|
||||||
<?= translate('household_split', $i18n) ?>
|
|
||||||
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
|
|
||||||
</header>
|
|
||||||
<canvas id="memberSplitChart"></canvas>
|
|
||||||
</section>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($showCategoryCostGraph) {
|
|
||||||
?>
|
|
||||||
<section class="graph">
|
|
||||||
<header>
|
|
||||||
<?= translate('category_split', $i18n) ?>
|
|
||||||
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
|
|
||||||
</header>
|
|
||||||
<canvas id="categorySplitChart" style="height: 370px; width: 100%;"></canvas>
|
|
||||||
</section>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($showPaymentMethodCountGraph) {
|
|
||||||
?>
|
|
||||||
<section class="graph">
|
|
||||||
<header>
|
|
||||||
<?= translate('payment_method_split', $i18n) ?>
|
|
||||||
</header>
|
|
||||||
<canvas id="paymentMethidSplitChart" style="height: 370px; width: 100%;"></canvas>
|
|
||||||
</section>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$showPaymentMethodCountGraph = count($paymentMethodDataPoints) > 1;
|
||||||
|
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodCountGraph) {
|
||||||
?>
|
?>
|
||||||
</div>
|
<h2><?= translate('split_views', $i18n) ?></h2>
|
||||||
|
<div class="graphs">
|
||||||
|
<?php
|
||||||
|
if ($showMemberCostGraph) {
|
||||||
|
?>
|
||||||
|
<section class="graph">
|
||||||
|
<header>
|
||||||
|
<?= translate('household_split', $i18n) ?>
|
||||||
|
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
|
||||||
|
</header>
|
||||||
|
<canvas id="memberSplitChart"></canvas>
|
||||||
|
</section>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($showCategoryCostGraph) {
|
||||||
|
?>
|
||||||
|
<section class="graph">
|
||||||
|
<header>
|
||||||
|
<?= translate('category_split', $i18n) ?>
|
||||||
|
<div class="sub-header">(<?= translate('monthly_cost', $i18n) ?>)</div>
|
||||||
|
</header>
|
||||||
|
<canvas id="categorySplitChart" style="height: 370px; width: 100%;"></canvas>
|
||||||
|
</section>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($showPaymentMethodCountGraph) {
|
||||||
|
?>
|
||||||
|
<section class="graph">
|
||||||
|
<header>
|
||||||
|
<?= translate('payment_method_split', $i18n) ?>
|
||||||
|
</header>
|
||||||
|
<canvas id="paymentMethidSplitChart" style="height: 370px; width: 100%;"></canvas>
|
||||||
|
</section>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<?php
|
<?php
|
||||||
if ($showCategoryCostGraph || $showMemberCostGraph) {
|
if ($showCategoryCostGraph || $showMemberCostGraph || $showPaymentMethodCountGraph) {
|
||||||
?>
|
?>
|
||||||
<script src="scripts/libs/chart.js"></script>
|
<script src="scripts/libs/chart.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|||||||
@ -11,15 +11,21 @@ header .logo .logo-image {
|
|||||||
background-image: url("../images/wallossolidwhite.png");
|
background-image: url("../images/wallossolidwhite.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.split-header > h2 .header-subtitle {
|
||||||
|
color: #A9A9A9;
|
||||||
|
}
|
||||||
|
|
||||||
.subscription,
|
.subscription,
|
||||||
.subscription-form,
|
.subscription-form,
|
||||||
.account-section,
|
.account-section,
|
||||||
.avatar-select,
|
.avatar-select,
|
||||||
.logo-search,
|
.logo-search,
|
||||||
|
.icon-search,
|
||||||
.dropdown-content,
|
.dropdown-content,
|
||||||
.sort-options,
|
.sort-options,
|
||||||
.statistic,
|
.statistic,
|
||||||
.graph {
|
.graph,
|
||||||
|
.filtermenu-content {
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
box-shadow: 0 2px 5px rgba(120, 120, 120, 0.1);
|
box-shadow: 0 2px 5px rgba(120, 120, 120, 0.1);
|
||||||
@ -37,6 +43,11 @@ header .logo .logo-image {
|
|||||||
background-color: #333333;
|
background-color: #333333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-item:hover,
|
||||||
|
.filtermenu-content .filter-title:hover {
|
||||||
|
background-color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
.subscription-form h3 {
|
.subscription-form h3 {
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
border-bottom: 1px solid #EEE;
|
border-bottom: 1px solid #EEE;
|
||||||
|
|||||||
@ -21,10 +21,34 @@ h2, h3 {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.split-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-header h2 {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split-header > h2 .header-subtitle {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666666;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.contain.settings {
|
.contain.settings {
|
||||||
padding: 20px 0px;
|
padding: 20px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.split-header > h2 .header-subtitle {
|
||||||
|
margin-left: 0px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body > header {
|
body > header {
|
||||||
@ -96,7 +120,7 @@ header .logo .logo-image {
|
|||||||
|
|
||||||
.dropdown-content a {
|
.dropdown-content a {
|
||||||
color: black;
|
color: black;
|
||||||
padding: 12px 16px;
|
padding: 14px 18px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -593,6 +617,10 @@ main > .contain {
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.payments-list .payments-payment > .payment-name {
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
|
||||||
.payments-list .payments-payment .delete-payment-method {
|
.payments-list .payments-payment .delete-payment-method {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -817,7 +845,7 @@ input[type="checkbox"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-search {
|
.icon-search {
|
||||||
width: 100px;
|
width: 112px;
|
||||||
height: 224px;
|
height: 224px;
|
||||||
top: 50px;
|
top: 50px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
@ -1047,7 +1075,7 @@ input[type="checkbox"] {
|
|||||||
|
|
||||||
.sort-options > ul > li {
|
.sort-options > ul > li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 10px 35px 10px 10px;
|
padding: 14px 35px 14px 18px;
|
||||||
border-bottom: 1px solid #DDD;
|
border-bottom: 1px solid #DDD;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -1283,4 +1311,122 @@ input[type="checkbox"] {
|
|||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings sort category */
|
||||||
|
|
||||||
|
.sortable-list {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag-icon {
|
||||||
|
width: 28px;
|
||||||
|
height: 50px;
|
||||||
|
cursor: grab;
|
||||||
|
background-image: url(../images/siteicons/draggable.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-size: 14px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable-list .sortable-ghost {
|
||||||
|
border-radius: 16px;
|
||||||
|
background-color: #c1d9f7;
|
||||||
|
border: 1px solid #8FBFFA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fitler dropdown */
|
||||||
|
|
||||||
|
.filtermenu {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
left: auto;
|
||||||
|
right: 0;
|
||||||
|
width: 220px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content.is-open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-title {
|
||||||
|
padding: 14px 18px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filtermenu-submenu:last-of-type .filter-title {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filtermenu-submenu:last-of-type .filter-item:first-of-type {
|
||||||
|
border-top: 1px solid #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filtermenu-submenu:last-of-type .filter-item:last-of-type {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-item {
|
||||||
|
padding: 14px 24px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid #DDD;
|
||||||
|
user-select: none;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-item.selected {
|
||||||
|
background-image: url(../images/siteicons/check.png);
|
||||||
|
background-size: 16px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center right 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-title.filter-clear {
|
||||||
|
color: #0056b3;
|
||||||
|
font-weight: normal;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-title.filter-clear > i {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-content .filter-item:hover,
|
||||||
|
.filtermenu-content .filter-title:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-submenu-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filtermenu-submenu-content.is-open {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user