summaryrefslogtreecommitdiff
path: root/pages/money.inc
diff options
context:
space:
mode:
authorRaindropsSys <raindrops@equestria.dev>2024-01-13 16:12:11 +0100
committerRaindropsSys <raindrops@equestria.dev>2024-01-13 16:12:11 +0100
commit2b192b3840ac344c456b98304ea400f0af90da15 (patch)
tree081ba8cbc0add17f08c9b94fb4a830834d87c259 /pages/money.inc
parent2bfdb0ab2e366007269d1b77446f1581801e05dc (diff)
downloadpluralconnect-2b192b3840ac344c456b98304ea400f0af90da15.tar.gz
pluralconnect-2b192b3840ac344c456b98304ea400f0af90da15.tar.bz2
pluralconnect-2b192b3840ac344c456b98304ea400f0af90da15.zip
Updated 46 files and deleted 19 files (automated)
Diffstat (limited to 'pages/money.inc')
-rw-r--r--pages/money.inc822
1 files changed, 0 insertions, 822 deletions
diff --git a/pages/money.inc b/pages/money.inc
deleted file mode 100644
index 881c618..0000000
--- a/pages/money.inc
+++ /dev/null
@@ -1,822 +0,0 @@
-<?php
-
-$minimumRaindrops = 100;
-//$minimumCloudburst = 2762.89;
-//$minimumCloudburst = 700;
-$minimumCloudburst = 0;
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages; global $_PROFILE;
-$parts = explode("/", $_GET["_"]);
-
-$accounts = array_map(function ($i) {
- $name = substr($i, 0, -5);
- $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $i), true);
- $data["_name"] = $name;
- return $data;
-}, array_values(array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money"), function ($i) { return !str_starts_with($i, "."); })));
-
-require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/functions.inc";
-
-global $parts;
-if (isset($parts[2])) {
- if (str_contains($parts[2], "/") || !file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $parts[2] . ".json")) {
- header("Location: /-/money");
- die();
- }
-}
-
-$systemID = $_PROFILE["login"] === "cloudburst" ? "ynmuc" : "gdapd";
-$fronters = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($_PROFILE["login"] === "cloudburst" ? "ynmuc" : "gdapd") . "/fronters.json"), true)["members"];
-
-if (!isset($parts[2])) {
- unset($systemID);
-} else {
- $systemID = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $parts[2] . ".json"), true)["owner"] === "cloudburst" ? "ynmuc" : "gdapd";
-}
-
-if (count($fronters) > 0) {
- $myId = $fronters[0]["id"];
-} else {
- $myId = "zdtsg";
-}
-
-if ((isset($_GET["create"]) || isset($_GET["delete"])) && isset($parts[2])) {
- $account = array_values(array_filter($accounts, function ($i) use ($parts) { return $i["_name"] === $parts[2]; }))[0];
-
- header("Content-Type: text/plain");
-
- if (isset($_GET["create"])) {
- if (!(isset($_GET["amount"]) && is_numeric($_GET["amount"]) && (float)$_GET["amount"] < 9999 && (float)$_GET["amount"] > -9999)) {
- header("Location: /-/money/" . $parts[2]);
- die();
- }
- if (!isset($_GET["description"])) $_GET["description"] = "";
- $_GET["description"] = substr($_GET["description"], 0, 150);
-
- $ntfy = $GLOBALS["ColdHazeApp"]["ntfy"];
- file_get_contents('https://' . $ntfy["server"] . '/' . $ntfy["topic"], false, stream_context_create([
- 'http' => [
- 'method' => 'POST',
- 'header' =>
- "Content-Type: text/plain\r\n" .
- "Title: " . formatPonypush((getMember($myId)["display_name"] ?? getMember($myId)["name"]) . " created a transaction to " . $account["name"] . " (" . ucfirst($account["owner"]) . ")") . "\r\n" .
- "Tags: bits\r\n" .
- "Authorization: Basic " . base64_encode($ntfy["user"] . ":" . $ntfy["password"]),
- 'content' => formatPonypush(($account["currency"] === "gbp" ? "£" : "€") . abs((float)$_GET["amount"]) . " were " . ((float)$_GET["amount"] >= 0 ? "added" : "removed") . " just now" . (trim($_GET["description"]) !== "" ? ": " . $_GET["description"] : ""))
- ]
- ]));
-
- if ((float)$_GET["amount"] !== 0.0) array_unshift($account["transactions"], [
- "author" => $myId,
- "description" => $_GET["description"],
- "amount" => (float)$_GET["amount"],
- "date" => date('c')
- ]);
-
- $name = $account["_name"];
- unset($account["_name"]);
-
- file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $name . ".json", json_encode($account, JSON_PRETTY_PRINT));
- } else {
- if (isset($_GET["id"]) && is_numeric($_GET["id"]) && isset($account["transactions"][(int)$_GET["id"]])) {
- $ntfy = $GLOBALS["ColdHazeApp"]["ntfy"];
- file_get_contents('https://' . $ntfy["server"] . '/' . $ntfy["topic"], false, stream_context_create([
- 'http' => [
- 'method' => 'POST',
- 'header' =>
- "Content-Type: text/plain\r\n" .
- "Title: " . formatPonypush((getMember($myId)["display_name"] ?? getMember($myId)["name"]) . " deleted a transaction from " . $account["name"] . " (" . ucfirst($account["owner"]) . ")") . "\r\n" .
- "Tags: bits\r\n" .
- "Authorization: Basic " . base64_encode($ntfy["user"] . ":" . $ntfy["password"]),
- 'content' => formatPonypush(($account["currency"] === "gbp" ? "£" : "€") . abs((float)$account["transactions"][(int)$_GET["id"]]["amount"]) . " " . ((float)$account["transactions"][(int)$_GET["id"]]["amount"] >= 0 ? "advance" : "withdrawal") . " created by " . (getMemberWithoutSystem($account["transactions"][(int)$_GET["id"]]["author"])["display_name"] ?? getMemberWithoutSystem($account["transactions"][(int)$_GET["id"]]["author"])["name"]) . " " . timeAgo($account["transactions"][(int)$_GET["id"]]["date"]))
- ]
- ]));
-
- unset($account["transactions"][(int)$_GET["id"]]);
-
- $name = $account["_name"];
- unset($account["_name"]);
-
- file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $name . ".json", json_encode($account, JSON_PRETTY_PRINT));
- }
- }
-
- header("Location: /-/money/" . $parts[2]);
- die();
-}
-
-$rate = (float)trim(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/exchange.txt"));
-
-require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc';
-$transactionMonths = [];
-
-foreach ($accounts as $account) {
- array_push($transactionMonths, ...array_map(function ($i) { return date('Y-m', strtotime($i["date"])); }, array_filter($account["transactions"], function ($i) { return !isset($i["initial"]) || !$i["initial"]; })));
-}
-
-$months = [
- ...[
- "2022-12", "2022-11", "2022-10", "2022-09",
- "2022-08", "2022-07", "2022-06"
- ],
- ...array_values(array_filter(array_unique(array_reduce($transactionMonths, function ($a, $b) {
- return [...$a, $b];
- }, [])), function ($i) {
- return $i !== date('Y-m');
- }))
-];
-
-$monthlyCloudburst = [];
-$monthlyRaindrops = [];
-
-$bits = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/bits.json"), true);
-$projects = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/projects.json"), true);
-
-foreach ($bits["cloudburst"] as $month => $value) {
- $monthlyCloudburst[$month] = $value;
-}
-
-foreach ($bits["raindrops"] as $month => $value) {
- $monthlyRaindrops[$month] = $value;
-}
-
-foreach ($months as $month) {
- $gainedCloudburst = $monthlyCloudburst[$month] ?? 0;
- $gainedRaindrops = $monthlyRaindrops[$month] ?? 0;
-
- foreach ($accounts as $account) {
- foreach ($account["transactions"] as $transaction) {
- if (isset($transaction["initial"]) && $transaction["initial"]) continue;
- if (date('Y-m', strtotime($transaction["date"])) !== $month) continue;
-
- if ($account["owner"] === "raindrops") {
- $gainedRaindrops += $transaction["amount"];
- } else {
- $gainedCloudburst += $transaction["amount"];
- }
- }
- }
-
- $monthlyCloudburst[$month] = $gainedCloudburst;
- $monthlyRaindrops[$month] = $gainedRaindrops;
-}
-
-uksort($monthlyCloudburst, function ($k1, $k2) {
- return strtotime($k2) - strtotime($k1);
-});
-
-uksort($monthlyRaindrops, function ($k1, $k2) {
- return strtotime($k2) - strtotime($k1);
-});
-
-function getMonthlyEarnings(): array {
- global $monthlyRaindrops;
- global $monthlyCloudburst;
-
- return [
- "cloudburst" => array_sum(array_values($monthlyCloudburst)) / count($monthlyCloudburst),
- "raindrops" => array_sum(array_values($monthlyRaindrops)) / count($monthlyRaindrops)
- ];
-}
-
-?>
-
-<script src="/assets/editor/chart.js"></script>
-
-<style>
- a:hover > .card {
- opacity: .75;
- }
-
- a:active > .card, a:focus > .card {
- opacity: .5;
- }
-
- <?php global $use2023UI; if (!$use2023UI): ?>
- .list-group-item {
- color: #fff;
- background-color: #222;
- border: 1px solid rgba(255, 255, 255, .125);
- }
-
- .list-group-item.disabled {
- color: #fff;
- background-color: #222;
- border-color: rgba(255, 255, 255, .125);
- opacity: .75;
- }
-
- .list-group-item-action:hover {
- background-color: #252525;
- color: #ddd;
- }
-
- .list-group-item-action:active, .list-group-item-action:focus {
- background-color: #272727;
- color: #bbb;
- }
-
- .modal-header {
- border-bottom: 1px solid #353738;
- }
-
- .modal-content {
- border: 1px solid rgba(255, 255, 255, .2);
- background-color: #111;
- }
- <?php endif; ?>
-
- .btn-close {
- filter: invert(1);
- }
-
- .text-danger, .text-success {
- filter: invert(1) brightness(150%) hue-rotate(180deg);
- }
-</style>
-
-<br>
-<div class="container">
- <?php if (count($parts) < 3): ?>
- <div>
- <h2>Money tracker</h2>
-
- <div class="alert alert-danger">
- <b>The Ponycule money tracker is deprecated and will be removed.</b> Data currently in the money tracker will be moved to individual accounts on a dedicated money tracking application that Equestria.dev will not have control over.
- </div>
-
- <hr>
-
- <?php
-
- $allAccounts = array_reduce(array_map(function ($i) {
- return calculateFullAmount($i, true, true);
- }, $accounts), function ($a, $b) {
- return $a + $b;
- });
-
- ?>
- <h2>£<?= number_format($allAccounts, 2, '.', ',') ?> · €<?= number_format($allAccounts * (1 / $rate), 2, '.', ',') ?></h2>
- <p>As of <?= date('j F Y') ?> · €1.00 = £<?= number_format($rate, 2, '.', ',') ?></p>
-
- <canvas id="history" style="margin-top: 10px; width: 100%; height: 400px; max-height: 100%;"></canvas>
- <?php
-
- $balance = 0;
- $history = [];
- $dates = [];
-
- $transactions1 = array_reduce(array_values(array_filter($accounts, function ($i) { return $i["owner"] === "raindrops"; })), function ($a, $b) {
- return [...$a, ...$b["transactions"]];
- }, []);
-
- $transactions2 = array_reduce(array_values(array_filter($accounts, function ($i) { return $i["owner"] === "cloudburst"; })), function ($a, $b) {
- return [...$a, ...$b["transactions"]];
- }, []);
- $transactions2 = array_map(function ($i) use ($rate) {
- $i["amount"] = $i["amount"] * (1/$rate);
- return $i;
- }, $transactions2);
-
- $transactions = [...$transactions1, ...$transactions2];
- usort($transactions, function ($a, $b) {
- return strtotime($a["date"]) - strtotime($b["date"]);
- });
-
- foreach ($transactions as $transaction) {
- $balance += $transaction["amount"];
- $history[] = $balance;
- $dates[] = date('j M Y, H:i', strtotime($transaction["date"]));
- }
-
- global $palette;
-
- ?>
- <script>
- const ctx3 = document.getElementById('history').getContext('2d');
- const graph3 = new Chart(ctx3, {
- type: 'line',
- data: {
- labels: JSON.parse(`<?= json_encode($dates) ?>`),
- datasets: [{
- label: 'Balance',
- data: JSON.parse(`<?= json_encode($history) ?>`),
- borderColor: '#<?= $use2023UI ? $palette[9] : "b9f1ef" ?>',
- backgroundColor: '#<?= $use2023UI ? $palette[9] : "b9f1ef77" ?>',
- lineTension: 0.4
- }]
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- ticks: {
- callback: function(label) {
- return '€' + Math.round(label);
- }
- },
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- elements: {
- point: {
- radius: 0
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- callbacks: {
- label: function(tooltipItem) {
- return '€' + tooltipItem.raw.toFixed(2);
- }
- },
- intersect: false
- }
- }
- }
- })
- </script>
-
- <hr>
-
- <h4>Cloudburst System (<?php
-
- $allAccounts = array_reduce(array_map(function ($i) {
- return calculateFullAmount($i, true, true);
- }, array_values(array_filter($accounts, function ($i) { return $i["owner"] === "cloudburst"; }))), function ($a, $b) {
- return $a + $b;
- });
-
- ?>£<?= number_format($allAccounts, 2, '.', ',') ?>, earning £<?= number_format(getMonthlyEarnings()["cloudburst"], 2, '.', ',') ?>/month)</h4>
- <div class="list-group">
- <details class="list-group-item list-group-item-action" style="margin-bottom: 10px;">
- <summary>Show monthly earnings</summary>
-
- <table style="margin-top: 10px;">
- <?php foreach ($monthlyCloudburst as $month => $value): ?>
- <tr>
- <td style="padding-right: 20px;"><b><?= date('F Y', strtotime($month)) ?>:</b></td>
- <td class="text-<?= $value > 0 ? "success" : ($value === 0 ? "warning" : "danger") ?>">£<?= number_format($value, 2, '.', ',') ?></td>
- </tr>
- <?php endforeach; ?>
- </table>
- </details>
- </div>
- <div style="display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px;">
- <?php foreach ($accounts as $index => $account): if ($account["owner"] === "cloudburst"): ?>
- <a style="color: white; text-decoration: none;" href="/-/money/<?= $account["_name"] ?>">
- <div class="card">
- <div class="card-body">
- <h4 class="card-title"><?= $account["currency"] === "gbp" ? "£" : "€" ?><?= calculateFullAmount($account); ?></h4>
- <?= $account["name"] ?><?php if ($account["default"]): ?> <span class="badge bg-success rounded-pill">Default</span><?php endif; ?><?php if (isset($account["interests"])): ?> · <?= $account["interests"] * 100 ?>% interests<?php endif; ?>
- <?php if (isset($account["max"])): ?><br><span class="text-muted">Max balance: <?= $account["currency"] === "gbp" ? "£" : "€" ?><?= number_format($account["max"], 2, '.', ',') ?> (<?= round((calculateFullAmount($account, true) / $account["max"]) * 100, 2) ?>% used)</span><?php else: ?><br><span class="text-muted">No maximum balance</span><?php endif; ?>
- </div>
- </div>
- </a>
- <?php endif; endforeach; ?>
- </div>
-
- <div class="progress" style="margin-top: 20px;">
- <?php
-
- $part1 = 0;
- $part2 = 1;
- $difference = 0;
-
- if ($allAccounts > $minimumCloudburst) {
- $part2 = ($allAccounts - $minimumCloudburst) / $allAccounts;
- $part1 = 1 - $part2;
- $difference = $allAccounts - $minimumCloudburst;
- } else {
- $part1 = 1;
- $part2 = 0;
- $difference = $minimumCloudburst - $allAccounts;
- }
-
- ?>
- <div class="progress-bar bg-danger" style="width:<?= $part1 * 100 ?>%"></div>
- <div class="progress-bar bg-success" style="width:<?= $part2 * 100 ?>%"></div>
- </div>
- <p style="text-align: center; margin-top: 5px;" class="<?= $allAccounts > $minimumCloudburst ? "" : "bold text-danger" ?>">£<?= number_format($difference, 2, '.', ',') ?><?php if ($allAccounts > $minimumCloudburst): ?> (<?= round($part2 * 100, 2) ?>%)<?php endif; ?> <?= $allAccounts > $minimumCloudburst ? "over" : "under" ?> the minimum</p>
-
- <?php if (isset($projects["cloudburst"]) && $projects["cloudburst"]["enable"]): ?>
- <div class="grid" style="margin-bottom: 10px; display: grid; grid-template-columns: 25% 1fr; grid-gap: 20px;">
- <div style="width: 100%; display: flex; align-items: center; justify-content: center;">
- <img src="<?= $projects["cloudburst"]["image"] ?>" style="width: 100%;">
- </div>
- <div style="display: flex; align-items: center;">
- <div style="width: 100%;">
- <h2><?= strip_tags($projects["cloudburst"]["name"]) ?></h2>
- <div class="progress" style="margin-top: 20px; margin-bottom: 20px; width: 100%; background-color: #222;">
- <div class="progress-bar bg-success" style="width: <?= ($allAccounts - $minimumRaindrops >= 0) ? (($allAccounts - $minimumRaindrops) / $projects["raindrops"]["cost"]) * 100 : 0 ?>%"></div>
- </div>
- <?php $missing = $projects["cloudburst"]["cost"] - ($allAccounts - $minimumCloudburst); if ($missing > 0): $months = ceil($missing / getMonthlyEarnings()["cloudburst"]); ?>
- <div>Costs £<?= number_format($projects["cloudburst"]["cost"], 2, '.', ',') ?> · Missing £<?= number_format($missing, 2, '.', ',') ?> · Can afford it in <?= date('F Y', time() + ($months * 2678400)) ?> (in <?= $months ?> month<?= $months > 1 ? "s" : "" ?>)</div>
- <?php elseif ($missing === 0): ?><div>You can afford it now, this will take you to the minimum.</div>
- <?php else: ?><div>You can afford it now, this will take you £<?= -$missing ?> above the minimum.</div><?php endif; ?>
- </div>
- </div>
- </div>
- <?php endif; ?>
-
- <canvas id="history-cloudburst" style="margin-top: 10px; width: 100%; height: 200px; max-height: 100%;"></canvas>
- <?php
-
- $balance = 0;
- $history = [];
- $dates = [];
-
- $transactions = array_reduce(array_values(array_filter($accounts, function ($i) { return $i["owner"] === "cloudburst"; })), function ($a, $b) {
- return [...$a, ...$b["transactions"]];
- }, []);
- usort($transactions, function ($a, $b) {
- return strtotime($a["date"]) - strtotime($b["date"]);
- });
-
- foreach ($transactions as $transaction) {
- $balance += $transaction["amount"];
- $history[] = $balance;
- $dates[] = date('j M Y, H:i', strtotime($transaction["date"]));
- }
-
- ?>
- <script>
- const ctx = document.getElementById('history-cloudburst').getContext('2d');
- const graph = new Chart(ctx, {
- type: 'line',
- data: {
- labels: JSON.parse(`<?= json_encode($dates) ?>`),
- datasets: [{
- label: 'Balance',
- data: JSON.parse(`<?= json_encode($history) ?>`),
- borderColor: '#<?= $use2023UI ? $palette[9] : "ff6ae6" ?>',
- backgroundColor: '#<?= $use2023UI ? $palette[9] : "ff6ae677" ?>',
- lineTension: 0.4
- }]
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- ticks: {
- callback: function(label) {
- return '£' + Math.round(label);
- }
- },
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- elements: {
- point: {
- radius: 0
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- callbacks: {
- label: function(tooltipItem) {
- return '£' + tooltipItem.raw.toFixed(2);
- }
- },
- intersect: false
- }
- }
- }
- })
- </script>
-
- <h4 style="margin-top: 20px;">Raindrops System (<?php
-
- $allAccounts = array_reduce(array_map(function ($i) {
- return calculateFullAmount($i, true);
- }, array_values(array_filter($accounts, function ($i) { return $i["owner"] === "raindrops"; }))), function ($a, $b) {
- return $a + $b;
- });
-
- ?>€<?= number_format($allAccounts, 2, '.', ',') ?>, earning €<?= number_format(getMonthlyEarnings()["raindrops"], 2, '.', ',') ?>/month)</h4>
- <div class="list-group">
- <details class="list-group-item list-group-item-action" style="margin-bottom: 10px;">
- <summary>Show monthly earnings</summary>
-
- <table style="margin-top: 10px;">
- <?php foreach ($monthlyRaindrops as $month => $value): ?>
- <tr>
- <td style="padding-right: 20px;"><b><?= date('F Y', strtotime($month)) ?>:</b></td>
- <td class="text-<?= $value > 0 ? "success" : ($value === 0 ? "warning" : "danger") ?>">€<?= number_format($value, 2, '.', ',') ?></td>
- </tr>
- <?php endforeach; ?>
- </table>
- </details>
- </div>
- <div style="display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px;">
- <?php foreach ($accounts as $index => $account): if ($account["owner"] === "raindrops"): ?>
- <a style="color: white; text-decoration: none;" href="/-/money/<?= $account["_name"] ?>">
- <div class="card">
- <div class="card-body">
- <h4 class="card-title"><?= $account["currency"] === "gbp" ? "£" : "€" ?><?= calculateFullAmount($account); ?></h4>
- <?= $account["name"] ?><?php if ($account["default"]): ?> <span class="badge bg-success rounded-pill">Default</span><?php endif; ?><?php if (isset($account["interests"])): ?> · <?= $account["interests"] * 100 ?>% interests<?php endif; ?>
- <?php if (isset($account["max"])): ?><br><span class="text-muted">Max balance: <?= $account["currency"] === "gbp" ? "£" : "€" ?><?= number_format($account["max"], 2, '.', ',') ?> (<?= round((calculateFullAmount($account, true) / $account["max"]) * 100, 2) ?>% used)</span><?php else: ?><br><span class="text-muted">No maximum balance</span><?php endif; ?>
- </div>
- </div>
- </a>
- <?php endif; endforeach; ?>
- </div>
-
- <div class="progress" style="margin-top: 20px;">
- <?php
-
- $part1 = 0;
- $part2 = 1;
- $difference = 0;
-
- if ($allAccounts > $minimumRaindrops) {
- $part2 = ($allAccounts - $minimumRaindrops) / $allAccounts;
- $part1 = 1 - $part2;
- $difference = $allAccounts - $minimumRaindrops;
- } else {
- $part1 = 1;
- $part2 = 0;
- $difference = $minimumRaindrops - $allAccounts;
- }
-
- ?>
- <div class="progress-bar bg-danger" style="width:<?= $part1 * 100 ?>%"></div>
- <div class="progress-bar bg-success" style="width:<?= $part2 * 100 ?>%"></div>
- </div>
- <p style="text-align: center; margin-top: 5px;" class="<?= $allAccounts > $minimumRaindrops ? "" : "bold text-danger" ?>">€<?= number_format($difference, 2, '.', ',') ?><?php if ($allAccounts > $minimumRaindrops): ?> (<?= round($part2 * 100, 2) ?>%)<?php endif; ?> <?= $allAccounts > $minimumRaindrops ? "over" : "under" ?> the minimum</p>
-
- <?php if (isset($projects["raindrops"]) && $projects["raindrops"]["enable"]): ?>
- <div class="grid" style="margin-bottom: 10px; display: grid; grid-template-columns: 25% 1fr; grid-gap: 20px;">
- <div style="width: 100%; display: flex; align-items: center; justify-content: center;">
- <img src="<?= $projects["raindrops"]["image"] ?>" style="width: 100%;">
- </div>
- <div style="display: flex; align-items: center;">
- <div style="width: 100%;">
- <h2><?= strip_tags($projects["raindrops"]["name"]) ?></h2>
- <div class="progress" style="margin-top: 20px; margin-bottom: 20px; width: 100%; background-color: #222;">
- <div class="progress-bar bg-success" style="width: <?= ($allAccounts - $minimumRaindrops >= 0) ? (($allAccounts - $minimumRaindrops) / $projects["raindrops"]["cost"]) * 100 : 0 ?>%"></div>
- </div>
- <?php $missing = $projects["raindrops"]["cost"] - ($allAccounts - $minimumRaindrops); if ($missing > 0): $months = ceil($missing / getMonthlyEarnings()["raindrops"]); ?>
- <div>Costs €<?= number_format($projects["raindrops"]["cost"], 2, '.', ',') ?> · Missing €<?= number_format($missing, 2, '.', ',') ?> · Can afford it in <?= date('F Y', time() + ($months * 2678400)) ?> (in <?= $months ?> month<?= $months > 1 ? "s" : "" ?>)</div>
- <?php elseif ($missing === 0): ?><div>You can afford it now, this will take you to the minimum.</div>
- <?php else: ?><div>You can afford it now, this will take you €<?= -$missing ?> above the minimum.</div><?php endif; ?>
- </div>
- </div>
- </div>
- <?php endif; ?>
-
- <canvas id="history-raindrops" style="margin-top: 10px; width: 100%; height: 200px; max-height: 100%;"></canvas>
- <?php
-
- $balance = 0;
- $history = [];
- $dates = [];
-
- $transactions = array_reduce(array_values(array_filter($accounts, function ($i) { return $i["owner"] === "raindrops"; })), function ($a, $b) {
- return [...$a, ...$b["transactions"]];
- }, []);
- usort($transactions, function ($a, $b) {
- return strtotime($a["date"]) - strtotime($b["date"]);
- });
-
- foreach ($transactions as $transaction) {
- $balance += $transaction["amount"];
- $history[] = $balance;
- $dates[] = date('j M Y, H:i', strtotime($transaction["date"]));
- }
-
- ?>
- <script>
- const ctx2 = document.getElementById('history-raindrops').getContext('2d');
- const graph2 = new Chart(ctx2, {
- type: 'line',
- data: {
- labels: JSON.parse(`<?= json_encode($dates) ?>`),
- datasets: [{
- label: 'Balance',
- data: JSON.parse(`<?= json_encode($history) ?>`),
- borderColor: '#<?= $use2023UI ? $palette[9] : "d7e1ff" ?>',
- backgroundColor: '#<?= $use2023UI ? $palette[9] : "d7e1ff77" ?>',
- lineTension: 0.4
- }]
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- ticks: {
- callback: function(label) {
- return '€' + Math.round(label);
- }
- },
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- elements: {
- point: {
- radius: 0
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- callbacks: {
- label: function(tooltipItem) {
- return '€' + tooltipItem.raw.toFixed(2);
- }
- },
- intersect: false
- }
- }
- }
- })
- </script>
- </div>
- <?php else: $account = array_values(array_filter($accounts, function ($i) use ($parts) { return $i["_name"] === $parts[2]; }))[0]; ?>
- <h2>
- <?= $account["owner"] === "cloudburst" ? "Cloudburst System" : "Raindrops System" ?> · <?= $account["name"] ?><?php if ($account["default"]): ?><span class="text-muted"> (default)</span><?php endif; ?>
- <a href="/-/money" class="small btn btn-outline-<?= $use2023UI ? "primary" : "light" ?>" style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; <?= $use2023UI ? "" : "color: white;" ?>">Back</a>
- </h2>
- <div style="display: grid; grid-template-columns: max-content 1fr; grid-gap: 15px;">
- <h3 style="margin-bottom: 0; display: flex; align-items: center; justify-content: center;"><?= $account["currency"] === "gbp" ? "£" : "€" ?><?= calculateFullAmount($account) ?></h3>
- <div>
- <div><b>Maximum balance:</b> <?php if (isset($account["max"])): ?><?= $account["currency"] === "gbp" ? "£" : "€" ?><?= number_format($account["max"], 2, '.', ',') ?> (<?= round((calculateFullAmount($account, true) / $account["max"]) * 100, 2) ?>% used)<?php else: ?>No maximum balance<?php endif; ?></div>
- <div><b>Interests:</b> <?php if (isset($account["interests"])): ?><?= $account["interests"] * 100 ?>% interests<?php else: ?>None<?php endif; ?></div>
- </div>
- </div>
- <canvas id="history" style="margin-top: 10px; width: 100%; height: 200px; max-height: 100%;"></canvas>
- <?php
-
- $balance = 0;
- $history = [];
- $dates = [];
-
- $transactions = $account["transactions"];
- usort($transactions, function ($a, $b) {
- return strtotime($a["date"]) - strtotime($b["date"]);
- });
-
- foreach ($transactions as $transaction) {
- $balance += $transaction["amount"];
- $history[] = $balance;
- $dates[] = date('j M Y, H:i', strtotime($transaction["date"]));
- }
-
- global $palette;
-
- ?>
- <script>
- const ctx = document.getElementById('history').getContext('2d');
- const graph = new Chart(ctx, {
- type: 'line',
- data: {
- labels: JSON.parse(`<?= json_encode($dates) ?>`),
- datasets: [{
- label: 'Balance',
- data: JSON.parse(`<?= json_encode($history) ?>`),
- borderColor: '#<?= $use2023UI ? $palette[9] : ($account["owner"] === "cloudburst" ? "ff6ae6" : "d7e1ff") ?>',
- backgroundColor: '#<?=$use2023UI ? $palette[9] : ($account["owner"] === "cloudburst" ? "ff6ae677" : "d7e1ff77") ?>',
- lineTension: 0.4
- }]
- },
- options: {
- animation: {
- duration: 0
- },
- scales: {
- y: {
- ticks: {
- callback: function(label) {
- return '<?= $account["currency"] === "gbp" ? "£" : "€" ?>' + Math.round(label);
- }
- },
- grid: {
- color: "rgba(255,255,255,0.25)"
- }
- }
- },
- elements: {
- point: {
- radius: 0
- }
- },
- plugins: {
- legend: {
- display: false
- },
- tooltip: {
- callbacks: {
- label: function(tooltipItem) {
- return '<?= $account["currency"] === "gbp" ? "£" : "€" ?>' + tooltipItem.raw.toFixed(2);
- }
- },
- intersect: false
- }
- }
- }
- })
- </script>
-
- <hr>
-
- <div class="list-group">
- <a href="#" data-bs-toggle="modal" data-bs-target="#create" class="list-group-item list-group-item-action" style="display: grid; grid-template-columns: max-content 1fr;"><img src="<?= $use2023UI ? icon('add', null, true) : "/assets/icons/add.svg" ?>" style="filter: invert(1); margin-right: 10px; height: 32px; width: 32px;"><div style="display: flex; align-items: center;"><b>Add new transaction</b></div></a>
- <?php foreach ($account["transactions"] as $index => $transaction): $member = getMemberWithoutSystem($transaction["author"]) ?? getMemberWithoutSystem("zdtsg"); ?>
- <a id="transaction-<?= $index ?>" onclick="deleteTransaction(<?= $index ?>)" class="list-group-item list-group-item-action" style="display: grid; grid-template-columns: max-content 1fr;cursor:pointer;"><div style="display: flex; align-items: center;"><img src="<?= getAsset($member["_system"], $member["id"]) ?>" style="border-radius: 999px; width: 32px; height: 32px; margin-right: 10px;"></div><div style="display: flex; align-items: center;"><div><b><?= $member["display_name"] ?? $member["name"] ?></b><?= $transaction["amount"] < 0 ? " removed" : " added" ?>&nbsp;<span class="<?= $transaction["amount"] < 0 ? "text-danger" : "text-success" ?>"><?= $account["currency"] === "gbp" ? "£" : "€" ?><?= number_format(abs($transaction["amount"]), 2, '.', ',') ?>&nbsp;</span><?= timeAgo($transaction["date"]) ?><?php if (isset($transaction["description"]) && trim($transaction["description"]) !== "" && (!isset($transaction["initial"]) || !$transaction["initial"])): ?>: <?= strip_tags(trim($transaction["description"])) ?><?php endif; ?><?php if (isset($transaction["initial"]) && $transaction["initial"]): ?> <span class="badge bg-<?= $use2023UI ? "success" : "secondary" ?> rounded-pill">Initial amount</span><?php endif; ?></div></div></a>
- <?php endforeach; ?>
- </div>
-
- <script>
- window.transactions = JSON.parse(atob("<?= base64_encode(json_encode($account["transactions"])) ?>"));
-
- function deleteTransaction(index) {
- document.getElementById("delete-item").innerHTML = document.getElementById("transaction-" + index).innerHTML;
- document.getElementById("delete-link").href = location.pathname + "/?delete&id=" + index;
- new bootstrap.Modal(document.getElementById("delete")).show();
- }
- </script>
-
- <div class="modal fade" id="delete">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title">Delete transaction?</h4>
- <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
- </div>
-
- <div class="modal-body">
- <p>Are you sure you want to delete the following transaction?</p>
-
- <p>
- <div class="list-group">
- <div class="list-group-item" id="delete-item" style="display: grid; grid-template-columns: max-content 1fr;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab eum facere minima officiis quas. Architecto ea eius impedit incidunt ipsa itaque laudantium pariatur quae repudiandae sunt unde vel, veritatis, voluptates.</div>
- </div>
- </p>
-
- <p>Deleting a transaction takes effect immediately and cannot be undone.</p>
- <a href="#" id="delete-link" class="btn btn-<?= $use2023UI ? "primary" : "danger" ?>">Delete</a>
- </div>
- </div>
- </div>
- </div>
-
- <div class="modal fade" id="create">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <h4 class="modal-title">Create new transaction</h4>
- <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
- </div>
-
- <div class="modal-body">
- <form>
- <input type="hidden" name="create">
-
- <label style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 20px;">
- <span style="align-items: center; justify-content: right; display: flex;">Amount (<?= $account["currency"] === "gbp" ? "£" : "€" ?>):</span>
- <input required type="text" pattern="^(-|)\d{1,4}([,.]\d{0,2}|)$" name="amount" class="form-control" placeholder="Amount" style="filter: invert(1) hue-rotate(180deg);" maxlength="7" minlength="1">
- </label>
-
- <label style="margin-top: 10px;display: grid; grid-template-columns: 1fr 1fr; grid-gap: 20px;">
- <span style="align-items: center; justify-content: right; display: flex;">Description:</span>
- <input maxlength="150" type="text" name="description" class="form-control" placeholder="Description" style="filter: invert(1) hue-rotate(180deg);">
- </label>
-
- <p>
- <label style="margin-top: 10px;display: grid; grid-template-columns: 1fr 1fr; grid-gap: 20px;">
- <span style="align-items: center; justify-content: right; display: flex;">Author:</span>
- <input type="text" disabled class="form-control" placeholder="Description" style="filter: invert(1) hue-rotate(180deg);" value="<?= getMemberWithoutSystem($myId)["display_name"] ?? getMemberWithoutSystem($myId)["name"] ?>">
- </label>
- </p>
-
- <p>Adding a transaction takes effect immediately and cannot be modified afterward.</p>
- <button id="delete-link" class="btn btn-<?= $use2023UI ? "primary" : "success" ?>">Create</button>
- </form>
- </div>
- </div>
- </div>
- </div>
- <?php endif; ?>
-</div>
-
-<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>