Compare commits
10 Commits
ad86eb5b9c
...
5fff7c59eb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fff7c59eb | ||
|
|
7b509d2b3d | ||
|
|
65cc376dff | ||
|
|
b80ab4bdc6 | ||
|
|
27f84ff3d5 | ||
|
|
769f8a0587 | ||
|
|
80678acfa4 | ||
|
|
70e42349ca | ||
|
|
2c186b4818 | ||
|
|
16bc737d67 |
2
.tmp/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
36
CHANGELOG.md
@ -1,5 +1,41 @@
|
||||
# Changelog
|
||||
|
||||
## [1.23.0](https://github.com/ellite/Wallos/compare/v1.22.0...v1.23.0) (2024-04-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* backup and restore ([#288](https://github.com/ellite/Wallos/issues/288)) ([7b509d2](https://github.com/ellite/Wallos/commit/7b509d2b3d769e14a9cb4fd183395dcecc9d993b))
|
||||
|
||||
## [1.22.0](https://github.com/ellite/Wallos/compare/v1.21.1...v1.22.0) (2024-04-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* option to hide disabled subscriptions ([#286](https://github.com/ellite/Wallos/issues/286)) ([b80ab4b](https://github.com/ellite/Wallos/commit/b80ab4bdc662c3e80a2fd42b8b286b69beac441c))
|
||||
|
||||
## [1.21.1](https://github.com/ellite/Wallos/compare/v1.21.0...v1.21.1) (2024-04-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* small layout issues ([769f8a0](https://github.com/ellite/Wallos/commit/769f8a0587941bffd0d7463b7e7ffeb38a70e301))
|
||||
|
||||
## [1.21.0](https://github.com/ellite/Wallos/compare/v1.20.2...v1.21.0) (2024-04-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add italian translation ([70e4234](https://github.com/ellite/Wallos/commit/70e42349caee5d6647b6b704643fe2b5e26dff4e))
|
||||
* add themes and custom color options ([70e4234](https://github.com/ellite/Wallos/commit/70e42349caee5d6647b6b704643fe2b5e26dff4e))
|
||||
|
||||
## [1.20.2](https://github.com/ellite/Wallos/compare/v1.20.1...v1.20.2) (2024-04-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* encoding for url and notes ([#273](https://github.com/ellite/Wallos/issues/273)) ([ad86eb5](https://github.com/ellite/Wallos/commit/ad86eb5b9c6e60004de2795170032d62b33ddcfb))
|
||||
|
||||
## [1.20.1](https://github.com/ellite/Wallos/compare/v1.20.0...v1.20.1) (2024-04-09)
|
||||
|
||||
|
||||
|
||||
@ -6,11 +6,11 @@ WORKDIR /var/www/html
|
||||
|
||||
# Update packages and install dependencies
|
||||
RUN apk upgrade --no-cache && \
|
||||
apk add --no-cache sqlite-dev libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp icu-dev nginx dcron tzdata imagemagick imagemagick-dev && \
|
||||
apk add --no-cache sqlite-dev libpng libpng-dev libjpeg-turbo libjpeg-turbo-dev freetype freetype-dev curl autoconf libgomp icu-dev nginx dcron tzdata imagemagick imagemagick-dev libzip-dev && \
|
||||
docker-php-ext-install pdo pdo_sqlite && \
|
||||
docker-php-ext-enable pdo pdo_sqlite && \
|
||||
docker-php-ext-configure gd --with-freetype --with-jpeg && \
|
||||
docker-php-ext-install -j$(nproc) gd intl && \
|
||||
docker-php-ext-install -j$(nproc) gd intl zip && \
|
||||
apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && \
|
||||
pecl install imagick && \
|
||||
docker-php-ext-enable imagick && \
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./images/wallossolidwhite.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="./images/wallossolid.png">
|
||||
<img alt="Wallos" src="./images/wallossolid.png">
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./images/siteicons/blue/walloswhite.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="./images/siteicons/blue/wallos.png">
|
||||
<img alt="Wallos" src="./images/siteicons/blue/wallos.png">
|
||||
</picture>
|
||||
|
||||
Wallos: Open-Source Personal Subscription Tracker
|
||||
@ -61,6 +61,7 @@ See instructions to run Wallos below.
|
||||
- intl
|
||||
- openssl
|
||||
- sqlite3
|
||||
- zip
|
||||
|
||||
#### Docker
|
||||
|
||||
|
||||
71
endpoints/db/backup.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?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)
|
||||
]));
|
||||
}
|
||||
|
||||
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
|
||||
if (is_dir($dir)) {
|
||||
if ($dh = opendir($dir)) {
|
||||
//Add the directory
|
||||
if(!empty($zipdir)) $zipArchive->addEmptyDir($zipdir);
|
||||
while (($file = readdir($dh)) !== false) {
|
||||
// Skip '.' and '..'
|
||||
if ($file == "." || $file == "..") {
|
||||
continue;
|
||||
}
|
||||
//If it's a folder, run the function again!
|
||||
if(is_dir($dir . $file)){
|
||||
$newdir = $dir . $file . '/';
|
||||
addFolderToZip($newdir, $zipArchive, $zipdir . $file . '/');
|
||||
}else{
|
||||
//Add the files
|
||||
$zipArchive->addFile($dir . $file, $zipdir . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "Directory does not exist: $dir"
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$filename = "backup_" . uniqid() . ".zip";
|
||||
$zipname = "../../.tmp/" . $filename;
|
||||
|
||||
if ($zip->open($zipname, ZipArchive::CREATE)!==TRUE) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate('cannot_open_zip', $i18n)
|
||||
]));
|
||||
}
|
||||
|
||||
addFolderToZip('../../db/', $zip);
|
||||
addFolderToZip('../../images/uploads/', $zip);
|
||||
|
||||
$numberOfFilesAdded = $zip->numFiles;
|
||||
|
||||
if ($zip->close() === false) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "Failed to finalize the zip file"
|
||||
]));
|
||||
} else {
|
||||
flush();
|
||||
die(json_encode([
|
||||
"success" => true,
|
||||
"message" => "Zip file created successfully",
|
||||
"numFiles" => $numberOfFilesAdded,
|
||||
"file" => $filename
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
112
endpoints/db/import.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
require_once '../../includes/connect_endpoint.php';
|
||||
session_start();
|
||||
|
||||
$result = $db->query("SELECT COUNT(*) as count FROM user");
|
||||
$row = $result->fetchArray(SQLITE3_NUM);
|
||||
if ($row[0] > 0) {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "Denied"
|
||||
]));
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_FILES['file'])) {
|
||||
$file = $_FILES['file'];
|
||||
$fileTmpName = $file['tmp_name'];
|
||||
$fileError = $file['error'];
|
||||
|
||||
if ($fileError === 0) {
|
||||
$fileDestination = '../../.tmp/restore.zip';
|
||||
move_uploaded_file($fileTmpName, $fileDestination);
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($fileDestination) === true) {
|
||||
$zip->extractTo('../../.tmp/restore/');
|
||||
$zip->close();
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "Failed to extract the uploaded file"
|
||||
]));
|
||||
}
|
||||
|
||||
if (file_exists('../../.tmp/restore/wallos.db')) {
|
||||
if (file_exists('../../db/wallos.db')) {
|
||||
unlink('../../db/wallos.db');
|
||||
}
|
||||
rename('../../.tmp/restore/wallos.db', '../../db/wallos.db');
|
||||
|
||||
if (file_exists('../../.tmp/restore/logos/')) {
|
||||
$dir = '../../images/uploads/logos/';
|
||||
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
|
||||
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
foreach ( $ri as $file ) {
|
||||
if ( $file->isDir() ) {
|
||||
rmdir($file->getPathname());
|
||||
} else {
|
||||
unlink($file->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
$dir = new RecursiveDirectoryIterator('../../.tmp/restore/logos/');
|
||||
$ite = new RecursiveIteratorIterator($dir);
|
||||
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
|
||||
|
||||
foreach ($ite as $filePath) {
|
||||
if (in_array(pathinfo($filePath, PATHINFO_EXTENSION), $allowedExtensions)) {
|
||||
$destination = str_replace('../../.tmp/restore/', '../../images/uploads/', $filePath);
|
||||
$destinationDir = pathinfo($destination, PATHINFO_DIRNAME);
|
||||
|
||||
if (!is_dir($destinationDir)) {
|
||||
mkdir($destinationDir, 0755, true);
|
||||
}
|
||||
|
||||
copy($filePath, $destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator('../../.tmp', RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $fileinfo) {
|
||||
$removeFunction = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
|
||||
$removeFunction($fileinfo->getRealPath());
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => translate("success", $i18n)
|
||||
]);
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "wallos.db does not exist in the backup file"
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Failed to upload file"
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "No file uploaded"
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Invalid request method"
|
||||
]);
|
||||
}
|
||||
?>
|
||||
109
endpoints/db/restore.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?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 ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_FILES['file'])) {
|
||||
$file = $_FILES['file'];
|
||||
$fileTmpName = $file['tmp_name'];
|
||||
$fileError = $file['error'];
|
||||
|
||||
if ($fileError === 0) {
|
||||
$fileDestination = '../../.tmp/restore.zip';
|
||||
move_uploaded_file($fileTmpName, $fileDestination);
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($fileDestination) === true) {
|
||||
$zip->extractTo('../../.tmp/restore/');
|
||||
$zip->close();
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "Failed to extract the uploaded file"
|
||||
]));
|
||||
}
|
||||
|
||||
if (file_exists('../../.tmp/restore/wallos.db')) {
|
||||
if (file_exists('../../db/wallos.db')) {
|
||||
unlink('../../db/wallos.db');
|
||||
}
|
||||
rename('../../.tmp/restore/wallos.db', '../../db/wallos.db');
|
||||
|
||||
if (file_exists('../../.tmp/restore/logos/')) {
|
||||
$dir = '../../images/uploads/logos/';
|
||||
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
|
||||
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
foreach ( $ri as $file ) {
|
||||
if ( $file->isDir() ) {
|
||||
rmdir($file->getPathname());
|
||||
} else {
|
||||
unlink($file->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
$dir = new RecursiveDirectoryIterator('../../.tmp/restore/logos/');
|
||||
$ite = new RecursiveIteratorIterator($dir);
|
||||
$allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];
|
||||
|
||||
foreach ($ite as $filePath) {
|
||||
if (in_array(pathinfo($filePath, PATHINFO_EXTENSION), $allowedExtensions)) {
|
||||
$destination = str_replace('../../.tmp/restore/', '../../images/uploads/', $filePath);
|
||||
$destinationDir = pathinfo($destination, PATHINFO_DIRNAME);
|
||||
|
||||
if (!is_dir($destinationDir)) {
|
||||
mkdir($destinationDir, 0755, true);
|
||||
}
|
||||
|
||||
copy($filePath, $destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator('../../.tmp', RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $fileinfo) {
|
||||
$removeFunction = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
|
||||
$removeFunction($fileinfo->getRealPath());
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => translate("success", $i18n)
|
||||
]);
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => "wallos.db does not exist in the backup file"
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Failed to upload file"
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "No file uploaded"
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Invalid request method"
|
||||
]);
|
||||
}
|
||||
?>
|
||||
34
endpoints/settings/colortheme.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?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 ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$postData = file_get_contents("php://input");
|
||||
$data = json_decode($postData, true);
|
||||
|
||||
$color = $data['color'];
|
||||
|
||||
$stmt = $db->prepare('UPDATE settings SET color_theme = :color');
|
||||
$stmt->bindParam(':color', $color, SQLITE3_TEXT);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
die(json_encode([
|
||||
"success" => true,
|
||||
"message" => translate("success", $i18n)
|
||||
]));
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate("error", $i18n)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
41
endpoints/settings/customtheme.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 ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$postData = file_get_contents("php://input");
|
||||
$data = json_decode($postData, true);
|
||||
|
||||
$main_color = $data['mainColor'];
|
||||
$accent_color = $data['accentColor'];
|
||||
$hover_color = $data['hoverColor'];
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM custom_colors');
|
||||
$stmt->execute();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO custom_colors (main_color, accent_color, hover_color) VALUES (:main_color, :accent_color, :hover_color)');
|
||||
$stmt->bindParam(':main_color', $main_color, SQLITE3_TEXT);
|
||||
$stmt->bindParam(':accent_color', $accent_color, SQLITE3_TEXT);
|
||||
$stmt->bindParam(':hover_color', $hover_color, SQLITE3_TEXT);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
die(json_encode([
|
||||
"success" => true,
|
||||
"message" => translate("success", $i18n)
|
||||
]));
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate("error", $i18n)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
33
endpoints/settings/hide_disabled.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?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 ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$postData = file_get_contents("php://input");
|
||||
$data = json_decode($postData, true);
|
||||
|
||||
$hide_disabled = $data['value'];
|
||||
|
||||
$stmt = $db->prepare('UPDATE settings SET hide_disabled = :hide_disabled');
|
||||
$stmt->bindParam(':hide_disabled', $hide_disabled, SQLITE3_INTEGER);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
die(json_encode([
|
||||
"success" => true,
|
||||
"message" => translate("success", $i18n)
|
||||
]));
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate("error", $i18n)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
28
endpoints/settings/resettheme.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?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 ($_SERVER["REQUEST_METHOD"] === "DELETE") {
|
||||
$stmt = $db->prepare('DELETE FROM custom_colors');
|
||||
|
||||
if ($stmt->execute()) {
|
||||
die(json_encode([
|
||||
"success" => true,
|
||||
"message" => translate("success", $i18n)
|
||||
]));
|
||||
} else {
|
||||
die(json_encode([
|
||||
"success" => false,
|
||||
"message" => translate("error", $i18n)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -1,48 +0,0 @@
|
||||
<?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)
|
||||
]));
|
||||
}
|
||||
|
||||
require_once '../../includes/getdbkeys.php';
|
||||
|
||||
$query = "SELECT * FROM subscriptions";
|
||||
|
||||
$result = $db->query($query);
|
||||
if ($result) {
|
||||
$subscriptions = array();
|
||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||
// Map foreign keys to their corresponding values
|
||||
$row['currency'] = $currencies[$row['currency_id']];
|
||||
$row['payment_method'] = $payment_methods[$row['payment_method_id']];
|
||||
$row['payer_user'] = $members[$row['payer_user_id']];
|
||||
$row['category'] = $categories[$row['category_id']];
|
||||
$row['cycle'] = $cycles[$row['cycle']];
|
||||
$row['frequency'] = $frequencies[$row['frequency']];
|
||||
|
||||
$subscriptions[] = $row;
|
||||
}
|
||||
|
||||
// Output JSON
|
||||
$json = json_encode($subscriptions, JSON_PRETTY_PRINT);
|
||||
|
||||
// Set headers for file download
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Disposition: attachment; filename="subscriptions.json"');
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: 0');
|
||||
|
||||
// Output JSON for download
|
||||
echo $json;
|
||||
} else {
|
||||
echo json_encode(array('error' => 'Failed to fetch subscriptions.'));
|
||||
}
|
||||
|
||||
?>
|
||||
@ -14,6 +14,11 @@
|
||||
$theme = $settings['theme'];
|
||||
}
|
||||
|
||||
$colorTheme = "blue";
|
||||
if (isset($settings['color_theme'])) {
|
||||
$colorTheme = $settings['color_theme'];
|
||||
}
|
||||
|
||||
if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
|
||||
$sort = "next_payment";
|
||||
$order = "ASC";
|
||||
@ -63,8 +68,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
$defaultLogo = $theme == "light" ? "images/wallos.png" : "images/walloswhite.png";
|
||||
$defaultLogo = $theme == "light" ? "images/siteicons/" . $colorTheme . "/wallos.png" : "images/siteicons/" . $colorTheme . "/walloswhite.png";
|
||||
foreach ($subscriptions as $subscription) {
|
||||
if ($subscription['inactive'] == 1 && isset($settings['hideDisabledSubscriptions']) && $settings['hideDisabledSubscriptions'] === 'true') {
|
||||
continue;
|
||||
}
|
||||
$id = $subscription['id'];
|
||||
$print[$id]['id'] = $id;
|
||||
$print[$id]['logo'] = $subscription['logo'] != "" ? "images/uploads/logos/".$subscription['logo'] : $defaultLogo;
|
||||
@ -97,7 +105,7 @@
|
||||
}
|
||||
|
||||
if (isset($print)) {
|
||||
printSubscriptions($print, $sort, $categories, $members, $i18n);
|
||||
printSubscriptions($print, $sort, $categories, $members, $i18n, $colorTheme);
|
||||
}
|
||||
|
||||
if (count($subscriptions) == 0) {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
BIN
images/siteicons/blue/check.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 846 B After Width: | Height: | Size: 846 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
images/siteicons/blue/wallos.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
images/siteicons/blue/walloswhite.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
BIN
images/siteicons/green/category.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
images/siteicons/green/check.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
images/siteicons/green/delete.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
images/siteicons/green/edit.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
images/siteicons/green/notes.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
images/siteicons/green/payment.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
images/siteicons/green/save.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
images/siteicons/green/subscription.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
images/siteicons/green/wallos.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
images/siteicons/green/walloswhite.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
images/siteicons/green/web.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
images/siteicons/green/websearch.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
images/siteicons/red/category.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
images/siteicons/red/check.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
images/siteicons/red/delete.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
images/siteicons/red/edit.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
images/siteicons/red/notes.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
images/siteicons/red/payment.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
images/siteicons/red/save.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
images/siteicons/red/subscription.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
images/siteicons/red/wallos.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
images/siteicons/red/walloswhite.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
images/siteicons/red/web.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
images/siteicons/red/websearch.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
images/siteicons/yellow/category.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
images/siteicons/yellow/check.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
images/siteicons/yellow/delete.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
images/siteicons/yellow/edit.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
images/siteicons/yellow/notes.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
images/siteicons/yellow/payment.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
images/siteicons/yellow/save.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
images/siteicons/yellow/subscription.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
images/siteicons/yellow/wallos.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
images/siteicons/yellow/walloswhite.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
images/siteicons/yellow/web.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
images/siteicons/yellow/websearch.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
@ -8,6 +8,12 @@
|
||||
$stmt->bindValue(':username', $username, SQLITE3_TEXT);
|
||||
$result = $stmt->execute();
|
||||
$userData = $result->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
if ($userData === false) {
|
||||
header('Location: logout.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($userData['avatar'] == "") {
|
||||
$userData['avatar'] = "0";
|
||||
}
|
||||
|
||||
@ -24,5 +24,11 @@
|
||||
<div class="progress success"></div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (isset($db)) {
|
||||
$db->close();
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -7,9 +7,19 @@ if ($settings) {
|
||||
$cookieExpire = time() + (30 * 24 * 60 * 60);
|
||||
setcookie('theme', $settings['dark_theme'] ? 'dark': 'light', $cookieExpire);
|
||||
$settings['theme'] = $settings['dark_theme'] ? 'dark': 'light';
|
||||
$settings['color_theme'] = $settings['color_theme'] ? $settings['color_theme'] : "blue";
|
||||
$settings['showMonthlyPrice'] = $settings['monthly_price'] ? 'true': 'false';
|
||||
$settings['convertCurrency'] = $settings['convert_currency'] ? 'true': 'false';
|
||||
$settings['removeBackground'] = $settings['remove_background'] ? 'true': 'false';
|
||||
$settings['hideDisabledSubscriptions'] = $settings['hide_disabled'] ? 'true': 'false';
|
||||
}
|
||||
|
||||
$query = "SELECT * FROM custom_colors";
|
||||
$result = $db->query($query);
|
||||
$customColors = $result->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
if ($customColors) {
|
||||
$settings['customColors'] = $customColors;
|
||||
}
|
||||
|
||||
?>
|
||||
@ -23,6 +23,10 @@
|
||||
$theme = $settings['theme'];
|
||||
}
|
||||
|
||||
$colorTheme = "blue";
|
||||
if (isset($settings['color_theme'])) {
|
||||
$colorTheme = $settings['color_theme'];
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -34,8 +38,12 @@
|
||||
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
|
||||
<link rel="manifest" href="manifest.json" crossorigin="use-credentials">
|
||||
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
|
||||
<link rel="stylesheet" href="styles/styles.css?<?= $version ?>">
|
||||
<link rel="stylesheet" href="styles/dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/barlow.css">
|
||||
<link rel="stylesheet" href="styles/font-awesome.min.css">
|
||||
<script type="text/javascript" src="scripts/all.js?<?= $version ?>"></script>
|
||||
@ -43,11 +51,31 @@
|
||||
<script type="text/javascript">
|
||||
window.theme = "<?= $theme ?>";
|
||||
window.lang = "<?=$lang ?>";
|
||||
window.colorTheme = "<?= $colorTheme ?>";
|
||||
</script>
|
||||
<?php
|
||||
if (isset($settings['customColors'])) {
|
||||
?>
|
||||
<style id="custom_theme_colors">
|
||||
:root {
|
||||
<?php if (isset($settings['customColors']['main_color']) && !empty($settings['customColors']['main_color'])): ?>
|
||||
--main-color: <?= $settings['customColors']['main_color'] ?>;
|
||||
<?php endif; ?>
|
||||
<?php if (isset($settings['customColors']['accent_color']) && !empty($settings['customColors']['accent_color'])): ?>
|
||||
--accent-color: <?= $settings['customColors']['accent_color'] ?>;
|
||||
<?php endif; ?>
|
||||
<?php if (isset($settings['customColors']['hover_color']) && !empty($settings['customColors']['hover_color'])): ?>
|
||||
--hover-color: <?= $settings['customColors']['hover_color'] ?>;
|
||||
<?php endif; ?>
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript" src="scripts/i18n/<?= $lang ?>.js?<?= $version ?>"></script>
|
||||
<script type="text/javascript" src="scripts/i18n/getlang.js?<?= $version ?>"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="<?= $theme ?>">
|
||||
<header>
|
||||
<div class="contain">
|
||||
<div class="logo">
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Die Passwörter stimmen nicht überein",
|
||||
"registration_failed" => "Registrierung fehlgeschlagen, bitte erneut versuchen.",
|
||||
"register" => "Registrieren",
|
||||
"restore_database" => "Datenbank wiederherstellen",
|
||||
// Login Page
|
||||
'please_login' => "Bitte einloggen",
|
||||
'stay_logged_in' => "Angemeldet bleiben (30 Tage)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Erhalte deinen kostenfreien Fixer API Key",
|
||||
"get_key_alternative" => "Alternativ können Sie einen kostenlosen Fixer-Api-Schlüssel erhalten von",
|
||||
"display_settings" => "Display-Einstellungen",
|
||||
"theme_settings" => "Themen-Einstellungen",
|
||||
"custom_colors" => "Benutzerdefinierte Farben",
|
||||
"dark_theme" => "Dark Theme",
|
||||
"switch_theme" => "Light / Dark Theme umschalten",
|
||||
"calculate_monthly_price" => "Berechne und zeige monatlichen Preis für alle Abonnements an",
|
||||
"convert_prices" => "Preise immer in meine Hauptwährung umrechnen und darin anzeigen (langsamer)",
|
||||
"hide_disabled_subscriptions" => "Deaktivierte Abonnements verstecken",
|
||||
"experimental_settings" => "Experimentelle Einstellungen",
|
||||
"remove_background" => "Versuchen den Hintergrund von Logos aus der Bildersuche zu entfernen (experimentell)",
|
||||
"experimental_info" => "Experimentelle Einstellungen funktionieren möglicherweise nicht perfekt.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Test",
|
||||
"add" => "Hinzufügen",
|
||||
"save" => "Speichern",
|
||||
"export_subscriptions" => "Abonnements exportieren",
|
||||
"export_to_json" => "Nach JSON exportieren",
|
||||
"reset" => "Zurücksetzen",
|
||||
"backup_and_restore" => "Backup und Wiederherstellung",
|
||||
"backup" => "Backup",
|
||||
"restore" => "Wiederherstellen",
|
||||
"restore_info" => "Durch die Wiederherstellung der Datenbank werden alle aktuellen Daten überschrieben. Nach der Wiederherstellung werden Sie abgemeldet.",
|
||||
// Filters menu
|
||||
"filter" => "Filter",
|
||||
"clear" => "Leeren",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Οι κωδικοί πρόσβασης δεν ταιριάζουν",
|
||||
"registration_failed" => "Η εγγραφή απέτυχε, παρακαλώ προσπάθησε ξανά.",
|
||||
"register" => "Εγγραφή",
|
||||
"restore_database" => "Επαναφορά βάσης δεδομένων",
|
||||
// Login Page
|
||||
'please_login' => "Παρακαλώ συνδέσου",
|
||||
'stay_logged_in' => "Μείνε συνδεδεμένος (30 ημέρες)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Απόκτησε ΔΩΡΕΑΝ Fixer API κλειδί",
|
||||
"get_key_alternative" => "Εναλλακτικά, μπορείτε να λάβετε ένα δωρεάν κλειδί api fixer από το",
|
||||
"display_settings" => "Ρυθμίσεις εμφάνισης",
|
||||
"theme_settings" => "Ρυθμίσεις θέματος",
|
||||
"custom_colors" => "Προσαρμοσμένα χρώματα",
|
||||
"dark_theme" => "Dark Theme",
|
||||
"switch_theme" => "Διακόπτης Light / Dark Theme",
|
||||
"calculate_monthly_price" => "Υπολογισμός και εμφάνιση της μηνιαίας τιμής για όλες τις συνδρομές",
|
||||
"convert_prices" => "Πάντα να μετατρέπει και να εμφανίζει τις τιμές στο κύριο νόμισμά μου (πιο αργό)",
|
||||
"hide_disabled_subscriptions" => "Απόκρυψη απενεργοποιημένων συνδρομών",
|
||||
"experimental_settings" => "Πειραματικές ρυθμίσεις",
|
||||
"remove_background" => "Προσπάθεια αφαίρεσης του φόντου των λογότυπων από την αναζήτηση εικόνας (πειραματικά)",
|
||||
"experimental_info" => "Οι πειραματικές ρυθμίσεις πιθανότατα δεν θα λειτουργούν τέλεια.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Δοκιμή",
|
||||
"add" => "Προσθήκη",
|
||||
"save" => "Αποθήκευση",
|
||||
"export_subscriptions" => "Εξαγωγή συνδρομών",
|
||||
"export_to_json" => "Εξαγωγή σε JSON",
|
||||
"reset" => "Επαναφορά",
|
||||
"backup_and_restore" => "Αντίγραφο ασφαλείας και επαναφορά",
|
||||
"backup" => "Αντίγραφο ασφαλείας",
|
||||
"restore" => "Επαναφορά",
|
||||
"restore_info" => "Η επαναφορά της βάσης δεδομένων θα ακυρώσει όλα τα τρέχοντα δεδομένα. Μετά την επαναφορά θα αποσυνδεθείτε.",
|
||||
// Filters menu
|
||||
"filter" => "Φίλτρο",
|
||||
"clear" => "Καθαρισμός",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Passwords do not match",
|
||||
"registration_failed" => "Registration failed, please try again.",
|
||||
"register" => "Register",
|
||||
"restore_database" => "Restore Database",
|
||||
// Login Page
|
||||
'please_login' => "Please login",
|
||||
'stay_logged_in' => "Stay logged in (30 days)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Get free Fixer API Key",
|
||||
"get_key_alternative" => "Alternatively, you can get a free fixer api key from",
|
||||
"display_settings" => "Display Settings",
|
||||
"theme_settings" => "Theme Settings",
|
||||
"custom_colors" => "Custom Colors",
|
||||
"dark_theme" => "Dark Theme",
|
||||
"switch_theme" => "Switch Light / Dark Theme",
|
||||
"calculate_monthly_price" => "Calculate and show monthly price for all subscriptions",
|
||||
"convert_prices" => "Always convert and show prices on my main currency (slower)",
|
||||
"hide_disabled_subscriptions" => "Hide disabled subscriptions",
|
||||
"experimental_settings" => "Experimental Settings",
|
||||
"remove_background" => "Attempt to remove background of logos from image search (experimental)",
|
||||
"experimental_info" => "Experimental settings will probably not work perfectly.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Test",
|
||||
"add" => "Add",
|
||||
"save" => "Save",
|
||||
"export_subscriptions" => "Export Subscriptions",
|
||||
"export_to_json" => "Export to JSON",
|
||||
"reset" => "Reset",
|
||||
"backup_and_restore" => "Backup and Restore",
|
||||
"backup" => "Backup",
|
||||
"restore" => "Restore",
|
||||
"restore_info" => "Restoring the database will override all current data. You will be signed out after the restore.",
|
||||
// Filters menu
|
||||
"filter" => "Filter",
|
||||
"clear" => "Clear",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Las contraseñas no coinciden",
|
||||
"registration_failed" => "Error en el registro, por favor inténtalo de nuevo.",
|
||||
"register" => "Registrar",
|
||||
"restore_database" => "Restaurar Base de Datos",
|
||||
// Login Page
|
||||
'please_login' => "Por favor, inicia sesión",
|
||||
'stay_logged_in' => "Mantener sesión iniciada (30 días)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Obtén una API Key de Fixer gratuita",
|
||||
"get_key_alternative" => "También puede obtener una clave api gratuita de Fixer en",
|
||||
"display_settings" => "Configuración de Pantalla",
|
||||
"theme_settings" => "Configuración de Tema",
|
||||
"custom_collors" => "Colores Personalizados",
|
||||
"dark_theme" => "Tema Oscuro",
|
||||
"switch_theme" => "Cambiar entre Tema Claro / Oscuro",
|
||||
"calculate_monthly_price" => "Calcular y mostrar el precio mensual de todas las suscripciones",
|
||||
"convert_prices" => "Convertir y mostrar siempre los precios en mi moneda principal (más lento)",
|
||||
"hide_disabled_subscriptions" => "Ocultar suscripciones desactivadas",
|
||||
"experimental_settings" => "Configuraciones Experimentales",
|
||||
"remove_background" => "Intentar quitar el fondo de los logotipos de la búsqueda de imágenes (experimental)",
|
||||
"experimental_info" => "Las configuraciones experimentales probablemente no funcionarán perfectamente.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Probar",
|
||||
"add" => "Agregar",
|
||||
"save" => "Guardar",
|
||||
"export_subscriptions" => "Exportar suscripciones",
|
||||
"export_to_json" => "Exportar a JSON",
|
||||
"reset" => "Restablecer",
|
||||
"backup_and_restore" => "Copia de Seguridad y Restauración",
|
||||
"backup" => "Copia de Seguridad",
|
||||
"restore" => "Restaurar",
|
||||
"restore_info" => "La restauración de la base de datos anulará todos los datos actuales. Se cerrará la sesión después de la restauración.",
|
||||
// Filters menu
|
||||
"filter" => "Filtrar",
|
||||
"clear" => "Limpiar",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Les mots de passe ne correspondent pas",
|
||||
"registration_failed" => "L'inscription a échoué, veuillez réessayer.",
|
||||
"register" => "S'inscrire",
|
||||
"restore_database" => "Restaurer la base de données",
|
||||
// Page de connexion
|
||||
'please_login' => "Veuillez vous connecter",
|
||||
'stay_logged_in' => "Rester connecté (30 jours)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Obtenez une clé API Fixer gratuite",
|
||||
"get_key_alternative" => "Vous pouvez également obtenir une clé api de fixation gratuite auprès de",
|
||||
"display_settings" => "Paramètres d'affichage",
|
||||
"theme_settings" => "Paramètres de thème",
|
||||
"custom_colors" => "Couleurs personnalisées",
|
||||
"dark_theme" => "Thème sombre",
|
||||
"switch_theme" => "Basculer entre le thème clair et sombre",
|
||||
"calculate_monthly_price" => "Calculer et afficher le prix mensuel pour tous les abonnements",
|
||||
"convert_prices" => "Convertir toujours et afficher les prix dans ma devise principale (plus lent)",
|
||||
"hide_disabled_subscriptions" => "Masquer les abonnements désactivés",
|
||||
"experimental_settings" => "Paramètres expérimentaux",
|
||||
"remove_background" => "Tenter de supprimer l'arrière-plan des logos de la recherche d'images (expérimental)",
|
||||
"experimental_info" => "Les paramètres expérimentaux ne fonctionneront probablement pas parfaitement.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Test",
|
||||
"add" => "Ajouter",
|
||||
"save" => "Enregistrer",
|
||||
"export_subscriptions" => "Exporter les abonnements",
|
||||
"export_to_json" => "Exporter en JSON",
|
||||
"reset" => "Réinitialiser",
|
||||
"backup_and_restore" => "Sauvegarde et restauration",
|
||||
"backup" => "Sauvegarde",
|
||||
"restore" => "Restauration",
|
||||
"restore_info" => "La restauration de la base de données annulera toutes les données actuelles. Vous serez déconnecté après la restauration.",
|
||||
// Menu des filtes
|
||||
"filter" => "Filtre",
|
||||
"clear" => "Effacer",
|
||||
|
||||
198
includes/i18n/it.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
$i18n = [
|
||||
// Registration
|
||||
'create_account' => 'Devi creare un account prima di poter accedere',
|
||||
'username' => 'Nome utente',
|
||||
'password' => 'Password',
|
||||
'email' => 'Email',
|
||||
'confirm_password' => 'Conferma password',
|
||||
'main_currency' => 'Valuta principale',
|
||||
'language' => 'Lingua',
|
||||
'passwords_dont_match' => 'Le password non corrispondono',
|
||||
'registration_failed' => 'Registrazione fallita, riprova.',
|
||||
'register' => 'Registrati',
|
||||
"restore_database" => 'Ripristina database',
|
||||
|
||||
// Login
|
||||
'please_login' => 'Per favore, accedi',
|
||||
'stay_logged_in' => 'Rimani connesso (30 giorni)',
|
||||
'login' => 'Accedi',
|
||||
'login_failed' => 'Le credenziali non sono corrette',
|
||||
|
||||
// Header
|
||||
'subscriptions' => 'Abbonamenti',
|
||||
'stats' => 'Statistiche',
|
||||
'settings' => 'Impostazioni',
|
||||
'about' => 'Informazioni',
|
||||
'logout' => 'Esci',
|
||||
|
||||
// Subscriptions
|
||||
'subscription' => 'Abbonamento',
|
||||
'no_subscriptions_yet' => 'Non hai ancora nessun abbonamento',
|
||||
'add_first_subscription' => 'Aggiungo il tuo primo abbonamento',
|
||||
'new_subscription' => 'Nuovo abbonamento',
|
||||
'search' => 'Cerca',
|
||||
'sort' => 'Ordina',
|
||||
'name' => 'Nome',
|
||||
'last_added' => 'Ultimo aggiunto',
|
||||
'price' => 'Prezzo',
|
||||
'next_payment' => 'Prossimo pagamento',
|
||||
'inactive' => 'Disattiva abbonamento',
|
||||
'member' => 'Membro',
|
||||
'category' => 'Categoria',
|
||||
'payment_method' => 'Metodo di pagamento',
|
||||
'Daily' => 'Quotidiano',
|
||||
'Weekly' => 'Settimanale',
|
||||
'Monthly' => 'Mensile',
|
||||
'Yearly' => 'Annuale',
|
||||
'daily' => 'Giorno/i',
|
||||
'weekly' => 'Settimana/e',
|
||||
'monthly' => 'Mese/i',
|
||||
'yearly' => 'Anno/i',
|
||||
'days' => 'giorni',
|
||||
'weeks' => 'settimane',
|
||||
'months' => 'mesi',
|
||||
'years' => 'anni',
|
||||
'external_url' => 'Apri URL esterno',
|
||||
'empty_page' => 'Pagina vuota',
|
||||
'clear_filters' => 'Pulisci filtri',
|
||||
'no_matching_subscriptions' => 'Nessun abbonamento corrispondente',
|
||||
|
||||
// Add/Edit Subscription
|
||||
'add_subscription' => 'Aggiungi abbonamento',
|
||||
'edit_subscription' => 'Modifica abbonamento',
|
||||
'subscription_name' => 'Nome abbonamento',
|
||||
'logo_preview' => 'Anteprima del logo',
|
||||
'search_logo' => 'Cerca il logo sul web',
|
||||
'web_search' => 'Ricerca web',
|
||||
'currency' => 'Valuta',
|
||||
'payment_every' => 'Pagamento ogni',
|
||||
'frequency' => 'Frequenza',
|
||||
'cycle' => 'Ciclo',
|
||||
'no_category' => 'Nessuna categoria',
|
||||
'paid_by' => 'Pagato da',
|
||||
'url' => 'URL',
|
||||
'notes' => 'Note',
|
||||
'enable_notifications' => 'Abilita notifiche per questo abbonamento',
|
||||
'delete' => 'Cancella',
|
||||
'cancel' => 'Annulla',
|
||||
'upload_logo' => 'Carica logo',
|
||||
|
||||
// Statistics
|
||||
'general_statistics' => 'Statistiche generali',
|
||||
'active_subscriptions' => 'Abbonamenti attivi',
|
||||
'inactive_subscriptions' => 'Abbonamenti inattivi',
|
||||
'monthly_cost' => 'Costo mensile',
|
||||
'yearly_cost' => 'Costo annuale',
|
||||
'average_monthly' => "Costo medio mensile dell'abbonamento",
|
||||
'most_expensive' => "Costo dell'abbonamento più elevato",
|
||||
'amount_due' => 'Importo dovuto questo mese',
|
||||
'monthly_savings' => 'Risparmi mensili (su abbonamenti inattivi)',
|
||||
'split_views' => 'Visualizzazioni con grafici',
|
||||
'category_split' => 'Suddivisione per categoria',
|
||||
'household_split' => 'Suddivisione per nucleo familiare',
|
||||
'payment_method_split' => 'Suddivisione per metodo di pagamento',
|
||||
|
||||
// About
|
||||
'about_and_credits' => 'Informazioni e crediti',
|
||||
'license' => 'Licenza',
|
||||
'issues_and_requests' => 'Problemi e richieste',
|
||||
'the_author' => "L'autore",
|
||||
'icons' => 'Icone',
|
||||
'payment_icons' => 'Icone di pagamento',
|
||||
|
||||
// Settings
|
||||
'upload_avatar' => 'Carica avatar',
|
||||
'file_type_error' => 'Il tipo di file fornito non è supportato.',
|
||||
'user_details' => 'Dettagli utente',
|
||||
'household' => 'Nucleo familiare',
|
||||
'save_member' => 'Salva membro',
|
||||
'delete_member' => 'Elimina membro',
|
||||
'cant_delete_member' => 'Non è possibile eliminare il membro principale',
|
||||
'cant_delete_member_in_use' => 'Non è possibile eliminare un membro che utilizza almeno un abbonamento',
|
||||
'household_info' => 'Il campo e-mail consente ai membri del nucleo familiare di essere avvisati degli abbonamenti in procinto di scadere.',
|
||||
'notifications' => 'Notifiche',
|
||||
'enable_email_notifications' => 'Abilita le notifiche via e-mail',
|
||||
'notify_me' => 'Avvisami',
|
||||
'day_before' => 'giorno prima',
|
||||
'days_before' => 'giorni prima',
|
||||
'smtp_address' => 'Indirizzo SMTP',
|
||||
'port' => 'Porta',
|
||||
'tls' => 'TLS',
|
||||
'ssl' => 'SSL',
|
||||
'smtp_username' => 'Nome utente SMTP',
|
||||
'smtp_password' => 'Password SMTP',
|
||||
'from_email' => 'Da quale e-mail (Opzionale)',
|
||||
'smtp_info' => 'La password SMTP viene memorizzata e trasmessa in chiaro. Per motivi di sicurezza, si prega di creare un account da utilizzare solo per questo.',
|
||||
'categories' => 'Categorie',
|
||||
'save_category' => 'Salva categoria',
|
||||
'delete_category' => 'Elimina categoria',
|
||||
'cant_delete_category_in_use' => 'Non è possibile eliminare una categoria in uso da almeno un abbonamento',
|
||||
'currencies' => 'Valute',
|
||||
'save_currency' => 'Salva valuta',
|
||||
'delete_currency' => 'Elimina valuta',
|
||||
'cant_delete_main_currency' => 'Impossibile eliminare la valuta principale',
|
||||
'cant_delete_currency_in_use' => 'Non è possibile eliminare la valuta in uso da almeno un abbonamento',
|
||||
'exchange_update' => "Tassi di cambio aggiornati l'ultima volta il",
|
||||
'currency_info' => 'Trova le valute supportate e i codici valuta corretti su',
|
||||
'currency_performance' => 'Per garantire prestazioni migliori, tieni solo le valute che utilizzi.',
|
||||
'fixer_api_key' => 'Chiave API di Fixer',
|
||||
'api_key' => 'Chiave API',
|
||||
'provider' => 'Fornitore',
|
||||
'fixer_info' => 'Se utilizzi più valute e desideri visualizzare statistiche e ordinamenti accurati sugli abbonamenti, è necessaria una chiave API (Gratuita) da Fixer.',
|
||||
'get_key' => 'Ottieni la tua chiave su',
|
||||
'get_free_fixer_api_key' => 'Ottieni gratuitamente la chiave API di Fixer',
|
||||
'get_key_alternative' => 'In alternativa, puoi ottenere gratuitamente una chiave API di Fixer da',
|
||||
'display_settings' => 'Impostazioni di visualizzazione',
|
||||
"theme_settings" => 'Impostazioni del tema',
|
||||
"custom_colors" => 'Colori personalizzati',
|
||||
"dark_theme" => 'Tema scuro',
|
||||
'switch_theme' => 'Cambia tema chiaro/scuro',
|
||||
'calculate_monthly_price' => 'Calcola e mostra il prezzo mensile per tutti gli abbonamenti',
|
||||
'convert_prices' => 'Converti sempre e mostra i prezzi nella mia valuta principale (più lento)',
|
||||
"hide_disabled_subscriptions" => 'Nascondi gli abbonamenti disattivati',
|
||||
'experimental_settings' => 'Impostazioni sperimentali',
|
||||
'remove_background' => 'Prova a rimuovere lo sfondo dei loghi dalla ricerca delle immagini (sperimentale)',
|
||||
'experimental_info' => 'Le impostazioni sperimentali potrebbero non funzioneranno perfettamente.',
|
||||
'payment_methods' => 'Metodi di pagamento',
|
||||
'payment_methods_info' => 'Fai clic su un metodo di pagamento per abilitarlo/disabilitarlo.',
|
||||
'rename_payment_methods_info' => 'Fai clic sul nome di un metodo di pagamento per rinominarlo.',
|
||||
'cant_delete_payment_method_in_use' => 'Non è possibile disabilitare un metodo di pagamento in uso',
|
||||
'add_custom_payment' => 'Aggiungi metodo di pagamento personalizzato',
|
||||
'payment_method_name' => 'Nome del metodo di pagamento',
|
||||
'payment_method_added_successfuly' => 'Metodo di pagamento aggiunto con successo',
|
||||
'payment_method_removed' => 'Metodo di pagamento rimosso',
|
||||
'disable' => 'Disabilita',
|
||||
'enable' => 'Abilita',
|
||||
'rename_payment_method' => 'Rinomina metodo di pagamento',
|
||||
'payment_renamed' => 'Metodo di pagamento rinominato',
|
||||
'payment_not_renamed' => 'Metodo di pagamento non rinominato',
|
||||
'test' => 'Test',
|
||||
'add' => 'Aggiungi',
|
||||
'save' => 'Salva',
|
||||
"reset" => 'Ripristina',
|
||||
"backup_and_restore" => 'Backup e ripristino',
|
||||
"backup" => 'Backup',
|
||||
"restore" => 'Ripristina',
|
||||
"restore_info" => "Il ripristino del database annullerà tutti i dati correnti. Al termine del ripristino, l'utente verrà disconnesso.",
|
||||
// Filters
|
||||
'filter' => 'Filtra',
|
||||
'clear' => 'Pulisci',
|
||||
|
||||
// Toast
|
||||
'success' => 'Successo',
|
||||
|
||||
// Endpoint responses
|
||||
'session_expired' => 'La tua sessione è scaduta. Effettua nuovamente il login',
|
||||
'fields_missing' => 'Mancano alcuni campi',
|
||||
'fill_all_fields' => 'Si prega di compilare tutti i campi',
|
||||
'fill_mandatory_fields' => 'Si prega di compilare tutti i campi obbligatori',
|
||||
'error' => 'Errore',
|
||||
|
||||
// Category
|
||||
'failed_add_category' => 'Impossibile aggiungere la categoria',
|
||||
'failed_edit_category' => 'Impossibile modificare la categoria',
|
||||
];
|
||||
|
||||
?>
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "パスワードが違います",
|
||||
"registration_failed" => "登録に失敗しました。もう一度お試しください。",
|
||||
"register" => "登録する",
|
||||
"restore_database" => "データベースをリストア",
|
||||
// Login Page
|
||||
'please_login' => "ログインしてください",
|
||||
'stay_logged_in' => "ログインしたままにする (30日)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "無料のFixer APIキーを取得",
|
||||
"get_key_alternative" => "または、以下のサイトから無料のフィクサーapiキーを入手することもできます。",
|
||||
"display_settings" => "表示設定",
|
||||
"theme_settings" => "テーマ設定",
|
||||
"custom_colors" => "カスタムカラー",
|
||||
"dark_theme" => "ダークテーマ",
|
||||
"switch_theme" => "ライト/ダーク テーマの切り替え",
|
||||
"calculate_monthly_price" => "すべての定期購入の月額料金を計算して表示する",
|
||||
"convert_prices" => "常にメイン通貨で価格を換算して表示する (遅い)",
|
||||
"hide_disabled_subscriptions" => "無効な定期購入を非表示にする",
|
||||
"experimental_settings" => "実験的な設定",
|
||||
"remove_background" => "画像検索からロゴの背景を削除する (実験)",
|
||||
"experimental_info" => "実験的な設定は、おそらく完全には機能しません。",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "テスト",
|
||||
"add" => "追加",
|
||||
"save" => "保存",
|
||||
"export_subscriptions" => "購読をエクスポート",
|
||||
"export_to_json" => "JSONにエクスポート",
|
||||
"reset" => "リセット",
|
||||
"backup_and_restore" => "バックアップとリストア",
|
||||
"backup" => "バックアップ",
|
||||
"restore" => "リストア",
|
||||
"restore_info" => "データベースをリストアすると、現在のデータがすべて上書きされます。リストア後はサインアウトされます。",
|
||||
// Filters menu
|
||||
"filter" => "フィルタ",
|
||||
"clear" => "クリア",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
// File Name => Language Name
|
||||
|
||||
// File Name => Language Name
|
||||
$languages = [
|
||||
// English first
|
||||
"en" => "English",
|
||||
@ -9,12 +9,13 @@
|
||||
"el" => "Ελληνικά",
|
||||
"es" => "Español",
|
||||
"fr" => "Français",
|
||||
"it" => "Italiano",
|
||||
"jp" => "日本語",
|
||||
"pl" => "Polski",
|
||||
"pl" => "Polski",
|
||||
"pt" => "Português",
|
||||
"pt_br" => "Português Brasileiro",
|
||||
"sr" => "Српски",
|
||||
"sr_lat" => "Srpski",
|
||||
"sr_lat" => "Srpski",
|
||||
"sr" => "Српски",
|
||||
"tr" => "Türkçe",
|
||||
"zh_cn" => "简体中文",
|
||||
"zh_tw" => "繁體中文",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Hasła nie pasują",
|
||||
"registration_failed" => "Rejestracja nie powiodła się, spróbuj ponownie.",
|
||||
"register" => "Rejestracja",
|
||||
"restore_database" => "Przywróć bazę danych",
|
||||
// Login Page
|
||||
'please_login' => "Proszę się zalogować",
|
||||
'stay_logged_in' => "Pozostań zalogowany (30 dni)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Uzyskaj bezpłatny klucz API Fixer'a",
|
||||
"get_key_alternative" => "Alternatywnie, możesz uzyskać darmowy klucz api fixer'a od",
|
||||
"display_settings" => "Ustawienia wyświetlania",
|
||||
"theme_settings" => "Ustawienia motywu",
|
||||
"custom_colors" => "Kolory niestandardowe",
|
||||
"dark_theme" => "Przełącz na jasny/ciemny motyw",
|
||||
"switch_theme" => "Przełącz na jasny/ciemny motyw",
|
||||
"calculate_monthly_price" => "Oblicz i pokaż miesięczną cenę wszystkich subskrypcji",
|
||||
"convert_prices" => "Zawsze przeliczaj i pokazuj ceny w mojej głównej walucie (wolniej)",
|
||||
"hide_disabled_subscriptions" => "Ukryj wyłączone subskrypcje",
|
||||
"experimental_settings" => "Ustawienia eksperymentalne",
|
||||
"remove_background" => "Próba usunięcia tła logo z wyszukiwania obrazów (eksperymentalnie)",
|
||||
"experimental_info" => "Ustawienia eksperymentalne prawdopodobnie nie będą działać idealnie.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Test",
|
||||
"add" => "Dodaj",
|
||||
"save" => "Zapisz",
|
||||
"export_subscriptions" => "Eksportuj subskrypcje",
|
||||
"export_to_json" => "Eksportuj do JSON",
|
||||
"reset" => "Resetuj",
|
||||
"backup_and_restore" => "Kopia zapasowa i przywracanie",
|
||||
"backup" => "Kopia zapasowa",
|
||||
"restore" => "Przywróć",
|
||||
"restore_info" => "Przywrócenie bazy danych zastąpi wszystkie bieżące dane. Po przywróceniu zostaniesz wylogowany.",
|
||||
// Filters menu
|
||||
"filter" => "Filtr",
|
||||
"clear" => "Wyczyść",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "As passwords não coincidem",
|
||||
"registration_failed" => "O registo falhou. Tente novamente",
|
||||
"register" => "Registar",
|
||||
"restore_database" => "Restaurar base de dados",
|
||||
// Login Page
|
||||
'please_login' => "Por favor inicie sessão",
|
||||
'stay_logged_in' => "Manter sessão (30 dias)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Obtenha a sua API Key grátis do Fixer",
|
||||
"get_key_alternative" => "Como alternativa obtenha a sua API Key em",
|
||||
"display_settings" => "Definições de visualização",
|
||||
"theme_settings" => "Definições de Tema",
|
||||
"custom_colors" => "Cores Personalizadas",
|
||||
"dark_theme" => "Tema Escuro",
|
||||
"switch_theme" => "Trocar Tema Claro / Escuro",
|
||||
"calculate_monthly_price" => "Calcular e mostrar preço mensal para todas as subscrições",
|
||||
"convert_prices" => "Converter e mostrar todas as subscrições na moeda principal (mais lento)",
|
||||
"hide_disabled_subscriptions" => "Esconder subscrições desactivadas",
|
||||
"experimental_settings" => "Definições Experimentais",
|
||||
"remove_background" => "Tentar remover o fundo dos logos na pesquisa de imagem (experimental)",
|
||||
"experimental_info" => "Definições experimentais provavelmente não funcionarão correctamente.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Testar",
|
||||
"add" => "Adicionar",
|
||||
"save" => "Guardar",
|
||||
"export_subscriptions" => "Exportar Subscrições",
|
||||
"export_to_json" => "Exportar para JSON",
|
||||
"reset" => "Repor",
|
||||
"backup_and_restore" => "Backup e Restauro",
|
||||
"backup" => "Backup",
|
||||
"restore" => "Restauro",
|
||||
"restore_info" => "O restauro da base de dados apagará todos os dados actuais. A sua sessão irá terminar após o restauro.",
|
||||
// Filters menu
|
||||
"filter" => "Filtro",
|
||||
"clear" => "Limpar",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "As senhas não são iguais",
|
||||
"registration_failed" => "O registro falhou. Por favor, tente novamente",
|
||||
"register" => "Registrar",
|
||||
"restore_database" => "Restaurar banco de dados",
|
||||
// Login Page
|
||||
'please_login' => "Por favor, faça o login",
|
||||
'stay_logged_in' => "Me manter logado (30 dias)",
|
||||
@ -137,9 +138,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Obtenha a sua chave API do Fixer gratuitamente",
|
||||
"get_key_alternative" => "Como alternativa, você pode obter uma chave de API grátis em",
|
||||
"display_settings" => "Configurações de visualização",
|
||||
"theme_settings" => "Configurações de tema",
|
||||
"custom_colors" => "Cores personalizadas",
|
||||
"dark_theme" => "Tema Escuro",
|
||||
"switch_theme" => "Alternar entre tema Claro / Escuro",
|
||||
"calculate_monthly_price" => "Calcular e exibir o custo mensal para todas as assinaturas",
|
||||
"convert_prices" => "Sempre converter e exibir preços na moeda principal (mais lento)",
|
||||
"hide_disabled_subscriptions" => "Ocultar assinaturas desativadas",
|
||||
"experimental_settings" => "Configurações experimentais",
|
||||
"remove_background" => "Tentar remover o fundo de logos na pesquisa de imagem",
|
||||
"experimental_info" => "As configurações experimentais provavelmente não funcionarão corretamente",
|
||||
@ -159,8 +164,11 @@ $i18n = [
|
||||
"test" => "Testar",
|
||||
"add" => "Adicionar",
|
||||
"save" => "Salvar",
|
||||
"export_subscriptions" => "Exportar assinaturas",
|
||||
"export_to_json" => "Exportar para JSON",
|
||||
"reset" => "Redefinir",
|
||||
"backup_and_restore" => "Backup e Restauração",
|
||||
"backup" => "Backup",
|
||||
"restore" => "Restaurar",
|
||||
"restore_info" => "A restauração do banco de dados substituirá todos os dados atuais. Você será desconectado após a restauração.",
|
||||
// Filters menu
|
||||
"filter" => "Filtrar",
|
||||
"clear" => "Limpar",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Лозинке се не поклапају",
|
||||
"registration_failed" => "Регистрација није успела, покушајте поново.",
|
||||
"register" => "Региструј се",
|
||||
"restore_database" => "Врати базу података",
|
||||
// Страница за пријаву
|
||||
'please_login' => "Молимо вас да се пријавите",
|
||||
'stay_logged_in' => "Остани пријављен (30 дана)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Добијте бесплатни Fixer API кључ",
|
||||
"get_key_alternative" => "Алтернативно, можете добити бесплатни Fixer API кључ са",
|
||||
"display_settings" => "Подешавања приказа",
|
||||
"theme_settings" => "Подешавања теме",
|
||||
"custom_colors" => "Прилагођене боје",
|
||||
"dark_theme" => "Тамна тема",
|
||||
"switch_theme" => "Промени светлу / тамну тему",
|
||||
"calculate_monthly_price" => "Израчунајте и прикажите месечну цену за све претплате",
|
||||
"convert_prices" => "Увек конвертујте и прикажите цене на мојој главној валути (спорије)",
|
||||
"hide_disabled_subscriptions" => "Сакриј онемогућене претплате",
|
||||
"experimental_settings" => "Експериментална подешавања",
|
||||
"remove_background" => "Покушајте уклонити позадину логотипа са слика претраге (експериментално)",
|
||||
"experimental_info" => "Експериментална подешавања вероватно неће радити савршено.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Тест",
|
||||
"add" => "Додај",
|
||||
"save" => "Сачувај",
|
||||
"export_subscriptions" => "Извоз претплата",
|
||||
"export_to_json" => "Извоз у JSON формат",
|
||||
"reset" => "Ресетуј",
|
||||
"backup_and_restore" => "Бекап и ресторе",
|
||||
"backup" => "Бекап",
|
||||
"restore" => "Ресторе",
|
||||
"restore_info" => "Враћање базе података ће заменити све тренутне податке. Бићете одјављени након враћања.",
|
||||
// Мени са филтерима
|
||||
"filter" => "Филтер",
|
||||
"clear" => "Очисти",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Lozinke se ne poklapaju",
|
||||
"registration_failed" => "Registracija nije uspela, pokušajte ponovo.",
|
||||
"register" => "Registruj se",
|
||||
"restore_database" => "Vrati bazu podataka",
|
||||
// Stranica za prijavu
|
||||
'please_login' => "Molimo vas da se prijavite",
|
||||
'stay_logged_in' => "Ostani prijavljen (30 dana)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Pronađite besplatni Fixer API ključ",
|
||||
"get_key_alternative" => "Alternativno, možete dobiti besplatni Fixer API ključ na",
|
||||
"display_settings" => "Podešavanja prikaza",
|
||||
"theme_settings" => "Podešavanja teme",
|
||||
"custom_colors" => "Prilagođene boje",
|
||||
"dark_theme" => "Tamna tema",
|
||||
"switch_theme" => "Promeni svetli / tamni temu",
|
||||
"calculate_monthly_price" => "Izračunaj i prikaži mesečnu cenu za sve pretplate",
|
||||
"convert_prices" => "Uvek konvertuj i prikaži cene u mojoj glavnoj valuti (sporije)",
|
||||
"hide_disabled_subscriptions" => "Sakrij onemogućene pretplate",
|
||||
"experimental_settings" => "Eksperimentalna podešavanja",
|
||||
"remove_background" => "Pokušajte ukloniti pozadinu logotipa sa pretrage slika (eksperimentalno)",
|
||||
"experimental_info" => "Eksperimentalna podešavanja verovatno neće savršeno funkcionisati.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Test",
|
||||
"add" => "Dodaj",
|
||||
"save" => "Sačuvaj",
|
||||
"export_subscriptions" => "Izvezi pretplate",
|
||||
"export_to_json" => "Izvezi u JSON format",
|
||||
"reset" => "Resetuj",
|
||||
"backup_and_restore" => "Backup i restore",
|
||||
"backup" => "Backup",
|
||||
"restore" => "Restore",
|
||||
"restore_info" => "Vraćanje baze podataka će zameniti sve trenutne podatke. Bićete odjavljeni nakon vraćanja.",
|
||||
// Meni sa filterima
|
||||
"filter" => "Filter",
|
||||
"clear" => "Očisti",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "Şifreler eşleşmiyor",
|
||||
"registration_failed" => "Kayıt başarısız, lütfen tekrar deneyin.",
|
||||
"register" => "Kayıt Ol",
|
||||
"restore_database" => "Veritabanını geri yükle",
|
||||
// Login Page
|
||||
'please_login' => "Lütfen giriş yapın",
|
||||
'stay_logged_in' => "Oturumu açık tut (30 gün)",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "Ücretsiz Fixer API Anahtarı alın",
|
||||
"get_key_alternative" => "Alternatif olarak, şu adresten ücretsiz bir fixer api anahtarı edinebilirsiniz",
|
||||
"display_settings" => "Görüntüleme Ayarları",
|
||||
"theme_settings" => "Tema Ayarları",
|
||||
"custom_colors" => "Özel Renkler",
|
||||
"dark_theme" => "Koyu Temayı",
|
||||
"switch_theme" => "Açık / Koyu Temayı Değiştir",
|
||||
"calculate_monthly_price" => "Tüm aboneliklerin aylık fiyatını hesaplayın ve gösterin",
|
||||
"convert_prices" => "Fiyatları her zaman ana para birimimde dönüştürün ve gösterin (daha yavaş)",
|
||||
"hide_disabled_subscriptions" => "Devre dışı bırakılan abonelikleri gizle",
|
||||
"experimental_settings" => "Deneysel Ayarlar",
|
||||
"remove_background" => "Görsel aramadan logoların arka planını kaldırmayı deneyin (deneysel)",
|
||||
"experimental_info" => "Deneysel ayarlar muhtemelen mükemmel çalışmayacak.",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "Test Et",
|
||||
"add" => "Ekle",
|
||||
"save" => "Kaydet",
|
||||
"export_subscriptions" => "Abonelikleri Dışa Aktar",
|
||||
"export_to_json" => "JSON'a dışa aktar",
|
||||
"reset" => "Sıfırla",
|
||||
"backup_and_restore" => "Yedekle ve Geri Yükle",
|
||||
"backup" => "Yedekle",
|
||||
"restore" => "Geri Yükle",
|
||||
"restore_info" => "Veritabanının geri yüklenmesi tüm mevcut verileri geçersiz kılacaktır. Geri yüklemeden sonra oturumunuz kapatılacaktır.",
|
||||
// Filters menu
|
||||
"filter" => "Filtre",
|
||||
"clear" => "Temizle",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "密码不匹配",
|
||||
"registration_failed" => "注册失败,请重试。",
|
||||
"register" => "注册",
|
||||
"restore_database" => "恢复数据库",
|
||||
|
||||
// 登录页面
|
||||
'please_login' => "请登录",
|
||||
@ -146,9 +147,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "申请免费 Fixer API 密钥",
|
||||
"get_key_alternative" => "或者,您也可以从以下网站获取免费的修复程序 api 密钥",
|
||||
"display_settings" => "显示设置",
|
||||
"theme_settings" => "主题设置",
|
||||
"custom_colors" => "自定义颜色",
|
||||
"dark_theme" => "深色主题",
|
||||
"switch_theme" => "切换浅色/深色主题",
|
||||
"calculate_monthly_price" => "计算并显示所有订阅的月价格",
|
||||
"convert_prices" => "始终按我的主要货币转换和显示价格(较慢)",
|
||||
"hide_disabled_subscriptions" => "隐藏已停用的订阅",
|
||||
"experimental_settings" => "实验性设置",
|
||||
"remove_background" => "尝试从图片搜索中移除标志的背景(实验性)",
|
||||
"experimental_info" => "实验性设置,可能存在问题。",
|
||||
@ -168,9 +173,11 @@ $i18n = [
|
||||
"test" => "测试",
|
||||
"add" => "添加",
|
||||
"save" => "保存",
|
||||
"export_subscriptions" => "导出订阅",
|
||||
"export_to_json" => "导出为 JSON",
|
||||
|
||||
"reset" => "重置",
|
||||
"backup_and_restore" => "备份和恢复",
|
||||
"backup" => "备份",
|
||||
"restore" => "恢复",
|
||||
"restore_info" => "还原数据库将覆盖所有当前数据。还原后,您将退出登录。",
|
||||
// Filters menu
|
||||
"filter" => "筛选",
|
||||
"clear" => "清除",
|
||||
|
||||
@ -12,6 +12,7 @@ $i18n = [
|
||||
"passwords_dont_match" => "密碼不一致",
|
||||
"registration_failed" => "註冊失敗,請再試一次。",
|
||||
"register" => "註冊",
|
||||
"restore_database" => "還原資料庫",
|
||||
// 登入頁面
|
||||
'please_login' => "請先登入",
|
||||
'stay_logged_in' => "保持登入 30 天",
|
||||
@ -139,9 +140,13 @@ $i18n = [
|
||||
"get_free_fixer_api_key" => "申請免費的 Fixer API 金鑰",
|
||||
"get_key_alternative" => "或者,您可以從以下網址取得一個免費的修復 api 金鑰",
|
||||
"display_settings" => "顯示設定",
|
||||
"theme_settings" => "主題設定",
|
||||
"custom_colors" => "自訂顏色",
|
||||
"dark_theme" => "深色主題",
|
||||
"switch_theme" => "切換淺色/深色主題",
|
||||
"calculate_monthly_price" => "計算並顯示所有訂閱的每月價格",
|
||||
"convert_prices" => "始終按照我的主要貨幣單位轉換和顯示價格(較慢)",
|
||||
"hide_disabled_subscriptions" => "隱藏已停用的訂閱",
|
||||
"experimental_settings" => "實驗性設定",
|
||||
"remove_background" => "嘗試從圖片搜尋中移除圖示的背景顏色(實驗性)",
|
||||
"experimental_info" => "實驗性設定,可能存在問題。",
|
||||
@ -161,8 +166,11 @@ $i18n = [
|
||||
"test" => "測試",
|
||||
"add" => "新增",
|
||||
"save" => "儲存",
|
||||
"export_subscriptions" => "匯出訂閱",
|
||||
"export_to_json" => "匯出為 JSON 檔案",
|
||||
"reset" => "重設",
|
||||
"backup_and_restore" => "備份與還原",
|
||||
"backup" => "備份",
|
||||
"restore" => "還原",
|
||||
"restore_info" => "復原資料庫將覆蓋所有目前資料。 恢復後您將被註銷。",
|
||||
// Filters menu
|
||||
"filter" => "篩選",
|
||||
"clear" => "清除",
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
function printSubscriptions($subscriptions, $sort, $categories, $members, $i18n) {
|
||||
function printSubscriptions($subscriptions, $sort, $categories, $members, $i18n, $colorTheme) {
|
||||
if ($sort === "price") {
|
||||
usort($subscriptions, function($a, $b) {
|
||||
return $a['price'] < $b['price'] ? 1 : -1;
|
||||
@ -110,14 +110,14 @@
|
||||
</span>
|
||||
<span class="actions">
|
||||
<button class="image-button medium" onClick="openEditSubscription(event, <?= $subscription['id'] ?>)" name="edit">
|
||||
<img src="images/siteicons/edit.png" title="<?= translate('edit_subscription', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/edit.png" title="<?= translate('edit_subscription', $i18n) ?>">
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class="subscription-secondary">
|
||||
<span class="name"><img src="images/siteicons/subscription.png" alt="<?= translate('subscription', $i18n) ?>" /><?= $subscription['name'] ?></span>
|
||||
<span class="payer_user" title="<?= translate('paid_by', $i18n) ?>"><img src="images/siteicons/payment.png" alt="<?= translate('paid_by', $i18n) ?>" /><?= $members[$subscription['payer_user_id']]['name'] ?></span>
|
||||
<span class="category" title="<?= translate('category', $i18n) ?>" ><img src="images/siteicons/category.png" alt="<?= translate('category', $i18n) ?>" /><?= $categories[$subscription['category_id']]['name'] ?></span>
|
||||
<span class="name"><img src="images/siteicons/<?= $colorTheme ?>/subscription.png" alt="<?= translate('subscription', $i18n) ?>" /><?= $subscription['name'] ?></span>
|
||||
<span class="payer_user" title="<?= translate('paid_by', $i18n) ?>"><img src="images/siteicons/<?= $colorTheme ?>/payment.png" alt="<?= translate('paid_by', $i18n) ?>" /><?= $members[$subscription['payer_user_id']]['name'] ?></span>
|
||||
<span class="category" title="<?= translate('category', $i18n) ?>" ><img src="images/siteicons/<?= $colorTheme ?>/category.png" alt="<?= translate('category', $i18n) ?>" /><?= $categories[$subscription['category_id']]['name'] ?></span>
|
||||
<?php
|
||||
if ($subscription['url'] != "") {
|
||||
$url = $subscription['url'];
|
||||
@ -125,7 +125,7 @@
|
||||
$url = "https://" . $url;
|
||||
}
|
||||
?>
|
||||
<span class="url" title="<?= translate('external_url', $i18n) ?>"><a href="<?= $url ?>" target="_blank"><img src="images/siteicons/web.png" alt="<?= translate('url', $i18n) ?>" /></a></span>
|
||||
<span class="url" title="<?= translate('external_url', $i18n) ?>"><a href="<?= $url ?>" target="_blank"><img src="images/siteicons/<?= $colorTheme ?>/web.png" alt="<?= translate('url', $i18n) ?>" /></a></span>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
@ -135,7 +135,7 @@
|
||||
?>
|
||||
<div class="subscription-notes">
|
||||
<span class="notes">
|
||||
<img src="images/siteicons/notes.png" alt="<?= translate('notes', $i18n) ?>" />
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/notes.png" alt="<?= translate('notes', $i18n) ?>" />
|
||||
<?= $subscription['notes'] ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<?php
|
||||
$version = "v1.20.2";
|
||||
$version = "v1.23.0";
|
||||
?>
|
||||
|
||||
15
index.php
@ -37,7 +37,7 @@
|
||||
}
|
||||
|
||||
$headerClass = count($subscriptions) > 0 ? "main-actions" : "main-actions hidden";
|
||||
$defaultLogo = $theme == "light" ? "images/wallos.png" : "images/walloswhite.png";
|
||||
$defaultLogo = $theme == "light" ? "images/siteicons/" . $colorTheme . "/wallos.png" : "images/siteicons/" . $colorTheme . "/walloswhite.png";
|
||||
?>
|
||||
<style>
|
||||
.logo-preview:after {
|
||||
@ -156,6 +156,9 @@
|
||||
<div class="subscriptions" id="subscriptions">
|
||||
<?php
|
||||
foreach ($subscriptions as $subscription) {
|
||||
if ($subscription['inactive'] == 1 && isset($settings['hideDisabledSubscriptions']) && $settings['hideDisabledSubscriptions'] === 'true') {
|
||||
continue;
|
||||
}
|
||||
$id = $subscription['id'];
|
||||
$print[$id]['id'] = $id;
|
||||
$print[$id]['logo'] = $subscription['logo'] != "" ? "images/uploads/logos/".$subscription['logo'] : $defaultLogo;
|
||||
@ -188,7 +191,7 @@
|
||||
}
|
||||
|
||||
if (isset($print)) {
|
||||
printSubscriptions($print, $sort, $categories, $members, $i18n);
|
||||
printSubscriptions($print, $sort, $categories, $members, $i18n, $colorTheme);
|
||||
}
|
||||
$db->close();
|
||||
|
||||
@ -224,7 +227,7 @@
|
||||
<input type="file" id="logo" name="logo" accept="image/jpeg, image/png, image/gif, image/webp" onchange="handleFileSelect(event)" class="hidden-input">
|
||||
<input type="hidden" id="logo-url" name="logo-url">
|
||||
<div id="logo-search-button" class="image-button medium disabled" title="<?= translate('search_logo', $i18n) ?>" onClick="searchLogo()">
|
||||
<img src="images/siteicons/websearch.png">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/websearch.png">
|
||||
</div>
|
||||
<input type="hidden" id="id" name="id">
|
||||
<div id="logo-search-results" class="logo-search">
|
||||
@ -351,9 +354,9 @@
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<input type="button" value="<?= translate('delete', $i18n) ?>" class="warning-button left" id="deletesub" style="display: none">
|
||||
<input type="button" value="<?= translate('cancel', $i18n) ?>" class="secondary-button" onClick="closeAddSubscription()">
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="save-button">
|
||||
<input type="button" value="<?= translate('delete', $i18n) ?>" class="warning-button left thin" id="deletesub" style="display: none">
|
||||
<input type="button" value="<?= translate('cancel', $i18n) ?>" class="secondary-button thin" onClick="closeAddSubscription()">
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" class="thin" id="save-button">
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
13
login.php
@ -25,6 +25,11 @@ if (isset($_COOKIE['theme'])) {
|
||||
$theme = $_COOKIE['theme'];
|
||||
}
|
||||
|
||||
$colorTheme = "blue";
|
||||
if (isset($_COOKIE['colorTheme'])) {
|
||||
$colorTheme = $_COOKIE['colorTheme'];
|
||||
}
|
||||
|
||||
$loginFailed = false;
|
||||
if (isset($_POST['username']) && isset($_POST['password'])) {
|
||||
$username = $_POST['username'];
|
||||
@ -80,7 +85,11 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
|
||||
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
|
||||
<link rel="stylesheet" href="styles/login.css?<?= $version ?>">
|
||||
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/barlow.css">
|
||||
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
|
||||
</head>
|
||||
@ -90,9 +99,9 @@ if (isset($_POST['username']) && isset($_POST['password'])) {
|
||||
<header>
|
||||
<?php
|
||||
if ($theme == "light") {
|
||||
?> <img src="images/wallossolid.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" /> <?php
|
||||
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
|
||||
} else {
|
||||
?> <img src="images/wallossolidwhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" /> <?php
|
||||
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
|
||||
}
|
||||
?>
|
||||
<p>
|
||||
|
||||
25
migrations/000014.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
// This migration adds a "color_theme" column to the settings table and sets it to blue as default.
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
$columnQuery = $db->query("SELECT * FROM pragma_table_info('settings') where name='color_theme'");
|
||||
$columnRequired = $columnQuery->fetchArray(SQLITE3_ASSOC) === false;
|
||||
|
||||
if ($columnRequired) {
|
||||
$db->exec("ALTER TABLE settings ADD COLUMN color_theme TEXT DEFAULT 'blue'");
|
||||
$db->exec('UPDATE settings SET `color_theme` = "blue"');
|
||||
}
|
||||
|
||||
// This migrations adds custom_colors table to the database, so the user can set custom accent colors to the application
|
||||
|
||||
$customColorsTableQuery = $db->query("SELECT * FROM sqlite_master WHERE type='table' AND name='custom_colors'");
|
||||
$customColorsTableRequired = $customColorsTableQuery->fetchArray(SQLITE3_ASSOC) === false;
|
||||
|
||||
if ($customColorsTableRequired) {
|
||||
$db->exec("CREATE TABLE custom_colors (
|
||||
main_color TEXT NOT NULL,
|
||||
accent_color TEXT NOT NULL,
|
||||
hover_color TEXT NOT NULL
|
||||
)");
|
||||
}
|
||||
|
||||
11
migrations/000015.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
// This migration adds a "hide_disabled" column to the settings table and sets to false as default.
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
$columnQuery = $db->query("SELECT * FROM pragma_table_info('settings') where name='hide_disabled'");
|
||||
$columnRequired = $columnQuery->fetchArray(SQLITE3_ASSOC) === false;
|
||||
|
||||
if ($columnRequired) {
|
||||
$db->exec("ALTER TABLE settings ADD COLUMN hide_disabled BOOLEAN DEFAULT 0");
|
||||
$db->exec('UPDATE settings SET `hide_disabled` = 0');
|
||||
}
|
||||
@ -26,6 +26,11 @@ if (isset($_COOKIE['theme'])) {
|
||||
$theme = $_COOKIE['theme'];
|
||||
}
|
||||
|
||||
$colorTheme = "blue";
|
||||
if (isset($_COOKIE['colorTheme'])) {
|
||||
$colorTheme = $_COOKIE['colorTheme'];
|
||||
}
|
||||
|
||||
$currencies = array();
|
||||
$query = "SELECT * FROM currencies";
|
||||
$result = $db->query($query);
|
||||
@ -94,8 +99,12 @@ if (isset($_POST['username'])) {
|
||||
<title>Wallos - Subscription Tracker</title>
|
||||
<link rel="icon" type="image/png" href="images/icon/favicon.ico" sizes="16x16">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="images/icon/apple-touch-icon.png">
|
||||
<link rel="manifest" href="manifes.json">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="styles/theme.css?<?= $version ?>">
|
||||
<link rel="stylesheet" href="styles/login.css?<?= $version ?>">
|
||||
<link rel="stylesheet" href="styles/themes/red.css?<?= $version ?>" id="red-theme" <?= $colorTheme != "red" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/green.css?<?= $version ?>" id="green-theme" <?= $colorTheme != "green" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/themes/yellow.css?<?= $version ?>" id="yellow-theme" <?= $colorTheme != "yellow" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/login-dark-theme.css?<?= $version ?>" id="dark-theme" <?= $theme == "light" ? "disabled" : "" ?>>
|
||||
<link rel="stylesheet" href="styles/barlow.css">
|
||||
<script type="text/javascript" src="scripts/registration.js?<?= $version ?>"></script>
|
||||
@ -106,9 +115,9 @@ if (isset($_POST['username'])) {
|
||||
<header>
|
||||
<?php
|
||||
if ($theme == "light") {
|
||||
?> <img src="images/wallossolid.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" /> <?php
|
||||
?> <img src="images/siteicons/<?= $colorTheme ?>/wallos.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
|
||||
} else {
|
||||
?> <img src="images/wallossolidwhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" /> <?php
|
||||
?> <img src="images/siteicons/<?= $colorTheme ?>/walloswhite.png" alt="Wallos Logo" title="Wallos - Subscription Tracker" width="215" /> <?php
|
||||
}
|
||||
?>
|
||||
<p>
|
||||
@ -179,8 +188,14 @@ if (isset($_POST['username'])) {
|
||||
<input type="submit" value="<?= translate('register', $i18n) ?>">
|
||||
</div>
|
||||
</form>
|
||||
<div class="separator">
|
||||
<input type="button" class="secondary-button" value="<?= translate('restore_database', $i18n) ?>" id="restoreDB" onClick="openRestoreDBFileSelect()" />
|
||||
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()" accept=".zip">
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require_once 'includes/footer.php';
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@ -37,7 +37,7 @@ function fillEditFormFields(subscription) {
|
||||
const formTitle = document.querySelector("#form-title");
|
||||
formTitle.textContent = translate('edit_subscription');
|
||||
const logo = document.querySelector("#form-logo");
|
||||
const defaultLogo = window.theme && window.theme == "light" ? "images/wallos.png" : "images/walloswhite.png";
|
||||
const defaultLogo = window.theme && window.theme == "light" ? "images/siteicons/" + colorTheme + "/wallos.png" : "images/siteicons/" + colorTheme + "/walloswhite.png";
|
||||
const logoFile = subscription.logo !== null ? "images/uploads/logos/" + subscription.logo : defaultLogo;
|
||||
logo.src = logoFile;
|
||||
logo.style = 'display: block';
|
||||
|
||||
37
scripts/i18n/it.js
Normal file
@ -0,0 +1,37 @@
|
||||
let i18n = {
|
||||
// Dashboard
|
||||
error_reloading_subscription: "Errore nel ricaricare l'abbonamento:",
|
||||
error_fetching_image_results: "Errore nel recupero delle immagini:",
|
||||
subscription_deleted: "Abbonamento eliminato",
|
||||
error_deleting_subscription: "Errore nell'eliminare l'abbonamento",
|
||||
failed_to_load_subscription: "Caricamento dell'abbonamento non riuscito",
|
||||
edit_subscription: "Modifica abbonamento",
|
||||
add_subscription: "Aggiungi abbonamento",
|
||||
confirm_delete_subscription: "Sei sicuro di voler eliminare questo abbonamento?",
|
||||
|
||||
// Settings
|
||||
network_response_error: "Si è verificato un errore nella risposta del server",
|
||||
failed_add_member: "Impossibile aggiungere il membro",
|
||||
member: "Membro",
|
||||
email: "Email",
|
||||
save_member: "Salva membro",
|
||||
delete_member: "Elimina membro",
|
||||
failed_remove_member: "Impossibile rimuovere il membro",
|
||||
failed_save_member: "Impossibile salvare il membro",
|
||||
failed_add_category: "Impossibile aggiungere la categoria",
|
||||
category: "Categoria",
|
||||
save_category: "Salva categoria",
|
||||
delete_category: "Elimina categoria",
|
||||
failed_remove_category: "Impossibile rimuovere la categoria",
|
||||
currency: "Valuta",
|
||||
currency_code: "Codice valuta",
|
||||
save_currency: "Salva valuta",
|
||||
delete_currency: "Elimina valuta",
|
||||
failed_remove_currency: "Impossibile rimuovere la valuta",
|
||||
failed_save_currency: "Impossibile salvare la valuta",
|
||||
cant_disable_payment_in_use: "Impossibile disabilitare il pagamento in uso",
|
||||
failed_save_payment_method: "Impossibile salvare il metodo di pagamento",
|
||||
unknown_error: "Errore sconosciuto, si prega di riprovare.",
|
||||
error_saving_notification_data: "Errore nel salvataggio delle impostazioni di notifica",
|
||||
error_sending_notification: "Errore nell'invio della notifica",
|
||||
}
|
||||
@ -62,6 +62,101 @@ function runDatabaseMigration() {
|
||||
});
|
||||
}
|
||||
|
||||
function showErrorMessage(message) {
|
||||
const toast = document.querySelector(".toast#errorToast");
|
||||
(closeIcon = document.querySelector(".close-error")),
|
||||
(errorMessage = document.querySelector(".errorMessage")),
|
||||
(progress = document.querySelector(".progress.error"));
|
||||
let timer1, timer2;
|
||||
errorMessage.textContent = message;
|
||||
toast.classList.add("active");
|
||||
progress.classList.add("active");
|
||||
timer1 = setTimeout(() => {
|
||||
toast.classList.remove("active");
|
||||
closeIcon.removeEventListener("click", () => {});
|
||||
}, 5000);
|
||||
|
||||
timer2 = setTimeout(() => {
|
||||
progress.classList.remove("active");
|
||||
}, 5300);
|
||||
|
||||
closeIcon.addEventListener("click", () => {
|
||||
toast.classList.remove("active");
|
||||
|
||||
setTimeout(() => {
|
||||
progress.classList.remove("active");
|
||||
}, 300);
|
||||
|
||||
clearTimeout(timer1);
|
||||
clearTimeout(timer2);
|
||||
closeIcon.removeEventListener("click", () => {});
|
||||
});
|
||||
}
|
||||
|
||||
function showSuccessMessage(message) {
|
||||
const toast = document.querySelector(".toast#successToast");
|
||||
(closeIcon = document.querySelector(".close-success")),
|
||||
(successMessage = document.querySelector(".successMessage")),
|
||||
(progress = document.querySelector(".progress.success"));
|
||||
let timer1, timer2;
|
||||
successMessage.textContent = message;
|
||||
toast.classList.add("active");
|
||||
progress.classList.add("active");
|
||||
timer1 = setTimeout(() => {
|
||||
toast.classList.remove("active");
|
||||
closeIcon.removeEventListener("click", () => {});
|
||||
}, 5000);
|
||||
|
||||
timer2 = setTimeout(() => {
|
||||
progress.classList.remove("active");
|
||||
}, 5300);
|
||||
|
||||
closeIcon.addEventListener("click", () => {
|
||||
toast.classList.remove("active");
|
||||
|
||||
setTimeout(() => {
|
||||
progress.classList.remove("active");
|
||||
}, 300);
|
||||
|
||||
clearTimeout(timer1);
|
||||
clearTimeout(timer2);
|
||||
closeIcon.removeEventListener("click", () => {});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function openRestoreDBFileSelect() {
|
||||
document.getElementById('restoreDBFile').click();
|
||||
};
|
||||
|
||||
function restoreDB() {
|
||||
const input = document.getElementById('restoreDBFile');
|
||||
const file = input.files[0];
|
||||
|
||||
if (!file) {
|
||||
console.error('No file selected');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
fetch('endpoints/db/import.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showSuccessMessage(data.message)
|
||||
window.location.href = 'logout.php';
|
||||
} else {
|
||||
showErrorMessage(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => showErrorMessage('Error:', error));
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
restoreFormFields();
|
||||
removeFromStorage();
|
||||
|
||||
@ -108,7 +108,7 @@ function addMemberButton(memberId) {
|
||||
};
|
||||
|
||||
let editImage = document.createElement("img");
|
||||
editImage.src = "images/siteicons/save.png";
|
||||
editImage.src = "images/siteicons/" + colorTheme + "/save.png";
|
||||
editImage.title = translate('save_member');
|
||||
|
||||
editLink.appendChild(editImage);
|
||||
@ -121,7 +121,7 @@ function addMemberButton(memberId) {
|
||||
};
|
||||
|
||||
let deleteImage = document.createElement("img");
|
||||
deleteImage.src = "images/siteicons/delete.png";
|
||||
deleteImage.src = "images/siteicons/" + colorTheme + "/delete.png";
|
||||
deleteImage.title = translate('delete_member');
|
||||
|
||||
deleteLink.appendChild(deleteImage);
|
||||
@ -237,7 +237,7 @@ function addCategoryButton(categoryId) {
|
||||
};
|
||||
|
||||
let editImage = document.createElement("img");
|
||||
editImage.src = "images/siteicons/save.png";
|
||||
editImage.src = "images/siteicons/" + colorTheme + "/save.png";
|
||||
editImage.title = translate('save_category');
|
||||
|
||||
editLink.appendChild(editImage);
|
||||
@ -250,7 +250,7 @@ function addCategoryButton(categoryId) {
|
||||
};
|
||||
|
||||
let deleteImage = document.createElement("img");
|
||||
deleteImage.src = "images/siteicons/delete.png";
|
||||
deleteImage.src = "images/siteicons/" + colorTheme + "/delete.png";
|
||||
deleteImage.title = translate('delete_category');
|
||||
|
||||
deleteLink.appendChild(deleteImage);
|
||||
@ -375,7 +375,7 @@ function addCurrencyButton(currencyId) {
|
||||
};
|
||||
|
||||
let editImage = document.createElement("img");
|
||||
editImage.src = "images/siteicons/save.png";
|
||||
editImage.src = "images/siteicons/" + colorTheme + "/save.png";
|
||||
editImage.title = translate('save_currency');
|
||||
|
||||
editLink.appendChild(editImage);
|
||||
@ -388,7 +388,7 @@ function addCurrencyButton(currencyId) {
|
||||
};
|
||||
|
||||
let deleteImage = document.createElement("img");
|
||||
deleteImage.src = "images/siteicons/delete.png";
|
||||
deleteImage.src = "images/siteicons/" + colorTheme + "/delete.png";
|
||||
deleteImage.title = translate('delete_currency');
|
||||
|
||||
deleteLink.appendChild(deleteImage);
|
||||
@ -937,6 +937,8 @@ function switchTheme() {
|
||||
const themeChoice = darkThemeCss.disabled ? 'light' : 'dark';
|
||||
document.cookie = `theme=${themeChoice}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;
|
||||
|
||||
document.body.className = themeChoice;
|
||||
|
||||
const button = document.getElementById("switchTheme");
|
||||
button.disabled = true;
|
||||
|
||||
@ -999,8 +1001,71 @@ function setRemoveBackground() {
|
||||
storeSettingsOnDB('remove_background', value);
|
||||
}
|
||||
|
||||
function exportToJson() {
|
||||
window.location.href = "endpoints/subscriptions/export.php";
|
||||
function setHideDisabled() {
|
||||
const hideDisabledCheckbox = document.querySelector("#hidedisabled");
|
||||
const value = hideDisabledCheckbox.checked;
|
||||
|
||||
storeSettingsOnDB('hide_disabled', value);
|
||||
}
|
||||
|
||||
function backupDB() {
|
||||
const button = document.getElementById("backupDB");
|
||||
button.disabled = true;
|
||||
|
||||
fetch('endpoints/db/backup.php')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const link = document.createElement('a');
|
||||
const filename = data.file;
|
||||
link.href = '.tmp/' + filename;
|
||||
link.download = 'backup.zip';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
button.disabled = false;
|
||||
} else {
|
||||
showErrorMessage(data.errorMessage);
|
||||
button.disabled = false;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showErrorMessage(error);
|
||||
button.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
function openRestoreDBFileSelect() {
|
||||
document.getElementById('restoreDBFile').click();
|
||||
};
|
||||
|
||||
function restoreDB() {
|
||||
const input = document.getElementById('restoreDBFile');
|
||||
const file = input.files[0];
|
||||
|
||||
if (!file) {
|
||||
console.error('No file selected');
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
fetch('endpoints/db/restore.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showSuccessMessage(data.message)
|
||||
window.location.href = 'logout.php';
|
||||
} else {
|
||||
showErrorMessage(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => showErrorMessage('Error:', error));
|
||||
}
|
||||
|
||||
function saveCategorySorting() {
|
||||
@ -1040,3 +1105,127 @@ var sortable = Sortable.create(el, {
|
||||
saveCategorySorting();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
function setTheme(themeColor) {
|
||||
var currentTheme = 'blue';
|
||||
var themeIds = ['red-theme', 'green-theme', 'yellow-theme'];
|
||||
|
||||
themeIds.forEach(function(id) {
|
||||
var themeStylesheet = document.getElementById(id);
|
||||
if (themeStylesheet && !themeStylesheet.disabled) {
|
||||
currentTheme = id.replace('-theme', '');
|
||||
themeStylesheet.disabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (themeColor !== "blue") {
|
||||
var enableTheme = document.getElementById(themeColor + '-theme');
|
||||
enableTheme.disabled = false;
|
||||
}
|
||||
|
||||
var images = document.querySelectorAll('img');
|
||||
images.forEach(function(img) {
|
||||
if (img.src.includes('siteicons/' + currentTheme)) {
|
||||
img.src = img.src.replace(currentTheme, themeColor);
|
||||
}
|
||||
});
|
||||
|
||||
var labels = document.querySelectorAll('.theme-preview');
|
||||
labels.forEach(function(label) {
|
||||
label.classList.remove('is-selected');
|
||||
});
|
||||
|
||||
var targetLabel = document.querySelector(`.theme-preview.${themeColor}`);
|
||||
if (targetLabel) {
|
||||
targetLabel.classList.add('is-selected');
|
||||
}
|
||||
|
||||
document.cookie = `colorTheme=${themeColor}; expires=Fri, 31 Dec 9999 23:59:59 GMT`;
|
||||
|
||||
fetch('endpoints/settings/colortheme.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ color: themeColor })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showSuccessMessage(data.message);
|
||||
} else {
|
||||
showErrorMessage(data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showErrorMessage(translate('unknown_error'));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function resetCustomColors() {
|
||||
const button = document.getElementById("reset-colors");
|
||||
button.disabled = true;
|
||||
|
||||
fetch('endpoints/settings/resettheme.php', {
|
||||
method: 'DELETE',
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showSuccessMessage(data.message);
|
||||
const custom_theme_colors = document.getElementById('custom_theme_colors');
|
||||
if (custom_theme_colors) {
|
||||
custom_theme_colors.remove();
|
||||
}
|
||||
document.documentElement.style.removeProperty('--main-color');
|
||||
document.documentElement.style.removeProperty('--accent-color');
|
||||
document.documentElement.style.removeProperty('--hover-color');
|
||||
document.getElementById("mainColor").value = "#FFFFFF";
|
||||
document.getElementById("accentColor").value = "#FFFFFF";
|
||||
document.getElementById("hoverColor").value = "#FFFFFF";
|
||||
} else {
|
||||
showErrorMessage(data.message);
|
||||
}
|
||||
button.disabled = false;
|
||||
})
|
||||
.catch(error => {
|
||||
showErrorMessage(translate('unknown_error'));
|
||||
button.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
function saveCustomColors() {
|
||||
const button = document.getElementById("save-colors");
|
||||
button.disabled = true;
|
||||
|
||||
const mainColor = document.getElementById("mainColor").value;
|
||||
const accentColor = document.getElementById("accentColor").value;
|
||||
const hoverColor = document.getElementById("hoverColor").value;
|
||||
|
||||
fetch('endpoints/settings/customtheme.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ mainColor: mainColor, accentColor: accentColor, hoverColor: hoverColor })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
showSuccessMessage(data.message);
|
||||
document.documentElement.style.setProperty('--main-color', mainColor);
|
||||
document.documentElement.style.setProperty('--accent-color', accentColor);
|
||||
document.documentElement.style.setProperty('--hover-color', hoverColor);
|
||||
} else {
|
||||
showErrorMessage(data.message);
|
||||
}
|
||||
button.disabled = false;
|
||||
})
|
||||
.catch(error => {
|
||||
showErrorMessage(translate('unknown_error'));
|
||||
button.disabled = false;
|
||||
});
|
||||
|
||||
}
|
||||
@ -14,6 +14,9 @@ self.addEventListener('install', function(event) {
|
||||
'styles/login.css',
|
||||
'styles/font-awesome.min.css',
|
||||
'styles/barlow.css',
|
||||
'styles/themes/red.css',
|
||||
'styles/themes/green.css',
|
||||
'styles/themes/yellow.css',
|
||||
'webfonts/fa-solid-900.woff2',
|
||||
'webfonts/fa-solid-900.ttf',
|
||||
'scripts/common.js',
|
||||
@ -26,6 +29,7 @@ self.addEventListener('install', function(event) {
|
||||
'scripts/i18n/el.js',
|
||||
'scripts/i18n/es.js',
|
||||
'scripts/i18n/fr.js',
|
||||
'scripts/i18n/it.js',
|
||||
'scripts/i18n/jp.js',
|
||||
'scripts/i18n/pl.js',
|
||||
'scripts/i18n/pt.js',
|
||||
@ -39,8 +43,14 @@ self.addEventListener('install', function(event) {
|
||||
'images/icon/favicon.ico',
|
||||
'images/icon/android-chrome-192x192.png',
|
||||
'images/screenshots/desktop.png',
|
||||
'images/wallossolid.png',
|
||||
'images/wallossolidwhite.png',
|
||||
'images/siteicons/blue/wallos.png',
|
||||
'images/siteicons/blue/walloswhite.png',
|
||||
'images/siteicons/green/wallos.png',
|
||||
'images/siteicons/green/walloswhite.png',
|
||||
'images/siteicons/red/wallos.png',
|
||||
'images/siteicons/red/walloswhite.png',
|
||||
'images/siteicons/yellow/wallos.png',
|
||||
'images/siteicons/yellow/walloswhite.png',
|
||||
'images/siteimages/empty.png',
|
||||
'images/avatars/1.svg',
|
||||
'images/avatars/2.svg',
|
||||
@ -51,19 +61,46 @@ self.addEventListener('install', function(event) {
|
||||
'images/avatars/7.svg',
|
||||
'images/avatars/8.svg',
|
||||
'images/avatars/9.svg',
|
||||
'images/siteicons/edit.png',
|
||||
'images/siteicons/websearch.png',
|
||||
'images/siteicons/save.png',
|
||||
'images/siteicons/delete.png',
|
||||
'images/siteicons/category.png',
|
||||
'images/siteicons/check.png',
|
||||
'images/siteicons/editavatar.png',
|
||||
'images/siteicons/notes.png',
|
||||
'images/siteicons/payment.png',
|
||||
'images/siteicons/plusicon.png',
|
||||
'images/siteicons/sort.png',
|
||||
'images/siteicons/subscription.png',
|
||||
'images/siteicons/web.png',
|
||||
'images/siteicons/blue/category.png',
|
||||
'images/siteicons/blue/check.png',
|
||||
'images/siteicons/blue/delete.png',
|
||||
'images/siteicons/blue/edit.png',
|
||||
'images/siteicons/blue/notes.png',
|
||||
'images/siteicons/blue/payment.png',
|
||||
'images/siteicons/blue/save.png',
|
||||
'images/siteicons/blue/subscription.png',
|
||||
'images/siteicons/blue/web.png',
|
||||
'images/siteicons/blue/websearch.png',
|
||||
'images/siteicons/red/category.png',
|
||||
'images/siteicons/red/check.png',
|
||||
'images/siteicons/red/delete.png',
|
||||
'images/siteicons/red/edit.png',
|
||||
'images/siteicons/red/notes.png',
|
||||
'images/siteicons/red/payment.png',
|
||||
'images/siteicons/red/save.png',
|
||||
'images/siteicons/red/subscription.png',
|
||||
'images/siteicons/red/web.png',
|
||||
'images/siteicons/red/websearch.png',
|
||||
'images/siteicons/green/category.png',
|
||||
'images/siteicons/green/check.png',
|
||||
'images/siteicons/green/delete.png',
|
||||
'images/siteicons/green/edit.png',
|
||||
'images/siteicons/green/notes.png',
|
||||
'images/siteicons/green/payment.png',
|
||||
'images/siteicons/green/save.png',
|
||||
'images/siteicons/green/subscription.png',
|
||||
'images/siteicons/green/web.png',
|
||||
'images/siteicons/green/websearch.png',
|
||||
'images/siteicons/yellow/category.png',
|
||||
'images/siteicons/yellow/check.png',
|
||||
'images/siteicons/yellow/delete.png',
|
||||
'images/siteicons/yellow/edit.png',
|
||||
'images/siteicons/yellow/notes.png',
|
||||
'images/siteicons/yellow/payment.png',
|
||||
'images/siteicons/yellow/save.png',
|
||||
'images/siteicons/yellow/subscription.png',
|
||||
'images/siteicons/yellow/web.png',
|
||||
'images/siteicons/yellow/websearch.png',
|
||||
'images/siteicons/pwa/stats.png',
|
||||
'images/siteicons/pwa/settings.png',
|
||||
'images/siteicons/pwa/about.png',
|
||||
|
||||
125
settings.php
@ -104,7 +104,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="userSubmit"/>
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="userSubmit" class="thin"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -142,19 +142,19 @@
|
||||
}
|
||||
?>
|
||||
<button class="image-button medium" onClick="editMember(<?= $member['id'] ?>)" name="save">
|
||||
<img src="images/siteicons/save.png" title="<?= translate('save_member', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/save.png" title="<?= translate('save_member', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
if ($member['id'] != 1) {
|
||||
?>
|
||||
<button class="image-button medium" onClick="removeMember(<?= $member['id'] ?>)">
|
||||
<img src="images/siteicons/delete.png" title="<?= translate('delete_member', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_member', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<button class="image-button medium disabled">
|
||||
<img src="images/siteicons/delete.png" title="<?= translate('cant_delete_member', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('cant_delete_member', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
@ -170,7 +170,7 @@
|
||||
<p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="<?= translate('add', $i18n) ?>" id="addMember" onClick="addMemberButton()"/>
|
||||
<input type="submit" value="<?= translate('add', $i18n) ?>" id="addMember" onClick="addMemberButton()" class="thin"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -248,8 +248,8 @@
|
||||
<p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="button" class="secondary-button" value="<?= translate('test', $i18n) ?>" id="testNotifications" onClick="testNotificationButton()"/>
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="saveNotifications" onClick="saveNotificationsButton()"/>
|
||||
<input type="button" class="secondary-button thin" value="<?= translate('test', $i18n) ?>" id="testNotifications" onClick="testNotificationButton()"/>
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="saveNotifications" onClick="saveNotificationsButton()" class="thin"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -292,19 +292,19 @@
|
||||
<div class="drag-icon"></div>
|
||||
<input type="text" name="category" value="<?= $category['name'] ?>" placeholder="Category">
|
||||
<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/<?= $colorTheme ?>/save.png" title="<?= translate('save_category', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
if ($canDelete) {
|
||||
?>
|
||||
<button class="image-button medium" onClick="removeCategory(<?= $category['id'] ?>)">
|
||||
<img src="images/siteicons/delete.png" title="<?= translate('delete_category', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_category', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<button class="image-button medium disabled">
|
||||
<img src="images/siteicons/delete.png" title="<?= translate('cant_delete_category_in_use', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('cant_delete_category_in_use', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
@ -316,7 +316,7 @@
|
||||
?>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="<?= translate('add', $i18n) ?>" id="addCategory" onClick="addCategoryButton()"/>
|
||||
<input type="submit" value="<?= translate('add', $i18n) ?>" id="addCategory" onClick="addCategoryButton()" class="thin"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -375,20 +375,20 @@
|
||||
<input type="text" name="currency" value="<?= $currency['name'] ?>" placeholder="Currency Name">
|
||||
<input type="text" name="code" value="<?= $currency['code'] ?>" placeholder="Currency Code" <?= !$canDelete ? 'disabled' : '' ?>>
|
||||
<button class="image-button medium" onClick="editCurrency(<?= $currency['id'] ?>)" name="save">
|
||||
<img src="images/siteicons/save.png" title="<?= translate('save_currency', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/save.png" title="<?= translate('save_currency', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
if ($canDelete) {
|
||||
?>
|
||||
<button class="image-button medium" onClick="removeCurrency(<?= $currency['id'] ?>)">
|
||||
<img src="images/siteicons/delete.png" title="<?= translate('delete_currency', $i18n) ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= translate('delete_currency', $i18n) ?>">
|
||||
</button>
|
||||
<?php
|
||||
} else {
|
||||
$cantDeleteMessage = $isMainCurrency ? translate('cant_delete_main_currency', $i18n) : translate('cant_delete_currency_in_use', $i18n);
|
||||
?>
|
||||
<button class="image-button medium disabled">
|
||||
<img src="images/siteicons/delete.png" title="<?= $cantDeleteMessage ?>">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/delete.png" title="<?= $cantDeleteMessage ?>">
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
@ -400,7 +400,7 @@
|
||||
?>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="<?= translate('add', $i18n) ?>" id="addCurrency" onClick="addCurrencyButton()"/>
|
||||
<input type="submit" value="<?= translate('add', $i18n) ?>" id="addCurrency" onClick="addCurrencyButton()" class="thin"/>
|
||||
</div>
|
||||
<div class="settings-notes">
|
||||
<p>
|
||||
@ -478,7 +478,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="addFixerKey" onClick="addFixerKeyButton()"/>
|
||||
<input type="submit" value="<?= translate('save', $i18n) ?>" id="addFixerKey" onClick="addFixerKeyButton()" class="thin"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -555,7 +555,7 @@
|
||||
<input type="file" id="paymenticon" name="paymenticon" accept="image/jpeg, image/png, image/gif, image/webp" onchange="handleFileSelect(event)" class="hidden-input">
|
||||
<input type="hidden" id="icon-url" name="icon-url">
|
||||
<div id="icon-search-button" class="image-button medium disabled" title="<?= translate('search_logo', $i18n) ?>" onClick="searchPaymentIcon()">
|
||||
<img src="images/siteicons/websearch.png">
|
||||
<img src="images/siteicons/<?= $colorTheme ?>/websearch.png">
|
||||
</div>
|
||||
<div id="icon-search-results" class="icon-search">
|
||||
<header>
|
||||
@ -571,14 +571,73 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="account-section">
|
||||
<header>
|
||||
<h2><?= translate('theme_settings', $i18n) ?></h2>
|
||||
</header>
|
||||
<div class="account-settings-theme">
|
||||
<div>
|
||||
<div class="theme-selector">
|
||||
<div class="theme">
|
||||
<label for="theme-blue" class="theme-preview blue <?= $settings['color_theme'] == 'blue' ? 'is-selected' : '' ?>">
|
||||
<input type="radio" name="theme" id="theme-blue" value="blue" onClick="setTheme('blue')" <?= $settings['color_theme'] == 'blue' ? 'checked' : '' ?>>
|
||||
<span class="main-color"></span>
|
||||
<span class="accent-color"></span>
|
||||
<span class="hover-color"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="theme">
|
||||
<label for="theme-green" class="theme-preview green <?= $settings['color_theme'] == 'green' ? 'is-selected' : '' ?>">
|
||||
<input type="radio" name="theme" id="theme-green" value="green" onClick="setTheme('green')" <?= $settings['color_theme'] == 'green' ? 'checked' : '' ?>>
|
||||
<span class="main-color"></span>
|
||||
<span class="accent-color"></span>
|
||||
<span class="hover-color"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="theme">
|
||||
<label for="theme-red" class="theme-preview red <?= $settings['color_theme'] == 'red' ? 'is-selected' : '' ?>">
|
||||
<input type="radio" name="theme" id="theme-red" value="red" onClick="setTheme('red')" <?= $settings['color_theme'] == 'red' ? 'checked' : '' ?>>
|
||||
<span class="main-color"></span>
|
||||
<span class="accent-color"></span>
|
||||
<span class="hover-color"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="theme">
|
||||
<label for="theme-yellow" class="theme-preview yellow <?= $settings['color_theme'] == 'yellow' ? 'is-selected' : '' ?>">
|
||||
<input type="radio" name="theme" id="theme-yellow" value="yellow" onClick="setTheme('yellow')" <?= $settings['color_theme'] == 'yellow' ? 'checked' : '' ?>>
|
||||
<span class="main-color"></span>
|
||||
<span class="accent-color"></span>
|
||||
<span class="hover-color"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2><?= translate('custom_colors', $i18n) ?></h2>
|
||||
<div class="form-group-inline wrap">
|
||||
<div class="color-picker-wrapper wrap">
|
||||
<input type="color" id="mainColor" name="mainColor" value="<?= isset($settings['customColors']['main_color']) ? $settings['customColors']['main_color'] : '#FFFFFF' ?>" class="color-picker fa-solid fa-eye-dropper">
|
||||
<input type="color" id="accentColor" name="accentColor" value="<?= isset($settings['customColors']['accent_color']) ? $settings['customColors']['accent_color'] : '#FFFFFF' ?>" class="color-picker fa-solid fa-eye-dropper">
|
||||
<input type="color" id="hoverColor" name="hoverColor" value="<?= isset($settings['customColors']['hover_color']) ? $settings['customColors']['hover_color'] : '#FFFFFF' ?>" class="color-picker fa-solid fa-eye-dropper">
|
||||
</div>
|
||||
<div class="color-picker-wrapper wrap">
|
||||
<input type="button" value="<?= translate('reset', $i18n) ?>" onClick="resetCustomColors()" class="secondary-button thin" id="reset-colors">
|
||||
<input type="button" value="<?= translate('save', $i18n) ?>" onClick="saveCustomColors()" class="buton thin" id="save-colors">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2><?= translate('dark_theme', $i18n) ?></h2>
|
||||
<div>
|
||||
<input id="switchTheme" type="button" value="<?= translate('switch_theme', $i18n) ?>" onClick="switchTheme()" class="button thin">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="account-section">
|
||||
<header>
|
||||
<h2><?= translate('display_settings', $i18n) ?></h2>
|
||||
</header>
|
||||
<div class="account-settings-list">
|
||||
<div>
|
||||
<input id="switchTheme" type="button" value="<?= translate('switch_theme', $i18n) ?>" onClick="switchTheme()">
|
||||
</div>
|
||||
<div>
|
||||
<div class="form-group-inline">
|
||||
<input type="checkbox" id="monthlyprice" name="monthlyprice" onChange="setShowMonthlyPrice()" <?php if ($settings['monthly_price']) echo 'checked'; ?>>
|
||||
@ -591,6 +650,12 @@
|
||||
<label for="convertcurrency"><?= translate('convert_prices', $i18n) ?></label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="form-group-inline">
|
||||
<input type="checkbox" id="hidedisabled" name="hidedisabled" onChange="setHideDisabled()" <?php if ($settings['hide_disabled']) echo 'checked'; ?>>
|
||||
<label for="hidedisabled"><?= translate('hide_disabled_subscriptions', $i18n) ?></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -616,11 +681,23 @@
|
||||
|
||||
<section class="account-section">
|
||||
<header>
|
||||
<h2><?= translate('export_subscriptions', $i18n) ?></h2>
|
||||
<h2><?= translate('backup_and_restore', $i18n) ?></h2>
|
||||
</header>
|
||||
<div>
|
||||
<input type="button" class="button" value="<?= translate('export_to_json', $i18n) ?>" id="exportToJson" onClick="exportToJson()"/>
|
||||
<div>
|
||||
<div class="form-group-inline">
|
||||
<div>
|
||||
<input type="button" class="button thin" value="<?= translate('backup', $i18n) ?>" id="backupDB" onClick="backupDB()"/>
|
||||
</div>
|
||||
<div>
|
||||
<input type="button" class="secondary-button thin" value="<?= translate('restore', $i18n) ?>" id="restoreDB" onClick="openRestoreDBFileSelect()" />
|
||||
<input type="file" name="restoreDBFile" id="restoreDBFile" style="display: none;" onChange="restoreDB()" accept=".zip">
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-notes">
|
||||
<p>
|
||||
<i class="fa-solid fa-circle-info"></i>
|
||||
<?= translate('restore_info', $i18n) ?>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
@ -8,7 +8,7 @@ body > header {
|
||||
}
|
||||
|
||||
header .logo .logo-image {
|
||||
background-image: url("../images/wallossolidwhite.png");
|
||||
background-image: url("../images/siteicons/blue/walloswhite.png");
|
||||
}
|
||||
|
||||
.split-header > h2 .header-subtitle {
|
||||
@ -96,6 +96,10 @@ input[type="button"].secondary-button:hover {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
input[type="color"] {
|
||||
background-color: #F2F2F2;
|
||||
}
|
||||
|
||||
.avatar-select .avatar-list .remove-avatar {
|
||||
background-color: #222;
|
||||
}
|
||||
@ -133,7 +137,7 @@ input[type="button"].secondary-button:hover {
|
||||
}
|
||||
|
||||
.logo-preview:after {
|
||||
color: #007bff;
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
.sort-options > ul > li {
|
||||
|
||||
151
styles/login.css
@ -90,11 +90,12 @@ select {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
input[type="submit"],
|
||||
input[type="button"] {
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
font-size: 16px;
|
||||
background-color: #007bff;
|
||||
background-color: var(--main-color);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
@ -102,7 +103,21 @@ input[type="submit"] {
|
||||
}
|
||||
|
||||
input[type="submit"]:hover {
|
||||
background-color: #0056b3;
|
||||
background-color: var(--hover-color);
|
||||
}
|
||||
|
||||
input[type="button"].secondary-button,
|
||||
button.button.secondary-button {
|
||||
background-color: #FFFFFF;
|
||||
color: var(--main-color);
|
||||
border: 2px solid var(--main-color);
|
||||
}
|
||||
|
||||
input[type="button"].secondary-button:hover,
|
||||
button.button.secondary-button:hover {
|
||||
background-color: #EEEEEE;
|
||||
color: var(--hover-color);
|
||||
border-color: var(--hover-color);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@ -120,6 +135,134 @@ input[type="checkbox"] {
|
||||
|
||||
.error {
|
||||
display: block;
|
||||
color: red;
|
||||
color: var(--error-color);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.separator {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
/* TOAST MESSAGE */
|
||||
|
||||
.toast {
|
||||
position: fixed;
|
||||
bottom: 25px;
|
||||
right: 30px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #eeeeee;
|
||||
background: #fff;
|
||||
padding: 20px 35px 20px 25px;
|
||||
box-shadow: 0 6px 20px -5px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
transform: translateX(calc(100% + 30px));
|
||||
transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.35);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.toast {
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.toast.active {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
|
||||
.toast .toast-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toast-content .toast-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 35px;
|
||||
min-width: 35px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.toast-content .toast-icon.error {
|
||||
background-color: var(--error-color);
|
||||
}
|
||||
|
||||
.toast-content .toast-icon.success {
|
||||
background-color: var(--success-color);
|
||||
}
|
||||
|
||||
|
||||
.toast-content .message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
.toast-content .message .text {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.toast-content .message .text.text-1 {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.toast .close {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 15px;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.toast .close:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.toast .progress {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
.toast .progress:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.toast .progress.error:before {
|
||||
background-color: var(--error-color);
|
||||
}
|
||||
|
||||
.toast .progress.success:before {
|
||||
background-color: var(--success-color);
|
||||
}
|
||||
|
||||
.progress.active:before {
|
||||
animation: progress 5s linear forwards;
|
||||
}
|
||||
|
||||
@keyframes progress {
|
||||
100% {
|
||||
right: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* TOAST END */
|
||||
@ -52,7 +52,7 @@ h2, h3 {
|
||||
}
|
||||
|
||||
body > header {
|
||||
border-bottom: 7px solid #007bff;
|
||||
border-bottom: 7px solid var(--main-color);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ header .logo .logo-image {
|
||||
height: 50px;
|
||||
width: 134px;
|
||||
margin-right: 10px;
|
||||
background-image: url("../images/wallossolid.png");
|
||||
background-image: url("../images/siteicons/blue/wallos.png");
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
@ -193,8 +193,8 @@ main > .contain {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
color: #fff;
|
||||
border: 1px solid #007bff;
|
||||
background-color: #007bff;
|
||||
border: 1px solid var(--main-color);
|
||||
background-color: var(--main-color);
|
||||
padding: 15px 30px;
|
||||
font-size: 1rem;
|
||||
border-radius: 8px;
|
||||
@ -203,8 +203,8 @@ main > .contain {
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #0056b3;
|
||||
border-color: #0056b3;
|
||||
background-color: var(--hover-color);
|
||||
border-color: var(--hover-color);
|
||||
}
|
||||
|
||||
.button.thin {
|
||||
@ -229,7 +229,7 @@ main > .contain {
|
||||
margin-top: -35px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
color: #007bff;
|
||||
color: var(--main-color);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
@ -603,17 +603,17 @@ header #avatar {
|
||||
justify-content: center;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border: 1px solid #007bff;
|
||||
border: 1px solid var(--main-color);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
margin: 0px;
|
||||
box-sizing: border-box;
|
||||
color: #007bff;
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
.avatar-select label.add-avatar:hover {
|
||||
border-color: #8FBFFA;
|
||||
color: #8FBFFA;
|
||||
border-color: var(--accent-color);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.avatar-select .avatar-list .remove-avatar {
|
||||
@ -667,7 +667,7 @@ header #avatar {
|
||||
}
|
||||
|
||||
.image-button > i {
|
||||
color: #0056b3;
|
||||
color: var(--hover-color);
|
||||
font-size: 28px;
|
||||
padding: 2px;
|
||||
}
|
||||
@ -709,7 +709,7 @@ header #avatar {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background-color: #8FBFFA;
|
||||
background-color: var(--accent-color);
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
transition: filter 300ms;
|
||||
@ -766,17 +766,17 @@ header #avatar {
|
||||
.settings-notes > p > span > a {
|
||||
margin-left: 5px;
|
||||
font-size: 13px;
|
||||
color: #8FBFFA;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.credits-list > p > span > a:visited,
|
||||
.settings-notes > p > span > a:visited {
|
||||
color: #8FBFFA;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.settings-notes > p > i,
|
||||
.account-section .notes > p > i {
|
||||
color: #007bff;
|
||||
color: var(--main-color);
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@ -844,6 +844,19 @@ select {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type="color"] {
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
background-color: #222;
|
||||
border: 1px solid var(--hover-color);
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.one-third {
|
||||
max-width: 33%;
|
||||
}
|
||||
@ -872,28 +885,34 @@ input[type="text"].short {
|
||||
input[type="submit"],
|
||||
input[type="button"],
|
||||
button.button {
|
||||
padding: 12px 30px;
|
||||
padding: 15px 30px;
|
||||
font-size: 16px;
|
||||
background-color: #007bff;
|
||||
background-color: var(--main-color);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid #007bff;
|
||||
border: 2px solid var(--main-color);
|
||||
}
|
||||
|
||||
input[type="submit"].thin,
|
||||
input[type="button"].thin,
|
||||
button.button.thin {
|
||||
padding: 13px 30px;
|
||||
}
|
||||
|
||||
input[type="button"].secondary-button,
|
||||
button.button.secondary-button {
|
||||
background-color: #FFFFFF;
|
||||
color: #007bff;
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
input[type="button"].secondary-button:hover,
|
||||
button.button.secondary-button:hover {
|
||||
background-color: #EEEEEE;
|
||||
color: #0056b3;
|
||||
border-color: #0056b3;
|
||||
color: var(--hover-color);
|
||||
border-color: var(--hover-color);
|
||||
}
|
||||
|
||||
input[type="button"].warning-button {
|
||||
@ -907,8 +926,8 @@ input[type="button"].warning-button:hover {
|
||||
}
|
||||
|
||||
input[type="submit"]:hover {
|
||||
background-color: #0056b3;
|
||||
border-color: #0056b3;
|
||||
background-color: var(--hover-color);
|
||||
border-color: var(--hover-color);
|
||||
}
|
||||
|
||||
input[type="submit"]:disabled,
|
||||
@ -1113,7 +1132,7 @@ input[type="text"]:disabled {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: #0056b3;
|
||||
color: var(--hover-color);
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
@ -1133,6 +1152,7 @@ input[type="text"]:disabled {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.icon-preview:after {
|
||||
@ -1141,7 +1161,7 @@ input[type="text"]:disabled {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: #0056b3;
|
||||
color: var(--hover-color);
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
@ -1281,11 +1301,11 @@ input[type="text"]:disabled {
|
||||
}
|
||||
|
||||
.toast-content .toast-icon.error {
|
||||
background-color: #f45a40;
|
||||
background-color: var(--error-color);
|
||||
}
|
||||
|
||||
.toast-content .toast-icon.success {
|
||||
background-color: #188823;
|
||||
background-color: var(--success-color);
|
||||
}
|
||||
|
||||
|
||||
@ -1338,11 +1358,11 @@ input[type="text"]:disabled {
|
||||
}
|
||||
|
||||
.toast .progress.error:before {
|
||||
background-color: #f45a40;
|
||||
background-color: var(--error-color);
|
||||
}
|
||||
|
||||
.toast .progress.success:before {
|
||||
background-color: #188823;
|
||||
background-color: var(--success-color);
|
||||
}
|
||||
|
||||
.progress.active:before {
|
||||
@ -1401,7 +1421,7 @@ input[type="text"]:disabled {
|
||||
|
||||
.statistic > span {
|
||||
font-size: 42px;
|
||||
color: #0056b3;
|
||||
color: var(--hover-color);
|
||||
}
|
||||
|
||||
.statistic > .title {
|
||||
@ -1411,7 +1431,7 @@ input[type="text"]:disabled {
|
||||
|
||||
.statistic > .subtitle {
|
||||
font-size: 25px;
|
||||
color: #8FBFFA;
|
||||
color: var(--accent-color);
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
@ -1486,8 +1506,8 @@ input[type="text"]:disabled {
|
||||
|
||||
.sortable-list .sortable-ghost {
|
||||
border-radius: 16px;
|
||||
background-color: #c1d9f7;
|
||||
border: 1px solid #8FBFFA;
|
||||
background-color: rgba(var(--accent-color-rgb), 0.6);
|
||||
border: 1px solid var(--accent-color);
|
||||
}
|
||||
|
||||
/* Fitler dropdown */
|
||||
@ -1567,7 +1587,7 @@ input[type="text"]:disabled {
|
||||
}
|
||||
|
||||
.filtermenu-content .filter-title.filter-clear {
|
||||
color: #0056b3;
|
||||
color: var(--hover-color);
|
||||
font-weight: normal;
|
||||
border-bottom: none;
|
||||
}
|
||||
@ -1588,3 +1608,115 @@ input[type="text"]:disabled {
|
||||
.filtermenu-submenu-content.is-open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Theme Selector */
|
||||
|
||||
.theme-selector {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.theme-preview {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
padding: 20px 15px 20px 10px;
|
||||
}
|
||||
|
||||
.theme-preview.is-selected {
|
||||
border: 1px solid var(--main-color);
|
||||
}
|
||||
|
||||
.theme-preview:hover {
|
||||
background-color: rgba(var(--accent-color-rgb), 0.6);
|
||||
}
|
||||
|
||||
.theme-preview > .main-color,
|
||||
.theme-preview > .accent-color,
|
||||
.theme-preview > .hover-color {
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border: 1px solid #FFF;
|
||||
}
|
||||
|
||||
.theme-preview.blue > .main-color {
|
||||
background-color: #007bff;
|
||||
}
|
||||
|
||||
.theme-preview.blue > .accent-color {
|
||||
background-color: #8fbffa;
|
||||
}
|
||||
|
||||
.theme-preview.blue > .hover-color {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.theme-preview.green > .main-color {
|
||||
background-color: #6B8E23;
|
||||
}
|
||||
|
||||
.theme-preview.green > .accent-color {
|
||||
background-color: #9ACD32;
|
||||
}
|
||||
|
||||
.theme-preview.green > .hover-color {
|
||||
background-color: #556B2F;
|
||||
}
|
||||
|
||||
.theme-preview.red > .main-color {
|
||||
background-color: #f45a40;
|
||||
}
|
||||
|
||||
.theme-preview.red > .accent-color {
|
||||
background-color: #f79988;
|
||||
}
|
||||
|
||||
.theme-preview.red > .hover-color {
|
||||
background-color: #c73f29;
|
||||
}
|
||||
|
||||
.theme-preview.yellow > .main-color {
|
||||
background-color: #ffae00;
|
||||
}
|
||||
|
||||
.theme-preview.yellow > .accent-color {
|
||||
background-color: #faea8f;
|
||||
}
|
||||
|
||||
.theme-preview.yellow > .hover-color {
|
||||
background-color: #cd930c;
|
||||
}
|
||||
|
||||
.color-picker-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.color-picker::before {
|
||||
color: var(--hover-color);
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -5px;
|
||||
border: 1px solid;
|
||||
border-radius: 15px;
|
||||
background-color: white;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||