Updated onlinestatus

This commit is contained in:
2025-08-31 19:56:06 +02:00
parent 15c38aa1ac
commit 0729b1f8f6
4 changed files with 85 additions and 24 deletions

View File

@@ -17,6 +17,7 @@
"react": "19.1.0",
"react-dom": "19.1.0",
"react-icons": "^5.5.0",
"react-tooltip": "^5.29.1",
"sonner": "^2.0.6",
"tailwind-merge": "^3.3.1",
"zod": "^4.0.10",
@@ -87,6 +88,12 @@
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
"@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="],
"@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="],
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
@@ -377,6 +384,8 @@
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
"classnames": ["classnames@2.5.1", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="],
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
@@ -753,6 +762,8 @@
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
"react-tooltip": ["react-tooltip@5.29.1", "", { "dependencies": { "@floating-ui/dom": "^1.6.1", "classnames": "^2.3.0" }, "peerDependencies": { "react": ">=16.14.0", "react-dom": ">=16.14.0" } }, "sha512-rmJmEb/p99xWhwmVT7F7riLG08wwKykjHiMGbDPloNJk3tdI73oHsVOwzZ4SRjqMdd5/xwb/4nmz0RcoMfY7Bw=="],
"reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="],
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],

View File

@@ -23,6 +23,7 @@
"react": "19.1.0",
"react-dom": "19.1.0",
"react-icons": "^5.5.0",
"react-tooltip": "^5.29.1",
"sonner": "^2.0.6",
"tailwind-merge": "^3.3.1",
"zod": "^4.0.10"

View File

@@ -1,7 +1,7 @@
import { getColor } from "@/lib/colors"
import { Player } from "@/lib/schema/player"
import { Wifi, WifiOff } from "lucide-react"
import Link from "next/link"
import { OnlineStatus } from "./online-status"
type NewPackageRank = Player["player"]["newPackageRank"]
type MonthlyPackageRank = Player["player"]["monthlyPackageRank"]
@@ -162,26 +162,3 @@ function GuildTag({ tag, tagColor, ign }: { tag?: string, tagColor?: string, ign
</Link>
)
}
function OnlineStatus({ lastLogin, lastLogout }: { lastLogin: number | undefined, lastLogout: number | undefined }) {
const size = 36
if (!lastLogout || !lastLogin) {
return (
<WifiOff className="text-mc-gray" size={size} />
// Offline. Player is most likely in status offline or a staff with api off.
)
}
if (lastLogout > lastLogin) {
return (
<WifiOff className="text-mc-gray" size={size} />
// {`Offline. Last seen online ${formatRelativeTime(lastLogout, "past")}`}
)
}
return (
<Wifi className="text-mc-green" size={size} />
// {`Online. Online for ${formatRelativeTime(lastLogout, "future")}`}
)
}

View File

@@ -0,0 +1,72 @@
"use client"
import { formatRelativeTime } from "@/lib/formatters"
import { Wifi, WifiOff } from "lucide-react"
import { useEffect, useState } from "react"
import { Tooltip } from "react-tooltip"
export function OnlineStatus({ lastLogin, lastLogout }: { lastLogin: number | undefined, lastLogout: number | undefined }) {
const [pos, setPos] = useState({ x: 0, y: 0 })
const size = 36
useEffect(() => {
const controller = new AbortController()
window.addEventListener("mousemove", (e) => {
if (!(e.target instanceof SVGElement)) return
if (e.target.dataset.id !== "online-status") return
setPos({ x: e.clientX, y: e.clientY - 10 })
}, { signal: controller.signal })
return () => {
controller.abort()
}
})
if (!lastLogout || !lastLogin) {
return (
<>
<WifiOff
data-id="online-status"
data-tooltip-id="online-status"
data-tooltip-content="Offline. Player is most likely in status offline or a staff with api off."
suppressHydrationWarning
className="text-mc-gray"
size={size}
/>
<Tooltip id="online-status" position={pos} />
</>
)
}
if (lastLogout > lastLogin) {
return (
<>
<WifiOff
data-id="online-status"
data-tooltip-id="online-status"
data-tooltip-content={`Offline. Last seen online ${formatRelativeTime(lastLogout, "past")}`}
suppressHydrationWarning
className="text-mc-gray"
size={size}
/>
<Tooltip id="online-status" position={pos} />
</>
)
}
return (
<>
<Wifi
data-id="online-status"
data-tooltip-id="online-status"
data-tooltip-content={`Online. Online for ${formatRelativeTime(lastLogout, "future")}`}
suppressHydrationWarning
className="text-mc-green"
size={size}
/>
<Tooltip id="online-status" position={pos} />
</>
)
}