From 929f81a540beac5bf068b829bda2a50a056cb6a2 Mon Sep 17 00:00:00 2001 From: Rufat Date: Sun, 28 Sep 2025 18:43:03 -0500 Subject: [PATCH 01/10] Fixed navbar color --- apps/web/src/app/globals.css | 5 +- pnpm-lock.yaml | 313 +---------------------------------- 2 files changed, 4 insertions(+), 314 deletions(-) diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index 8675b928..a35dbcef 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -48,7 +48,7 @@ --background: 240 10% 3.9%; --foreground: 0 0% 98%; - --nav: 0, 0, 0; + --nav: 240 10% 3.9%; --muted: 240 3.7% 15.9%; --muted-foreground: 240 5% 64.9%; @@ -139,6 +139,7 @@ } @keyframes pulseDot { + 0%, 100% { transform: scale(1); @@ -147,4 +148,4 @@ 50% { transform: scale(1.1); } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26111d2c..c8cf0adf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,31 +27,6 @@ importers: specifier: ^2.0.9 version: 2.0.9 - apps/backup: - dependencies: - '@aws-sdk/client-s3': - specifier: ^3.616.0 - version: 3.616.0 - '@hono/node-server': - specifier: ^1.12.0 - version: 1.12.0 - cron: - specifier: ^3.1.7 - version: 3.1.7 - envsafe: - specifier: ^2.0.3 - version: 2.0.3 - hono: - specifier: ^4.5.0 - version: 4.5.0 - typescript: - specifier: 5.5.3 - version: 5.5.3 - devDependencies: - '@types/node': - specifier: 20.14.11 - version: 20.14.11 - apps/backups: dependencies: '@aws-sdk/client-s3': @@ -537,72 +512,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/client-s3@3.616.0: - resolution: {integrity: sha512-6gyZnBlAgOU8cwNqPhFO9s6maGI4/iHV3cmqvQgUn3uqhi1EgTSZSsTMuRzKEgBpTGgC+9Bm6djKqOderMqjdA==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-crypto/sha1-browser': 5.2.0 - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/client-sts': 3.616.0 - '@aws-sdk/core': 3.616.0 - '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0)(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/middleware-bucket-endpoint': 3.616.0 - '@aws-sdk/middleware-expect-continue': 3.616.0 - '@aws-sdk/middleware-flexible-checksums': 3.616.0 - '@aws-sdk/middleware-host-header': 3.616.0 - '@aws-sdk/middleware-location-constraint': 3.609.0 - '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.616.0 - '@aws-sdk/middleware-sdk-s3': 3.616.0 - '@aws-sdk/middleware-signing': 3.616.0 - '@aws-sdk/middleware-ssec': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.616.0 - '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/signature-v4-multi-region': 3.616.0 - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.614.0 - '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.614.0 - '@aws-sdk/xml-builder': 3.609.0 - '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.8 - '@smithy/eventstream-serde-browser': 3.0.5 - '@smithy/eventstream-serde-config-resolver': 3.0.3 - '@smithy/eventstream-serde-node': 3.0.4 - '@smithy/fetch-http-handler': 3.2.2 - '@smithy/hash-blob-browser': 3.1.2 - '@smithy/hash-node': 3.0.3 - '@smithy/hash-stream-node': 3.1.2 - '@smithy/invalid-dependency': 3.0.3 - '@smithy/md5-js': 3.0.3 - '@smithy/middleware-content-length': 3.0.4 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.11 - '@smithy/middleware-serde': 3.0.3 - '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 - '@smithy/types': 3.3.0 - '@smithy/url-parser': 3.0.3 - '@smithy/util-base64': 3.0.0 - '@smithy/util-body-length-browser': 3.0.0 - '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.11 - '@smithy/util-defaults-mode-node': 3.0.11 - '@smithy/util-endpoints': 2.0.5 - '@smithy/util-retry': 3.0.3 - '@smithy/util-stream': 3.1.1 - '@smithy/util-utf8': 3.0.0 - '@smithy/util-waiter': 3.1.2 - tslib: 2.6.3 - transitivePeerDependencies: - - aws-crt - dev: false - /@aws-sdk/client-s3@3.750.0: resolution: {integrity: sha512-S9G9noCeBxchoMVkHYrRi1A1xW/VOTP2W7X34lP+Y7Wpl32yMA7IJo0fAGAuTc0q1Nu6/pXDm+oDG7rhTCA1tg==} engines: {node: '>=18.0.0'} @@ -1637,19 +1546,6 @@ packages: - aws-crt dev: false - /@aws-sdk/middleware-bucket-endpoint@3.616.0: - resolution: {integrity: sha512-KZv78s8UE7+s3qZCfG3pE9U9XV5WTP478aNWis5gDXmsb5LF7QWzEeR8kve5dnjNlK6qVQ33v+mUZa6lR5PwMw==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-arn-parser': 3.568.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.4 - '@smithy/types': 3.3.0 - '@smithy/util-config-provider': 3.0.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/middleware-bucket-endpoint@3.734.0: resolution: {integrity: sha512-etC7G18aF7KdZguW27GE/wpbrNmYLVT755EsFc8kXpZj8D6AFKxc7OuveinJmiy0bYXAMspJUWsF6CrGpOw6CQ==} engines: {node: '>=18.0.0'} @@ -1676,16 +1572,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/middleware-expect-continue@3.616.0: - resolution: {integrity: sha512-IM1pfJPm7pDUXa55js9bnGjS8o3ldzDwf95mL9ZAYdEsm10q6i0ZxZbbro2gTq25Ap5ykdeeS34lOSzIqPiW1A==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.4 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/middleware-expect-continue@3.734.0: resolution: {integrity: sha512-P38/v1l6HjuB2aFUewt7ueAW5IvKkFcv5dalPtbMGRhLeyivBOHwbCyuRKgVs7z7ClTpu9EaViEGki2jEQqEsQ==} engines: {node: '>=18.0.0'} @@ -1706,20 +1592,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/middleware-flexible-checksums@3.616.0: - resolution: {integrity: sha512-Mrco/dURoTXVqwcnYRcyrFaPTIg36ifg2PK0kUYfSVTGEOClZOQXlVG5zYCZoo3yEMgy/gLT907FjUQxwoifIw==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-crypto/crc32': 5.2.0 - '@aws-crypto/crc32c': 5.2.0 - '@aws-sdk/types': 3.609.0 - '@smithy/is-array-buffer': 3.0.0 - '@smithy/protocol-http': 4.0.4 - '@smithy/types': 3.3.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/middleware-flexible-checksums@3.750.0: resolution: {integrity: sha512-ach0d2buDnX2TUausUbiXXFWFo3IegLnCrA+Rw8I9AYVpLN9lTaRwAYJwYC6zEuW9Golff8MwkYsp/OaC5tKMw==} engines: {node: '>=18.0.0'} @@ -1807,15 +1679,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/middleware-location-constraint@3.609.0: - resolution: {integrity: sha512-xzsdoTkszGVqGVPjUmgoP7TORiByLueMHieI1fhQL888WPdqctwAx3ES6d/bA9Q/i8jnc6hs+Fjhy8UvBTkE9A==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/middleware-location-constraint@3.734.0: resolution: {integrity: sha512-EJEIXwCQhto/cBfHdm3ZOeLxd2NlJD+X2F+ZTOxzokuhBtY0IONfC/91hOo5tWQweerojwshSMHRCKzRv1tlwg==} engines: {node: '>=18.0.0'} @@ -1891,23 +1754,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/middleware-sdk-s3@3.616.0: - resolution: {integrity: sha512-heq9pzn0NRX6VL/oMlmwZdgcCh5eJUDscvwMl/oGev0tNdTpB2oGU+wPaNMka7IrW3eBPn7APmY9fdS1kBaBoQ==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-arn-parser': 3.568.0 - '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 - '@smithy/smithy-client': 3.1.9 - '@smithy/types': 3.3.0 - '@smithy/util-config-provider': 3.0.0 - '@smithy/util-stream': 3.1.1 - '@smithy/util-utf8': 3.0.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/middleware-sdk-s3@3.750.0: resolution: {integrity: sha512-3H6Z46cmAQCHQ0z8mm7/cftY5ifiLfCjbObrbyyp2fhQs9zk6gCKzIX8Zjhw0RMd93FZi3ebRuKJWmMglf4Itw==} engines: {node: '>=18.0.0'} @@ -1968,28 +1814,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/middleware-signing@3.616.0: - resolution: {integrity: sha512-wwzZFlXyURwo40oz1NmufreQa5DqwnCF8hR8tIP5+oKCyhbkmlmv8xG4Wn51bzY2WEbQhvFebgZSFTEvelCoCg==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 - '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 - tslib: 2.8.1 - dev: false - - /@aws-sdk/middleware-ssec@3.609.0: - resolution: {integrity: sha512-GZSD1s7+JswWOTamVap79QiDaIV7byJFssBW68GYjyRS5EBjNfwA/8s+6uE6g39R3ojyTbYOmvcANoZEhSULXg==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/types': 3.609.0 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/middleware-ssec@3.734.0: resolution: {integrity: sha512-d4yd1RrPW/sspEXizq2NSOUivnheac6LPeLSLnaeTbBG9g1KqIqvCzP1TfXEqv2CrWfHEsWtJpX7oyjySSPvDQ==} engines: {node: '>=18.0.0'} @@ -2246,18 +2070,6 @@ packages: tslib: 2.6.3 dev: false - /@aws-sdk/signature-v4-multi-region@3.616.0: - resolution: {integrity: sha512-WQn43cfnwbG6jnPjh/SyujDQVqbRjGFY9tGI/tqtUvvGwoDhI343TSDCA7fvs0FEC6Za6vgOBq1CwPv3CFyfhA==} - engines: {node: '>=16.0.0'} - dependencies: - '@aws-sdk/middleware-sdk-s3': 3.616.0 - '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/signature-v4-multi-region@3.750.0: resolution: {integrity: sha512-RA9hv1Irro/CrdPcOEXKwJ0DJYJwYCsauGEdRXihrRfy8MNSR9E+mD5/Fr5Rxjaq5AHM05DYnN3mg/DU6VwzSw==} engines: {node: '>=18.0.0'} @@ -2375,13 +2187,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/util-arn-parser@3.568.0: - resolution: {integrity: sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==} - engines: {node: '>=16.0.0'} - dependencies: - tslib: 2.8.1 - dev: false - /@aws-sdk/util-arn-parser@3.723.0: resolution: {integrity: sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w==} engines: {node: '>=18.0.0'} @@ -2533,14 +2338,6 @@ packages: tslib: 2.8.1 dev: false - /@aws-sdk/xml-builder@3.609.0: - resolution: {integrity: sha512-l9XxNcA4HX98rwCC2/KoiWcmEiRfZe4G+mYwDbCFT87JIMj6GBhLDkAzr/W8KAaA2IDr8Vc6J8fZPgVulxxfMA==} - engines: {node: '>=16.0.0'} - dependencies: - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@aws-sdk/xml-builder@3.734.0: resolution: {integrity: sha512-Zrjxi5qwGEcUsJ0ru7fRtW74WcTS0rbLcehoFB+rN1GRi2hbLcFaYs4PwVA5diLeAJH0gszv3x4Hr/S87MfbKQ==} engines: {node: '>=18.0.0'} @@ -4455,11 +4252,6 @@ packages: react: 18.3.1 dev: false - /@hono/node-server@1.12.0: - resolution: {integrity: sha512-e6oHjNiErRxsZRZBmc2KucuvY3btlO/XPncIpP2X75bRdTilF9GLjm3NHvKKunpJbbJJj31/FoPTksTf8djAVw==} - engines: {node: '>=18.14.1'} - dev: false - /@hookform/resolvers@3.9.0(react-hook-form@7.52.1): resolution: {integrity: sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==} peerDependencies: @@ -8378,13 +8170,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/chunked-blob-reader-native@3.0.0: - resolution: {integrity: sha512-VDkpCYW+peSuM4zJip5WDfqvg2Mo/e8yxOv3VF1m11y7B8KKMKVFtmZWDe36Fvk8rGuWrPZHHXZ7rR7uM5yWyg==} - dependencies: - '@smithy/util-base64': 3.0.0 - tslib: 2.8.1 - dev: false - /@smithy/chunked-blob-reader-native@4.0.0: resolution: {integrity: sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==} engines: {node: '>=18.0.0'} @@ -8393,12 +8178,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/chunked-blob-reader@3.0.0: - resolution: {integrity: sha512-sbnURCwjF0gSToGlsBiAmd1lRCmSn72nu9axfJu5lIx6RUEgHu6GwTMbqCdhQSi0Pumcm5vFxsi9XWXb2mTaoA==} - dependencies: - tslib: 2.8.1 - dev: false - /@smithy/chunked-blob-reader@5.0.0: resolution: {integrity: sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==} engines: {node: '>=18.0.0'} @@ -8515,15 +8294,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/eventstream-codec@3.1.2: - resolution: {integrity: sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==} - dependencies: - '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 3.3.0 - '@smithy/util-hex-encoding': 3.0.0 - tslib: 2.8.1 - dev: false - /@smithy/eventstream-codec@4.0.4: resolution: {integrity: sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==} engines: {node: '>=18.0.0'} @@ -8534,15 +8304,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/eventstream-serde-browser@3.0.5: - resolution: {integrity: sha512-dEyiUYL/ekDfk+2Ra4GxV+xNnFoCmk1nuIXg+fMChFTrM2uI/1r9AdiTYzPqgb72yIv/NtAj6C3dG//1wwgakQ==} - engines: {node: '>=16.0.0'} - dependencies: - '@smithy/eventstream-serde-universal': 3.0.4 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@smithy/eventstream-serde-browser@4.0.1: resolution: {integrity: sha512-HbIybmz5rhNg+zxKiyVAnvdM3vkzjE6ccrJ620iPL8IXcJEntd3hnBl+ktMwIy12Te/kyrSbUb8UCdnUT4QEdA==} engines: {node: '>=18.0.0'} @@ -8561,14 +8322,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/eventstream-serde-config-resolver@3.0.3: - resolution: {integrity: sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==} - engines: {node: '>=16.0.0'} - dependencies: - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@smithy/eventstream-serde-config-resolver@4.0.1: resolution: {integrity: sha512-lSipaiq3rmHguHa3QFF4YcCM3VJOrY9oq2sow3qlhFY+nBSTF/nrO82MUQRPrxHQXA58J5G1UnU2WuJfi465BA==} engines: {node: '>=18.0.0'} @@ -8585,15 +8338,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/eventstream-serde-node@3.0.4: - resolution: {integrity: sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==} - engines: {node: '>=16.0.0'} - dependencies: - '@smithy/eventstream-serde-universal': 3.0.4 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@smithy/eventstream-serde-node@4.0.1: resolution: {integrity: sha512-o4CoOI6oYGYJ4zXo34U8X9szDe3oGjmHgsMGiZM0j4vtNoT+h80TLnkUcrLZR3+E6HIxqW+G+9WHAVfl0GXK0Q==} engines: {node: '>=18.0.0'} @@ -8612,15 +8356,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/eventstream-serde-universal@3.0.4: - resolution: {integrity: sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==} - engines: {node: '>=16.0.0'} - dependencies: - '@smithy/eventstream-codec': 3.1.2 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@smithy/eventstream-serde-universal@4.0.1: resolution: {integrity: sha512-Z94uZp0tGJuxds3iEAZBqGU2QiaBHP4YytLUjwZWx+oUeohCsLyUm33yp4MMBmhkuPqSbQCXq5hDet6JGUgHWA==} engines: {node: '>=18.0.0'} @@ -8671,15 +8406,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/hash-blob-browser@3.1.2: - resolution: {integrity: sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==} - dependencies: - '@smithy/chunked-blob-reader': 3.0.0 - '@smithy/chunked-blob-reader-native': 3.0.0 - '@smithy/types': 3.3.0 - tslib: 2.8.1 - dev: false - /@smithy/hash-blob-browser@4.0.1: resolution: {integrity: sha512-rkFIrQOKZGS6i1D3gKJ8skJ0RlXqDvb1IyAphksaFOMzkn3v3I1eJ8m7OkLj0jf1McP63rcCEoLlkAn/HjcTRw==} engines: {node: '>=18.0.0'} @@ -8730,15 +8456,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/hash-stream-node@3.1.2: - resolution: {integrity: sha512-PBgDMeEdDzi6JxKwbfBtwQG9eT9cVwsf0dZzLXoJF4sHKHs5HEo/3lJWpn6jibfJwT34I1EBXpBnZE8AxAft6g==} - engines: {node: '>=16.0.0'} - dependencies: - '@smithy/types': 3.3.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.8.1 - dev: false - /@smithy/hash-stream-node@4.0.1: resolution: {integrity: sha512-U1rAE1fxmReCIr6D2o/4ROqAQX+GffZpyMt3d7njtGDr2pUNmAKRWa49gsNVhCh2vVAuf3wXzWwNr2YN8PAXIw==} engines: {node: '>=18.0.0'} @@ -8801,14 +8518,6 @@ packages: tslib: 2.8.1 dev: false - /@smithy/md5-js@3.0.3: - resolution: {integrity: sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==} - dependencies: - '@smithy/types': 3.3.0 - '@smithy/util-utf8': 3.0.0 - tslib: 2.8.1 - dev: false - /@smithy/md5-js@4.0.1: resolution: {integrity: sha512-HLZ647L27APi6zXkZlzSFZIjpo8po45YiyjMGJZM3gyDY8n7dPGdmxIIljLm4gPt/7rRvutLTTkYJpZVfG5r+A==} engines: {node: '>=18.0.0'} @@ -10175,10 +9884,6 @@ packages: /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - /@types/luxon@3.4.2: - resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} - dev: false - /@types/minimatch@5.1.2: resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} dev: true @@ -11469,13 +11174,6 @@ packages: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true - /cron@3.1.7: - resolution: {integrity: sha512-tlBg7ARsAMQLzgwqVxy8AZl/qlTc5nibqYwtNGoCrd+cV+ugI+tvZC1oT/8dFH8W455YrywGykx/KMmAqOr7Jw==} - dependencies: - '@types/luxon': 3.4.2 - luxon: 3.4.4 - dev: false - /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -12178,11 +11876,6 @@ packages: engines: {node: '>=0.12'} dev: false - /envsafe@2.0.3: - resolution: {integrity: sha512-51lek8h5btjXhXUDW//Pno7HPydM1WQzltOb1/ONRKdwB2QkfAURnN4Qn0cJ5LzGvX2Km1ReR2O3K3Bqq9sBMg==} - engines: {node: '>=10'} - dev: false - /es-module-lexer@1.4.1: resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} dev: true @@ -14269,11 +13962,6 @@ packages: react: 18.3.1 dev: false - /luxon@3.4.4: - resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} - engines: {node: '>=12'} - dev: false - /magic-bytes.js@1.10.0: resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==} dev: false @@ -14997,6 +14685,7 @@ packages: /path-match@1.2.4: resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} + deprecated: This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions dependencies: http-errors: 1.4.0 path-to-regexp: 1.9.0 From b14325f88e13fa4fac87fa1c843ddcb09332508d Mon Sep 17 00:00:00 2001 From: Rufat Date: Thu, 2 Oct 2025 13:59:02 -0500 Subject: [PATCH 02/10] Added ability to ban users --- apps/web/src/actions/admin/user-actions.ts | 42 +++++++++- apps/web/src/app/admin/users/[slug]/page.tsx | 30 +++++++ apps/web/src/app/globals.css | 3 +- apps/web/src/app/suspended/page.tsx | 42 ++++++++++ .../components/admin/users/BanUserDialog.tsx | 79 +++++++++++++++++++ .../admin/users/RemoveUserBanDialog.tsx | 67 ++++++++++++++++ apps/web/src/middleware.ts | 12 ++- .../drizzle/0001_smooth_squadron_supreme.sql | 21 +++++ packages/db/drizzle/meta/_journal.json | 7 ++ packages/db/schema.ts | 18 +++++ 10 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 apps/web/src/app/suspended/page.tsx create mode 100644 apps/web/src/components/admin/users/BanUserDialog.tsx create mode 100644 apps/web/src/components/admin/users/RemoveUserBanDialog.tsx create mode 100644 packages/db/drizzle/0001_smooth_squadron_supreme.sql diff --git a/apps/web/src/actions/admin/user-actions.ts b/apps/web/src/actions/admin/user-actions.ts index 919a9320..78e769d0 100644 --- a/apps/web/src/actions/admin/user-actions.ts +++ b/apps/web/src/actions/admin/user-actions.ts @@ -4,7 +4,7 @@ import { adminAction } from "@/lib/safe-action"; import { returnValidationErrors } from "next-safe-action"; import { z } from "zod"; import { perms } from "config"; -import { userCommonData } from "db/schema"; +import { userCommonData, bannedUsers } from "db/schema"; import { db } from "db"; import { eq } from "db/drizzle"; import { revalidatePath } from "next/cache"; @@ -60,3 +60,43 @@ export const setUserApproval = adminAction return { success: true }; }, ); + +export const banUser = adminAction + .schema( + z.object({ + userIDToUpdate: z.string(), + reason: z.string(), + }), + ) + .action( + async ({ + parsedInput: { userIDToUpdate, reason }, + ctx: { user, userId }, + }) => { + //TODO: Validate Permission + + await db.insert(bannedUsers).values({ + userID: userIDToUpdate, + reason: reason, + bannedByID: user.clerkID, + }); + revalidatePath(`/admin/users/${userIDToUpdate}`); + return { success: true }; + }, + ); + +export const removeUserBan = adminAction + .schema( + z.object({ + userIDToUpdate: z.string(), + }), + ) + .action(async ({ parsedInput: { userIDToUpdate }, ctx: { user } }) => { + //TODO: Validate Permission + + await db + .delete(bannedUsers) + .where(eq(bannedUsers.userID, userIDToUpdate)); + revalidatePath(`/admin/users/${userIDToUpdate}`); + return { success: true }; + }); diff --git a/apps/web/src/app/admin/users/[slug]/page.tsx b/apps/web/src/app/admin/users/[slug]/page.tsx index a3a64ef4..58c263a8 100644 --- a/apps/web/src/app/admin/users/[slug]/page.tsx +++ b/apps/web/src/app/admin/users/[slug]/page.tsx @@ -15,6 +15,10 @@ import { isUserAdmin } from "@/lib/utils/server/admin"; import ApproveUserButton from "@/components/admin/users/ApproveUserButton"; import c from "config"; import { getHacker, getUser } from "db/functions"; +import BanUserDialog from "@/components/admin/users/BanUserDialog"; +import { db, eq } from "db"; +import { bannedUsers } from "db/schema"; +import RemoveUserBanDialog from "@/components/admin/users/RemoveUserBanDialog"; export default async function Page({ params }: { params: { slug: string } }) { const { userId } = await auth(); @@ -30,8 +34,20 @@ export default async function Page({ params }: { params: { slug: string } }) { return

User Not Found

; } + const banInstance = await db.query.bannedUsers.findFirst({ + where: eq(bannedUsers.userID, user.clerkID), + }); + return (
+ {!!banInstance && ( +
+ + This user has been suspended, reason for suspenssion:{" "} + + {banInstance.reason} +
+ )}
@@ -57,6 +73,20 @@ export default async function Page({ params }: { params: { slug: string } }) { currPermision={user.role} userID={user.clerkID} /> + + {!!banInstance ? ( + + ) : ( + + )} + {(c.featureFlags.core.requireUsersApproval as boolean) && ( +
+

+ Account Suspended +

+

+ Dear {user.firstName} {user.lastName}, +

+

+ {" "} + Your account was suspended +

+

+ Reason: + {banInstance.reason} +

+
+ Contact administration for further assistance. +
+
+
+ ); +} + +export const runtime = "edge"; diff --git a/apps/web/src/components/admin/users/BanUserDialog.tsx b/apps/web/src/components/admin/users/BanUserDialog.tsx new file mode 100644 index 00000000..bf986f98 --- /dev/null +++ b/apps/web/src/components/admin/users/BanUserDialog.tsx @@ -0,0 +1,79 @@ +"use client"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/shadcn/ui/dialog"; +import { Button } from "@/components/shadcn/ui/button"; +import { toast } from "sonner"; +import { useAction } from "next-safe-action/hooks"; +import { banUser } from "@/actions/admin/user-actions"; +import { useState } from "react"; +import { Textarea } from "@/components/shadcn/ui/textarea"; + +interface BanUserDialogProps { + userID: string; + name: string; +} + +export default function BanUserDialog({ userID, name }: BanUserDialogProps) { + const [reason, setReason] = useState(""); + const [open, setOpen] = useState(false); + + const { execute } = useAction(banUser, { + async onSuccess() { + toast.dismiss(); + toast.success("Successfully Banned!"); + }, + async onError(e) { + toast.dismiss(); + toast.error("An error occurred while banning this user."); + console.error(e); + }, + }); + + return ( + + + + + + + Ban {name}. + + Ban this user (not permament action). + + +
+
+