aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2025-05-01 21:46:32 +0200
committerLinnea Gräf <nea@nea.moe>2025-05-01 21:46:42 +0200
commit00e37dc840f7dd9b4ec8d2aa7c17bebad08a2696 (patch)
treeacd21a461b53b9e2990c9a313cc74efcee6b0c40
parent0c60aa3278a9297e143ee4ad998c01b6ef2337b1 (diff)
downloadLocalTransactionLedger-00e37dc840f7dd9b4ec8d2aa7c17bebad08a2696.tar.gz
LocalTransactionLedger-00e37dc840f7dd9b4ec8d2aa7c17bebad08a2696.tar.bz2
LocalTransactionLedger-00e37dc840f7dd9b4ec8d2aa7c17bebad08a2696.zip
feat(frontend): more stylingHEADmaster
-rw-r--r--flake.lock61
-rw-r--r--flake.nix30
-rw-r--r--server/analysis/src/main/kotlin/moe/nea/ledger/analysis/DailyCashflow.kt52
-rw-r--r--server/frontend/index.html2
-rw-r--r--server/frontend/package.json5
-rw-r--r--server/frontend/pnpm-lock.yaml340
-rw-r--r--server/frontend/pnpm-workspace.yaml3
-rw-r--r--server/frontend/src/Analysis.tsx63
-rw-r--r--server/frontend/src/index.css5
-rw-r--r--server/frontend/src/index.tsx11
-rw-r--r--server/frontend/vite.config.ts2
-rw-r--r--settings.gradle.kts2
12 files changed, 554 insertions, 22 deletions
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..1f98193
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,61 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1745930157,
+ "narHash": "sha256-y3h3NLnzRSiUkYpnfvnS669zWZLoqqI6NprtLQ+5dck=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "46e634be05ce9dc6d4db8e664515ba10b78151ae",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..c508abe
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,30 @@
+{
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ flake-utils.url = "github:numtide/flake-utils";
+ };
+
+ outputs = {
+ self,
+ nixpkgs,
+ flake-utils,
+ ...
+ }:
+ flake-utils.lib.eachDefaultSystem (system: let
+ overlays = [];
+ pkgs = import nixpkgs {inherit system overlays;};
+ deps = [
+ pkgs.jdk8
+ pkgs.jdk21
+ pkgs.nodejs_22
+ pkgs.nodePackages.pnpm
+
+ ];
+ in
+ with pkgs; {
+ devShells.default = mkShell {
+ buildInputs = deps;
+ };
+ formatter = alejandra;
+ });
+} \ No newline at end of file
diff --git a/server/analysis/src/main/kotlin/moe/nea/ledger/analysis/DailyCashflow.kt b/server/analysis/src/main/kotlin/moe/nea/ledger/analysis/DailyCashflow.kt
new file mode 100644
index 0000000..3dcb438
--- /dev/null
+++ b/server/analysis/src/main/kotlin/moe/nea/ledger/analysis/DailyCashflow.kt
@@ -0,0 +1,52 @@
+package moe.nea.ledger.analysis
+
+import com.google.auto.service.AutoService
+import moe.nea.ledger.ItemChange
+import moe.nea.ledger.ItemId
+import moe.nea.ledger.TransactionType
+import moe.nea.ledger.database.DBItemEntry
+import moe.nea.ledger.database.DBLogEntry
+import moe.nea.ledger.database.sql.Clause
+import java.sql.Connection
+import java.time.LocalDate
+import kotlin.collections.component1
+import kotlin.collections.component2
+
+@AutoService(Analysis::class)
+class DailyCashflow : Analysis {
+ override val id: String
+ get() = "daily-cashflow"
+ override val name: String
+ get() = "Daily Cashflow"
+
+ override fun perform(
+ database: Connection,
+ filter: AnalysisFilter
+ ): AnalysisResult {
+ val query = DBLogEntry.from(database)
+ .join(DBItemEntry, Clause { column(DBItemEntry.transactionId) eq column(DBLogEntry.transactionId) })
+ .where(Clause { column(DBItemEntry.itemId) eq ItemId.COINS })
+ .select(DBItemEntry.size, DBLogEntry.transactionId)
+ filter.applyTo(query)
+ val spentThatDay = mutableMapOf<LocalDate, Double>()
+ for (resultRow in query) {
+ val timestamp = resultRow[DBLogEntry.transactionId].getTimestamp()
+ val damage = resultRow[DBItemEntry.size]
+ val localZone = filter.timeZone()
+ val localDate = timestamp.atZone(localZone).toLocalDate()
+ spentThatDay.merge(localDate, damage) { a, b -> a + b }
+ }
+ return AnalysisResult(
+ listOf(
+ Visualization(
+ "Daily Cashflow",
+ xLabel = "Day",
+ yLabel = "Coins +/-",
+ dataPoints = spentThatDay.entries.map { (k, v) ->
+ DataPoint(k.atTime(12, 0).atZone(filter.timeZone()).toInstant(), v)
+ }
+ )
+ )
+ )
+ }
+} \ No newline at end of file
diff --git a/server/frontend/index.html b/server/frontend/index.html
index 48c59fc..afc19c2 100644
--- a/server/frontend/index.html
+++ b/server/frontend/index.html
@@ -9,7 +9,7 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
- <div id="root"></div>
+ <div id="root" class="min-h-[100vh]"></div>
<script src="/src/index.tsx" type="module"></script>
</body>
diff --git a/server/frontend/package.json b/server/frontend/package.json
index a8a8880..e344700 100644
--- a/server/frontend/package.json
+++ b/server/frontend/package.json
@@ -21,11 +21,14 @@
},
"dependencies": {
"@solidjs/router": "^0.15.3",
+ "@tailwindcss/vite": "^4.1.5",
"apexcharts": "^4.3.0",
+ "chartist": "^1.3.1",
"moment": "^2.30.1",
"openapi-fetch": "^0.13.4",
"solid-apexcharts": "^0.4.0",
- "solid-js": "^1.9.3"
+ "solid-js": "^1.9.3",
+ "tailwindcss": "^4.1.5"
},
"devEngines": {
"packageManager": {
diff --git a/server/frontend/pnpm-lock.yaml b/server/frontend/pnpm-lock.yaml
index 6483404..d4b6e96 100644
--- a/server/frontend/pnpm-lock.yaml
+++ b/server/frontend/pnpm-lock.yaml
@@ -11,9 +11,15 @@ importers:
'@solidjs/router':
specifier: ^0.15.3
version: 0.15.3(solid-js@1.9.4)
+ '@tailwindcss/vite':
+ specifier: ^4.1.5
+ version: 4.1.5(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4))
apexcharts:
specifier: ^4.3.0
version: 4.3.0
+ chartist:
+ specifier: ^1.3.1
+ version: 1.3.1
moment:
specifier: ^2.30.1
version: 2.30.1
@@ -26,22 +32,25 @@ importers:
solid-js:
specifier: ^1.9.3
version: 1.9.4
+ tailwindcss:
+ specifier: ^4.1.5
+ version: 4.1.5
devDependencies:
openapi-typescript:
specifier: ^7.5.2
version: 7.5.2(typescript@5.7.3)
solid-devtools:
specifier: ^0.33.0
- version: 0.33.0(solid-js@1.9.4)(vite@6.0.7(sass@1.83.4))
+ version: 0.33.0(solid-js@1.9.4)(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4))
typescript:
specifier: ^5.7.2
version: 5.7.3
vite:
specifier: ^6.0.0
- version: 6.0.7(sass@1.83.4)
+ version: 6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)
vite-plugin-solid:
specifier: ^2.11.0
- version: 2.11.0(solid-js@1.9.4)(vite@6.0.7(sass@1.83.4))
+ version: 2.11.0(solid-js@1.9.4)(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4))
packages:
@@ -600,6 +609,96 @@ packages:
peerDependencies:
'@svgdotjs/svg.js': ^3.2.4
+ '@tailwindcss/node@4.1.5':
+ resolution: {integrity: sha512-CBhSWo0vLnWhXIvpD0qsPephiaUYfHUX3U9anwDaHZAeuGpTiB3XmsxPAN6qX7bFhipyGBqOa1QYQVVhkOUGxg==}
+
+ '@tailwindcss/oxide-android-arm64@4.1.5':
+ resolution: {integrity: sha512-LVvM0GirXHED02j7hSECm8l9GGJ1RfgpWCW+DRn5TvSaxVsv28gRtoL4aWKGnXqwvI3zu1GABeDNDVZeDPOQrw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.1.5':
+ resolution: {integrity: sha512-//TfCA3pNrgnw4rRJOqavW7XUk8gsg9ddi8cwcsWXp99tzdBAZW0WXrD8wDyNbqjW316Pk2hiN/NJx/KWHl8oA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.1.5':
+ resolution: {integrity: sha512-XQorp3Q6/WzRd9OalgHgaqgEbjP3qjHrlSUb5k1EuS1Z9NE9+BbzSORraO+ecW432cbCN7RVGGL/lSnHxcd+7Q==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.1.5':
+ resolution: {integrity: sha512-bPrLWbxo8gAo97ZmrCbOdtlz/Dkuy8NK97aFbVpkJ2nJ2Jo/rsCbu0TlGx8joCuA3q6vMWTSn01JY46iwG+clg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.5':
+ resolution: {integrity: sha512-1gtQJY9JzMAhgAfvd/ZaVOjh/Ju/nCoAsvOVJenWZfs05wb8zq+GOTnZALWGqKIYEtyNpCzvMk+ocGpxwdvaVg==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.1.5':
+ resolution: {integrity: sha512-dtlaHU2v7MtdxBXoqhxwsWjav7oim7Whc6S9wq/i/uUMTWAzq/gijq1InSgn2yTnh43kR+SFvcSyEF0GCNu1PQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.1.5':
+ resolution: {integrity: sha512-fg0F6nAeYcJ3CriqDT1iVrqALMwD37+sLzXs8Rjy8Z1ZHshJoYceodfyUwGJEsQoTyWbliFNRs2wMQNXtT7MVA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.1.5':
+ resolution: {integrity: sha512-SO+F2YEIAHa1AITwc8oPwMOWhgorPzzcbhWEb+4oLi953h45FklDmM8dPSZ7hNHpIk9p/SCZKUYn35t5fjGtHA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.1.5':
+ resolution: {integrity: sha512-6UbBBplywkk/R+PqqioskUeXfKcBht3KU7juTi1UszJLx0KPXUo10v2Ok04iBJIaDPkIFkUOVboXms5Yxvaz+g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-wasm32-wasi@4.1.5':
+ resolution: {integrity: sha512-hwALf2K9FHuiXTPqmo1KeOb83fTRNbe9r/Ixv9ZNQ/R24yw8Ge1HOWDDgTdtzntIaIUJG5dfXCf4g9AD4RiyhQ==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+ bundledDependencies:
+ - '@napi-rs/wasm-runtime'
+ - '@emnapi/core'
+ - '@emnapi/runtime'
+ - '@tybys/wasm-util'
+ - '@emnapi/wasi-threads'
+ - tslib
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.1.5':
+ resolution: {integrity: sha512-oDKncffWzaovJbkuR7/OTNFRJQVdiw/n8HnzaCItrNQUeQgjy7oUiYpsm9HUBgpmvmDpSSbGaCa2Evzvk3eFmA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.1.5':
+ resolution: {integrity: sha512-WiR4dtyrFdbb+ov0LK+7XsFOsG+0xs0PKZKkt41KDn9jYpO7baE3bXiudPVkTqUEwNfiglCygQHl2jklvSBi7Q==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.1.5':
+ resolution: {integrity: sha512-1n4br1znquEvyW/QuqMKQZlBen+jxAbvyduU87RS8R3tUSvByAkcaMTkJepNIrTlYhD+U25K4iiCIxE6BGdRYA==}
+ engines: {node: '>= 10'}
+
+ '@tailwindcss/vite@4.1.5':
+ resolution: {integrity: sha512-FE1stRoqdHSb7RxesMfCXE8icwI1W6zGE/512ae3ZDrpkQYTTYeSyUJPRCjZd8CwVAhpDUbi1YR8pcZioFJQ/w==}
+ peerDependencies:
+ vite: ^5.2.0 || ^6
+
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@@ -663,6 +762,10 @@ packages:
change-case@5.4.4:
resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==}
+ chartist@1.3.1:
+ resolution: {integrity: sha512-pvdQowirS3f59tkIvUl4MJoWAKU/aVv1RqleKzOkXQ0nD4X9uu+7T1cCJSTTnbAvPNuAt9JpUu6+cffvZh5nHg==}
+ engines: {node: '>=14'}
+
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
@@ -693,9 +796,17 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
+ detect-libc@2.0.4:
+ resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
+ engines: {node: '>=8'}
+
electron-to-chromium@1.5.83:
resolution: {integrity: sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==}
+ enhanced-resolve@5.18.1:
+ resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
+ engines: {node: '>=10.13.0'}
+
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
@@ -729,6 +840,9 @@ packages:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
engines: {node: '>=4'}
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
html-entities@2.3.3:
resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
@@ -759,6 +873,10 @@ packages:
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
engines: {node: '>=12.13'}
+ jiti@2.4.2:
+ resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
+ hasBin: true
+
js-levenshtein@1.1.6:
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
engines: {node: '>=0.10.0'}
@@ -783,6 +901,70 @@ packages:
engines: {node: '>=6'}
hasBin: true
+ lightningcss-darwin-arm64@1.29.2:
+ resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.29.2:
+ resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.29.2:
+ resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.29.2:
+ resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.29.2:
+ resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.29.2:
+ resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.29.2:
+ resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.29.2:
+ resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.29.2:
+ resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.29.2:
+ resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.29.2:
+ resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
+ engines: {node: '>= 12.0.0'}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -922,6 +1104,13 @@ packages:
resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==}
engines: {node: '>=12'}
+ tailwindcss@4.1.5:
+ resolution: {integrity: sha512-nYtSPfWGDiWgCkwQG/m+aX83XCwf62sBgg3bIlNiiOcggnS1x3uVRDAuyelBFL+vJdOPPCGElxv9DjHJjRHiVA==}
+
+ tapable@2.2.1:
+ resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+ engines: {node: '>=6'}
+
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -1512,6 +1701,71 @@ snapshots:
dependencies:
'@svgdotjs/svg.js': 3.2.4
+ '@tailwindcss/node@4.1.5':
+ dependencies:
+ enhanced-resolve: 5.18.1
+ jiti: 2.4.2
+ lightningcss: 1.29.2
+ tailwindcss: 4.1.5
+
+ '@tailwindcss/oxide-android-arm64@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-wasm32-wasi@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.1.5':
+ optional: true
+
+ '@tailwindcss/oxide@4.1.5':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.1.5
+ '@tailwindcss/oxide-darwin-arm64': 4.1.5
+ '@tailwindcss/oxide-darwin-x64': 4.1.5
+ '@tailwindcss/oxide-freebsd-x64': 4.1.5
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.5
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.1.5
+ '@tailwindcss/oxide-linux-arm64-musl': 4.1.5
+ '@tailwindcss/oxide-linux-x64-gnu': 4.1.5
+ '@tailwindcss/oxide-linux-x64-musl': 4.1.5
+ '@tailwindcss/oxide-wasm32-wasi': 4.1.5
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.1.5
+ '@tailwindcss/oxide-win32-x64-msvc': 4.1.5
+
+ '@tailwindcss/vite@4.1.5(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4))':
+ dependencies:
+ '@tailwindcss/node': 4.1.5
+ '@tailwindcss/oxide': 4.1.5
+ tailwindcss: 4.1.5
+ vite: 6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)
+
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.26.5
@@ -1589,6 +1843,8 @@ snapshots:
change-case@5.4.4: {}
+ chartist@1.3.1: {}
+
chokidar@4.0.3:
dependencies:
readdirp: 4.1.1
@@ -1611,8 +1867,15 @@ snapshots:
detect-libc@1.0.3:
optional: true
+ detect-libc@2.0.4: {}
+
electron-to-chromium@1.5.83: {}
+ enhanced-resolve@5.18.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.2.1
+
entities@4.5.0: {}
esbuild@0.24.2:
@@ -1659,6 +1922,8 @@ snapshots:
globals@11.12.0: {}
+ graceful-fs@4.2.11: {}
+
html-entities@2.3.3: {}
https-proxy-agent@7.0.6(supports-color@9.4.0):
@@ -1686,6 +1951,8 @@ snapshots:
is-what@4.1.16: {}
+ jiti@2.4.2: {}
+
js-levenshtein@1.1.6: {}
js-tokens@4.0.0: {}
@@ -1700,6 +1967,51 @@ snapshots:
json5@2.2.3: {}
+ lightningcss-darwin-arm64@1.29.2:
+ optional: true
+
+ lightningcss-darwin-x64@1.29.2:
+ optional: true
+
+ lightningcss-freebsd-x64@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.29.2:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.29.2:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.29.2:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.29.2:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.29.2:
+ optional: true
+
+ lightningcss@1.29.2:
+ dependencies:
+ detect-libc: 2.0.4
+ optionalDependencies:
+ lightningcss-darwin-arm64: 1.29.2
+ lightningcss-darwin-x64: 1.29.2
+ lightningcss-freebsd-x64: 1.29.2
+ lightningcss-linux-arm-gnueabihf: 1.29.2
+ lightningcss-linux-arm64-gnu: 1.29.2
+ lightningcss-linux-arm64-musl: 1.29.2
+ lightningcss-linux-x64-gnu: 1.29.2
+ lightningcss-linux-x64-musl: 1.29.2
+ lightningcss-win32-arm64-msvc: 1.29.2
+ lightningcss-win32-x64-msvc: 1.29.2
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -1827,7 +2139,7 @@ snapshots:
defu: 6.1.4
solid-js: 1.9.4
- solid-devtools@0.33.0(solid-js@1.9.4)(vite@6.0.7(sass@1.83.4)):
+ solid-devtools@0.33.0(solid-js@1.9.4)(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)):
dependencies:
'@babel/core': 7.26.0
'@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0)
@@ -1836,7 +2148,7 @@ snapshots:
'@solid-devtools/shared': 0.19.0(solid-js@1.9.4)
solid-js: 1.9.4
optionalDependencies:
- vite: 6.0.7(sass@1.83.4)
+ vite: 6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)
transitivePeerDependencies:
- supports-color
@@ -1859,6 +2171,10 @@ snapshots:
supports-color@9.4.0: {}
+ tailwindcss@4.1.5: {}
+
+ tapable@2.2.1: {}
+
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
@@ -1880,7 +2196,7 @@ snapshots:
validate-html-nesting@1.2.2: {}
- vite-plugin-solid@2.11.0(solid-js@1.9.4)(vite@6.0.7(sass@1.83.4)):
+ vite-plugin-solid@2.11.0(solid-js@1.9.4)(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)):
dependencies:
'@babel/core': 7.26.0
'@types/babel__core': 7.20.5
@@ -1888,23 +2204,25 @@ snapshots:
merge-anything: 5.1.7
solid-js: 1.9.4
solid-refresh: 0.6.3(solid-js@1.9.4)
- vite: 6.0.7(sass@1.83.4)
- vitefu: 1.0.5(vite@6.0.7(sass@1.83.4))
+ vite: 6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)
+ vitefu: 1.0.5(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4))
transitivePeerDependencies:
- supports-color
- vite@6.0.7(sass@1.83.4):
+ vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4):
dependencies:
esbuild: 0.24.2
postcss: 8.5.1
rollup: 4.30.1
optionalDependencies:
fsevents: 2.3.3
+ jiti: 2.4.2
+ lightningcss: 1.29.2
sass: 1.83.4
- vitefu@1.0.5(vite@6.0.7(sass@1.83.4)):
+ vitefu@1.0.5(vite@6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)):
optionalDependencies:
- vite: 6.0.7(sass@1.83.4)
+ vite: 6.0.7(jiti@2.4.2)(lightningcss@1.29.2)(sass@1.83.4)
webidl-conversions@3.0.1: {}
diff --git a/server/frontend/pnpm-workspace.yaml b/server/frontend/pnpm-workspace.yaml
new file mode 100644
index 0000000..012c404
--- /dev/null
+++ b/server/frontend/pnpm-workspace.yaml
@@ -0,0 +1,3 @@
+onlyBuiltDependencies:
+ - '@parcel/watcher'
+ - esbuild
diff --git a/server/frontend/src/Analysis.tsx b/server/frontend/src/Analysis.tsx
index 3bf9c13..3317f68 100644
--- a/server/frontend/src/Analysis.tsx
+++ b/server/frontend/src/Analysis.tsx
@@ -2,6 +2,7 @@ import { createAsync, useParams } from "@solidjs/router"
import { client, getAnalysisList, paths } from "./api.ts";
import { createSignal, For, onMount, Show, Suspense } from "solid-js";
import { SolidApexCharts } from "solid-apexcharts";
+import { BarChart, times } from "chartist";
type AnalysisResult =
{ status: 'not requested' }
@@ -13,11 +14,11 @@ export default function Analysis() {
const analysisId = pathParams.id!;
let analysis = createAsync(() => getAnalysisList());
const analysisName = () => analysis()?.data?.find(it => it.id == analysisId)?.name
- const [startTimestamp, setStartTimestamp] = createSignal(new Date().getTime() - 1000 * 60 * 60 * 24 * 30);
+ const [startTimestamp, setStartTimestamp] = createSignal(new Date().getTime() - 1000 * 60 * 60 * 24 * 356);
const [endTimestamp, setEndTimestamp] = createSignal(new Date().getTime());
const [analysisResult, setAnalysisResult] = createSignal<AnalysisResult>({ status: 'not requested' });
return <>
- <h1><Suspense fallback="Name not loaded...">{analysisName()}</Suspense></h1>
+ <h1 class="text-xl"><Suspense fallback="Name not loaded...">{analysisName()}</Suspense></h1>
<p>
<label>
Start:
@@ -52,13 +53,42 @@ export default function Analysis() {
{element =>
<For each={element().result.visualizations}>
{item =>
- <div>
+ <div class="h-300 max-h-[90vh]">
<SolidApexCharts
- width={1200}
type="bar"
+ width={"100%"}
+ height={"100%"}
options={{
+ colors: ['#b03060'],
xaxis: {
- type: 'numeric'
+ labels: {
+ style: {
+ colors: '#A0A0A0',
+ },
+ formatter(value, timestamp, opts) {
+ return formatDate(timestamp!)
+ },
+ },
+ type: 'numeric',
+ },
+ tooltip: {
+ enabled: false
+ },
+ yaxis: {
+ labels: {
+ style: {
+ colors: '#A0A0A0'
+ },
+ formatter(val, opts) {
+ return formatMoney(val)
+ }
+ },
+ decimalsInFloat: 3
+ },
+ dataLabels: {
+ formatter(val, opts) {
+ return formatMoney(val as number)
+ },
}
}}
series={[
@@ -76,6 +106,29 @@ export default function Analysis() {
</>
}
+const formatMoney = (money: number): string => {
+ if (money < 0) return `-${formatMoney(money)}`
+ const moneyNames = [
+ [1_000_000_000, 'b'],
+ [1_000_000, 'm'],
+ [1_000, 'k'],
+ [1, '']
+ ] as const;
+
+ for (const [factor, name] of moneyNames) {
+ if (money >= factor) {
+ const scaledValue = Math.round(money / factor * 10) / 10
+ return `${scaledValue}${name}`
+ }
+ }
+ return money.toString()
+}
+
+const formatDate = (date: number | Date) => {
+ const _date = new Date(date);
+ return `${_date.getDay()}.${_date.getMonth() + 1}.${_date.getFullYear()}`
+}
+
function takeIf<T extends P, P>(
obj: P,
condition: (arg: P) => arg is T,
diff --git a/server/frontend/src/index.css b/server/frontend/src/index.css
index 4a1df4d..e10ddff 100644
--- a/server/frontend/src/index.css
+++ b/server/frontend/src/index.css
@@ -1,3 +1,6 @@
+@import "tailwindcss";
+
+
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
@@ -10,4 +13,4 @@ body {
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
-}
+} \ No newline at end of file
diff --git a/server/frontend/src/index.tsx b/server/frontend/src/index.tsx
index 610a78b..3009300 100644
--- a/server/frontend/src/index.tsx
+++ b/server/frontend/src/index.tsx
@@ -5,7 +5,7 @@ import 'solid-devtools';
import "./index.css";
import type { RouteDefinition } from "@solidjs/router";
import { Router } from "@solidjs/router";
-import { lazy } from "solid-js";
+import { lazy, onMount } from "solid-js";
const root = document.getElementById("root");
@@ -20,4 +20,11 @@ const routes: Array<RouteDefinition> = [
{ path: "/analysis/:id", component: lazy(() => import("./Analysis.tsx")) },
];
-render(() => <Router>{routes}</Router>, root!);
+const Root = () => {
+
+ return <div class="bg-gray-800 text-white min-h-[100vh]">
+ <Router>{routes}</Router>
+ </div>
+}
+
+render(() => <Root />, root!);
diff --git a/server/frontend/vite.config.ts b/server/frontend/vite.config.ts
index 4d3fdd1..b356c7e 100644
--- a/server/frontend/vite.config.ts
+++ b/server/frontend/vite.config.ts
@@ -1,9 +1,11 @@
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
+import tailwindcss from '@tailwindcss/vite';
import devtools from 'solid-devtools/vite';
export default defineConfig({
plugins: [
solidPlugin(),
+ tailwindcss(),
devtools({
autoname: true
})
diff --git a/settings.gradle.kts b/settings.gradle.kts
index cab8376..0de6ae1 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -10,7 +10,7 @@ pluginManagement {
maven("https://maven.architectury.dev/")
maven("https://maven.minecraftforge.net/")
maven("https://repo.spongepowered.org/maven/")
- maven("https://repo.sk1er.club/repository/maven-releases/")
+ maven("https://repo.essential.gg/repository/maven-releases/")
}
resolutionStrategy {
eachPlugin {