From 144335f503e1fee4f605fe76409d620bb4f10047 Mon Sep 17 00:00:00 2001 From: Linrador <68631622+Linrador@users.noreply.github.com> Date: Tue, 9 Sep 2025 13:12:57 +0200 Subject: [PATCH] updated --- src/app/components/Card.tsx | 67 ++- src/app/components/MatchReadyOverlay.tsx | 64 ++- src/app/components/Navbar.tsx | 91 ---- src/app/components/PremierRankBadge.tsx | 2 +- src/app/components/Profile.tsx | 30 +- src/app/components/Sidebar.tsx | 387 +++++++++------- src/app/components/radar/LiveRadar.tsx | 419 ++++++++++-------- src/app/components/radar/TeamSidebar.tsx | 82 ++++ src/app/layout.tsx | 40 +- .../match-details/[matchId]/radar/page.tsx | 7 +- 10 files changed, 668 insertions(+), 521 deletions(-) delete mode 100644 src/app/components/Navbar.tsx create mode 100644 src/app/components/radar/TeamSidebar.tsx diff --git a/src/app/components/Card.tsx b/src/app/components/Card.tsx index e751db2..b0acbb7 100644 --- a/src/app/components/Card.tsx +++ b/src/app/components/Card.tsx @@ -1,12 +1,13 @@ 'use client' +import React from 'react' type CardWidth = - | 'sm' // 24rem (max‑w‑sm) - | 'md' // 28rem (max‑w‑md) - | 'lg' // 32rem (max‑w‑lg) - | 'xl' // 36rem (max‑w‑xl) - | '2xl' // 42rem (max‑w‑2xl) - | 'full' // 100 % (w‑full) + | 'sm' // 24rem + | 'md' // 28rem + | 'lg' // 32rem + | 'xl' // 36rem + | '2xl' // 42rem + | 'full' // 100% | 'auto' // keine Begrenzung type CardProps = { @@ -15,24 +16,31 @@ type CardProps = { children?: React.ReactNode /** links, rechts oder (Default) zentriert */ align?: 'left' | 'right' | 'center' - /** gewünschte Max‑Breite (Default: lg) */ + /** gewünschte Max-Breite (Default: lg) */ maxWidth?: CardWidth + /** zusätzliche Klassen für den Body-Bereich (Padding etc.) */ + className?: string + /** bei Überlauf innerhalb der Card scrollen (Default: false) */ + bodyScrollable?: boolean + /** Höhe der Card (z.B. 'inherit', '100%', '80vh', 600 ...) */ + height?: 'inherit' | string | number } export default function Card({ children, align = 'center', - maxWidth = 'lg' + maxWidth = 'lg', + className, + bodyScrollable = false, + height, }: CardProps) { - /* Ausrichtung bestimmen */ + // Ausrichtung const alignClasses = - align === 'left' - ? 'mr-auto' - : align === 'right' - ? 'ml-auto' - : 'mx-auto' // center + align === 'left' ? 'mr-auto' + : align === 'right' ? 'ml-auto' + : 'mx-auto' - /* Breite in Tailwind‑Klasse übersetzen */ + // Breite const widthClasses: Record = { sm: 'max-w-sm', md: 'max-w-md', @@ -40,19 +48,32 @@ export default function Card({ xl: 'max-w-xl', '2xl': 'max-w-2xl', full: 'w-full', - auto: '' // keine Begrenzung + auto: '', } + // style.height ableiten (Zahl => px) + const style: React.CSSProperties | undefined = height != null + ? { height: typeof height === 'number' ? `${height}px` : height } + : undefined + return (
-
- {children &&
{children}
} +
+ {children}
) diff --git a/src/app/components/MatchReadyOverlay.tsx b/src/app/components/MatchReadyOverlay.tsx index fe73acd..149bf0a 100644 --- a/src/app/components/MatchReadyOverlay.tsx +++ b/src/app/components/MatchReadyOverlay.tsx @@ -106,6 +106,31 @@ export default function MatchReadyOverlay({ try { new Audio('/assets/sounds/menu_accept.wav').play() } catch {} } + // --- sofort verbinden helper --- + const startConnectingNow = useCallback(() => { + if (finished) return + stopBeeps() + setFinished(true) + setConnecting(true) + try { sound.play('loading') } catch {} + + const doConnect = () => { + try { window.location.href = effectiveConnectHref } + catch { + try { + const a = document.createElement('a') + a.href = effectiveConnectHref + document.body.appendChild(a) + a.click() + a.remove() + } catch {} + } + try { onTimeout?.() } catch {} + } + // mini delay für UI Feedback + setTimeout(doConnect, 200) + }, [finished, effectiveConnectHref, onTimeout]) + // NUR nach Acceptance laden/aktualisieren const loadReady = useCallback(async () => { try { @@ -266,6 +291,14 @@ export default function MatchReadyOverlay({ return () => { cleanup(); stopBeeps() } }, [showContent]) // vorher: [isVisible] + // ⏩ Sofort verbinden, wenn alle bereit sind + useEffect(() => { + if (!isVisible) return + if (total > 0 && countReady >= total && !finished) { + startConnectingNow() + } + }, [isVisible, total, countReady, finished, startConnectingNow]) + // ----- countdown / timeout ----- const rafRef = useRef(null) useEffect(() => { @@ -274,32 +307,15 @@ export default function MatchReadyOverlay({ const t = Date.now() setNow(t) if (effectiveDeadline - t <= 0 && !finished) { + if (accepted) { + startConnectingNow() + } else { stopBeeps() setFinished(true) - - if (accepted) { - setConnecting(true) - try { sound.play('loading') } catch {} - - const doConnect = () => { - try { window.location.href = effectiveConnectHref } - catch { - try { - const a = document.createElement('a') - a.href = effectiveConnectHref - document.body.appendChild(a) - a.click() - a.remove() - } catch {} - } - try { onTimeout?.() } catch {} - } - setTimeout(doConnect, 2000) - } else { - setShowWaitHint(true) // ⬅️ triggert Hinweis „Dein Team wartet auf dich!“ - } - return + setShowWaitHint(true) } + return + } rafRef.current = requestAnimationFrame(step) } rafRef.current = requestAnimationFrame(step) @@ -378,7 +394,7 @@ export default function MatchReadyOverlay({ {/* Backdrop: 2s-Fade */}
diff --git a/src/app/components/Navbar.tsx b/src/app/components/Navbar.tsx deleted file mode 100644 index a0ab216..0000000 --- a/src/app/components/Navbar.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import Link from "next/link" -import { usePathname } from 'next/navigation' - -export default function Navbar({ children }: { children?: React.ReactNode }) { - const pathname = usePathname() - - return ( - <> -
- -
- - ) -} \ No newline at end of file diff --git a/src/app/components/PremierRankBadge.tsx b/src/app/components/PremierRankBadge.tsx index c9ef548..119832c 100644 --- a/src/app/components/PremierRankBadge.tsx +++ b/src/app/components/PremierRankBadge.tsx @@ -34,7 +34,7 @@ export default function PremierRankBadge({ rank }: Props) {
- ———— + ———
) diff --git a/src/app/components/Profile.tsx b/src/app/components/Profile.tsx index 4b35177..0e13eef 100644 --- a/src/app/components/Profile.tsx +++ b/src/app/components/Profile.tsx @@ -14,7 +14,7 @@ export default function Profile() {
@@ -48,19 +48,19 @@ export default function Profile() { }'> @@ -77,13 +77,13 @@ export default function Profile() {
- +
@@ -217,7 +217,7 @@ export default function Profile() { "toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-2 px-4 pe-7 flex text-nowrap w-full cursor-pointer bg-gray-100 rounded-lg text-start text-sm text-gray-800 focus:outline-hidden focus:bg-gray-200 before:absolute before:inset-0 before:z-1 dark:bg-neutral-700 dark:text-neutral-200 dark:focus:bg-neutral-700", "dropdownClasses": "mt-2 z-50 w-full min-w-36 max-h-72 p-1 space-y-0.5 overflow-hidden overflow-y-auto bg-white rounded-xl shadow-xl [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 dark:bg-neutral-900 dark:bg-neutral-900", "optionClasses": "hs-selected:bg-gray-100 dark:hs-selected:bg-neutral-800 py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-hidden focus:bg-gray-100 dark:text-neutral-300 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800", - "optionTemplate": "
", + "optionTemplate": "
", "viewport": "#hs-modal-status-body" }' className="hidden"> @@ -248,7 +248,7 @@ export default function Profile() {
- +
@@ -261,7 +261,7 @@ export default function Profile() { "toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-2 px-4 pe-7 flex text-nowrap w-full cursor-pointer bg-gray-100 rounded-lg text-start text-sm text-gray-800 focus:outline-hidden focus:bg-gray-200 before:absolute before:inset-0 before:z-1 dark:bg-neutral-700 dark:text-neutral-200 dark:focus:bg-neutral-700", "dropdownClasses": "mt-2 z-50 w-full min-w-36 max-h-72 p-1 space-y-0.5 overflow-hidden overflow-y-auto bg-white rounded-xl shadow-xl [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 dark:bg-neutral-900 dark:bg-neutral-900", "optionClasses": "hs-selected:bg-gray-100 dark:hs-selected:bg-neutral-800 py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-hidden focus:bg-gray-100 dark:text-neutral-300 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800", - "optionTemplate": "
", + "optionTemplate": "
", "viewport": "#hs-modal-status-body" }' className="hidden"> @@ -292,7 +292,7 @@ export default function Profile() {
- +
@@ -314,7 +314,7 @@ export default function Profile() { "toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-2 ps-3 pe-7 inline-flex justify-center items-center text-start bg-white border border-gray-200 text-gray-800 text-sm rounded-lg shadow-2xs align-middle focus:outline-hidden focus:ring-2 focus:ring-blue-500 before:absolute before:inset-0 before:z-1 hover:bg-gray-50 dark:bg-neutral-800 dark:border-neutral-600 dark:text-neutral-200 dark:hover:bg-neutral-700 dark:focus:bg-neutral-700", "dropdownClasses": "mt-2 z-50 w-48 p-1 space-y-0.5 bg-white rounded-xl shadow-xl dark:bg-neutral-900", "optionClasses": "hs-selected:bg-gray-100 dark:hs-selected:bg-neutral-800 py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-hidden focus:bg-gray-100 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:text-neutral-200 dark:focus:bg-neutral-800", - "optionTemplate": "
", + "optionTemplate": "
", "viewport": "#hs-modal-status-body" }' className="hidden"> @@ -326,7 +326,7 @@ export default function Profile() {
- +
@@ -349,7 +349,7 @@ export default function Profile() {