added timezone & translations

This commit is contained in:
Linrador 2025-09-24 15:03:06 +02:00
parent 7d204fe836
commit f27c6feedb
37 changed files with 924 additions and 411 deletions

70
package-lock.json generated
View File

@ -15,7 +15,7 @@
"@fortawesome/fontawesome-free": "^7.0.0",
"@preline/dropdown": "^3.0.1",
"@preline/tooltip": "^3.0.0",
"@prisma/client": "^6.16.1",
"@prisma/client": "^6.16.2",
"chart.js": "^4.5.0",
"clsx": "^2.1.1",
"csgo-sharecode": "^3.1.2",
@ -61,7 +61,7 @@
"@types/ws": "^8.18.1",
"eslint": "^9",
"eslint-config-next": "15.3.0",
"prisma": "^6.16.1",
"prisma": "^6.16.2",
"tailwindcss": "^4.1.4",
"ts-node": "^10.9.2",
"tsx": "^4.19.4",
@ -1599,9 +1599,9 @@
"license": "Licensed under MIT and Preline UI Fair Use License"
},
"node_modules/@prisma/client": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.16.1.tgz",
"integrity": "sha512-QaBCOY29lLAxEFFJgBPyW3WInCW52fJeQTmWx/h6YsP5u0bwuqP51aP0uhqFvhK9DaZPwvai/M4tSDYLVE9vRg==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.16.2.tgz",
"integrity": "sha512-E00PxBcalMfYO/TWnXobBVUai6eW/g5OsifWQsQDzJYm7yaY+IRLo7ZLsaefi0QkTpxfuhFcQ/w180i6kX3iJw==",
"hasInstallScript": true,
"license": "Apache-2.0",
"engines": {
@ -1621,9 +1621,9 @@
}
},
"node_modules/@prisma/config": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.16.1.tgz",
"integrity": "sha512-sz3uxRPNL62QrJ0EYiujCFkIGZ3hg+9hgC1Ae1HjoYuj0BxCqHua4JNijYvYCrh9LlofZDZcRBX3tHBfLvAngA==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.16.2.tgz",
"integrity": "sha512-mKXSUrcqXj0LXWPmJsK2s3p9PN+aoAbyMx7m5E1v1FufofR1ZpPoIArjjzOIm+bJRLLvYftoNYLx1tbHgF9/yg==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
@ -1634,24 +1634,24 @@
}
},
"node_modules/@prisma/debug": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.16.1.tgz",
"integrity": "sha512-RWv/VisW5vJE4cDRTuAHeVedtGoItXTnhuLHsSlJ9202QKz60uiXWywBlVcqXVq8bFeIZoCoWH+R1duZJPwqLw==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.16.2.tgz",
"integrity": "sha512-bo4/gA/HVV6u8YK2uY6glhNsJ7r+k/i5iQ9ny/3q5bt9ijCj7WMPUwfTKPvtEgLP+/r26Z686ly11hhcLiQ8zA==",
"devOptional": true,
"license": "Apache-2.0"
},
"node_modules/@prisma/engines": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.16.1.tgz",
"integrity": "sha512-EOnEM5HlosPudBqbI+jipmaW/vQEaF0bKBo4gVkGabasINHR6RpC6h44fKZEqx4GD8CvH+einD2+b49DQrwrAg==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.16.2.tgz",
"integrity": "sha512-7yf3AjfPUgsg/l7JSu1iEhsmZZ/YE00yURPjTikqm2z4btM0bCl2coFtTGfeSOWbQMmq45Jab+53yGUIAT1sjA==",
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.16.1",
"@prisma/debug": "6.16.2",
"@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"@prisma/fetch-engine": "6.16.1",
"@prisma/get-platform": "6.16.1"
"@prisma/fetch-engine": "6.16.2",
"@prisma/get-platform": "6.16.2"
}
},
"node_modules/@prisma/engines-version": {
@ -1662,25 +1662,25 @@
"license": "Apache-2.0"
},
"node_modules/@prisma/fetch-engine": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.16.1.tgz",
"integrity": "sha512-fl/PKQ8da5YTayw86WD3O9OmKJEM43gD3vANy2hS5S1CnfW2oPXk+Q03+gUWqcKK306QqhjjIHRFuTZ31WaosQ==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.16.2.tgz",
"integrity": "sha512-wPnZ8DMRqpgzye758ZvfAMiNJRuYpz+rhgEBZi60ZqDIgOU2694oJxiuu3GKFeYeR/hXxso4/2oBC243t/whxQ==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.16.1",
"@prisma/debug": "6.16.2",
"@prisma/engines-version": "6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
"@prisma/get-platform": "6.16.1"
"@prisma/get-platform": "6.16.2"
}
},
"node_modules/@prisma/get-platform": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.16.1.tgz",
"integrity": "sha512-kUfg4vagBG7dnaGRcGd1c0ytQFcDj2SUABiuveIpL3bthFdTLI6PJeLEia6Q8Dgh+WhPdo0N2q0Fzjk63XTyaA==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.16.2.tgz",
"integrity": "sha512-U/P36Uke5wS7r1+omtAgJpEB94tlT4SdlgaeTc6HVTTT93pXj7zZ+B/cZnmnvjcNPfWddgoDx8RLjmQwqGDYyA==",
"devOptional": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "6.16.1"
"@prisma/debug": "6.16.2"
}
},
"node_modules/@rtsao/scc": {
@ -6289,16 +6289,16 @@
"license": "MIT"
},
"node_modules/nypm": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.1.tgz",
"integrity": "sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w==",
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz",
"integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==",
"devOptional": true,
"license": "MIT",
"dependencies": {
"citty": "^0.1.6",
"consola": "^3.4.2",
"pathe": "^2.0.3",
"pkg-types": "^2.2.0",
"pkg-types": "^2.3.0",
"tinyexec": "^1.0.1"
},
"bin": {
@ -6781,15 +6781,15 @@
"peer": true
},
"node_modules/prisma": {
"version": "6.16.1",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.16.1.tgz",
"integrity": "sha512-MFkMU0eaDDKAT4R/By2IA9oQmwLTxokqv2wegAErr9Rf+oIe7W2sYpE/Uxq0H2DliIR7vnV63PkC1bEwUtl98w==",
"version": "6.16.2",
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.16.2.tgz",
"integrity": "sha512-aRvldGE5UUJTtVmFiH3WfNFNiqFlAtePUxcI0UEGlnXCX7DqhiMT5TRYwncHFeA/Reca5W6ToXXyCMTeFPdSXA==",
"devOptional": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@prisma/config": "6.16.1",
"@prisma/engines": "6.16.1"
"@prisma/config": "6.16.2",
"@prisma/engines": "6.16.2"
},
"bin": {
"prisma": "build/index.js"

View File

@ -19,7 +19,7 @@
"@fortawesome/fontawesome-free": "^7.0.0",
"@preline/dropdown": "^3.0.1",
"@preline/tooltip": "^3.0.0",
"@prisma/client": "^6.16.1",
"@prisma/client": "^6.16.2",
"chart.js": "^4.5.0",
"clsx": "^2.1.1",
"csgo-sharecode": "^3.1.2",
@ -65,7 +65,7 @@
"@types/ws": "^8.18.1",
"eslint": "^9",
"eslint-config-next": "15.3.0",
"prisma": "^6.16.1",
"prisma": "^6.16.2",
"tailwindcss": "^4.1.4",
"ts-node": "^10.9.2",
"tsx": "^4.19.4",

View File

@ -52,6 +52,8 @@
readyAcceptances MatchReady[] @relation("MatchReadyUser")
pterodactylClientApiKey String?
timeZone String? // IANA-TZ, z.B. "Europe/Berlin"
}
enum UserStatus {

View File

@ -21,6 +21,7 @@ const getTeamLogo = (logo?: string | null) =>
const toDateKey = (d: Date) => d.toISOString().slice(0, 10)
const weekdayDE = new Intl.DateTimeFormat('de-DE', { weekday: 'long' })
const weekdayEN = new Intl.DateTimeFormat('en-GB', { weekday: 'long' })
type TeamOption = { id: string; name: string; logo?: string | null }
@ -302,7 +303,8 @@ export default function CommunityMatchList({ matchType }: Props) {
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
{grouped.map(([dateKey, dayMatches], dayIdx) => {
const dateObj = new Date(dateKey + 'T00:00:00')
const dayLabel = `Tag #${dayIdx + 1} ${weekdayDE.format(dateObj)}`
const weekdayFmt = locale === 'de' ? weekdayDE : weekdayEN
const dayLabel = `${tMatches('day')} #${dayIdx + 1} ${weekdayFmt.format(dateObj)}`
return (
<div key={dateKey} className="flex flex-col gap-4">
<div className="bg-yellow-300 dark:bg-yellow-500 text-center py-2 font-bold tracking-wider">
@ -320,7 +322,7 @@ export default function CommunityMatchList({ matchType }: Props) {
const mv = getMapVoteState(m, now)
const opensText =
mv.hasVote && !mv.isOpen && mv.opensAt
? `öffnet in ${formatCountdown(mv.opensInMs)}`
? `${tMatches("opens-in")} ${formatCountdown(mv.opensInMs)}`
: null
return (

View File

@ -1,3 +1,5 @@
// /src/app/[locale]/components/NotificationBell.tsx
'use client'
import { useEffect, useState, useRef } from 'react'
@ -37,7 +39,7 @@ export default function NotificationBell() {
const router = useRouter()
const { lastEvent } = useSSEStore() // nur konsumieren, nicht connecten
const bellRef = useRef<HTMLButtonElement | null>(null);
const telemetryBannerPx = useUiChromeStore(s => s.telemetryBannerPx)
const telemetryBannerPx = useUiChromeStore(s => s.gameBannerPx)
const [notifications, setNotifications] = useState<Notification[]>([])
const [open, setOpen] = useState(false)

View File

@ -1,9 +1,12 @@
// NotificationCenter.tsx
'use client'
import { useEffect, useRef } from 'react'
import { useEffect, useRef, useMemo, useState } from 'react'
import Button from './Button'
import { formatDistanceToNow } from 'date-fns'
import { de } from 'date-fns/locale'
import { useTranslations } from 'next-intl'
import { Tabs } from './Tabs'
type Notification = {
id: string
@ -14,6 +17,8 @@ type Notification = {
createdAt?: string
}
type AnchorLikeRef = { current: HTMLElement | null }
type Props = {
notifications: Notification[]
markAllAsRead: () => void
@ -21,7 +26,7 @@ type Props = {
onClose: () => void
onAction: (action: 'accept' | 'reject', invitationId: string) => void
onClickNotification?: (notification: Notification) => void
anchorRef?: React.RefObject<HTMLElement> // Glocke
anchorRef?: AnchorLikeRef
}
export default function NotificationCenter({
@ -34,8 +39,17 @@ export default function NotificationCenter({
anchorRef
}: Props) {
const panelRef = useRef<HTMLDivElement | null>(null)
const tNotifications = useTranslations('notifications')
// EIN Outside-Click Listener, der sowohl Panel als auch Anchor ignoriert
// NEW: Tabs-State: 'all' | 'read'
type TabKey = 'all' | 'read';
const [activeTab, setActiveTab] = useState<TabKey>('all');
const labelAll = tNotifications('all');
const labelRead = tNotifications('read');
// Outside-Click
useEffect(() => {
const onDocPointerDown = (e: PointerEvent) => {
const t = e.target as Node
@ -47,44 +61,73 @@ export default function NotificationCenter({
return () => document.removeEventListener('pointerdown', onDocPointerDown)
}, [onClose, anchorRef])
// Gefilterte Liste abhängig vom Tab
const visibleNotifications = useMemo(() => {
return activeTab === 'read'
? notifications.filter(n => n.read)
: notifications.filter(n => !n.read);
}, [notifications, activeTab]);
return (
<div
ref={panelRef}
className="absolute bottom-20 right-0 w-80 bg-white dark:bg-neutral-800 border border-gray-200 dark:border-neutral-700 rounded-lg shadow-xl overflow-hidden z-50"
className="absolute bottom-20 right-0 w-100 bg-white dark:bg-neutral-800 border border-gray-200 dark:border-neutral-700 rounded-lg shadow-xl overflow-hidden z-50"
>
{/* Kopfzeile */}
<div className="p-2 flex justify-between items-center border-b border-gray-200 dark:border-neutral-700">
<span className="font-semibold text-gray-800 dark:text-white">
Benachrichtigungen
</span>
<Button
title="Alle als gelesen markieren"
onClick={markAllAsRead}
variant="solid"
color="blue"
size="sm"
className="p-2"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" className="w-4 h-4" fill="currentColor">
<path d="M255.4 48.2c.2-.1.4-.2.6-.2s.4.1.6.2L460.6 194c2.1 1.5 3.4 3.9 3.4 6.5v13.6L291.5 355.7c-20.7 17-50.4 17-71.1 0L48 214.1v-13.6c0-2.6 1.2-5 3.4-6.5L255.4 48.2zM48 276.2L190 392.8c38.4 31.5 93.7 31.5 132 0L464 276.2V456c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V276.2zM256 0c-10.2 0-20.2 3.2-28.5 9.1L23.5 154.9C8.7 165.4 0 182.4 0 200.5V456c0 30.9 25.1 56 56 56h400c30.9 0 56-25.1 56-56V200.5c0-18.1-8.7-35.1-23.4-45.6L284.5 9.1C276.2 3.2 266.2 0 256 0z" />
</svg>
</Button>
{/* Kopfzeile + Tabs */}
<div className="p-2 border-b border-gray-200 dark:border-neutral-700">
<div className="flex justify-between items-center">
<span className="font-semibold text-gray-800 dark:text-white">
{tNotifications('title')}
</span>
<Button
title="Alle als gelesen markieren"
onClick={markAllAsRead}
variant="solid"
color="blue"
size="sm"
className="p-2"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" className="w-4 h-4" fill="currentColor">
<path d="M255.4 48.2c.2-.1.4-.2.6-.2s.4.1.6.2L460.6 194c2.1 1.5 3.4 3.9 3.4 6.5v13.6L291.5 355.7c-20.7 17-50.4 17-71.1 0L48 214.1v-13.6c0-2.6 1.2-5 3.4-6.5L255.4 48.2zM48 276.2L190 392.8c38.4 31.5 93.7 31.5 132 0L464 276.2V456c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V276.2zM256 0c-10.2 0-20.2 3.2-28.5 9.1L23.5 154.9C8.7 165.4 0 182.4 0 200.5V456c0 30.9 25.1 56 56 56h400c30.9 0 56-25.1 56-56V200.5c0-18.1-8.7-35.1-23.4-45.6L284.5 9.1C276.2 3.2 266.2 0 256 0z" />
</svg>
</Button>
</div>
{/* Tabs-Zeile */}
<div className="mt-2">
<Tabs
value={activeTab === 'all' ? labelAll : labelRead}
onChange={(label) => setActiveTab(label === labelAll ? 'all' : 'read')}
>
<Tabs.Tab name={labelAll} href="/notifications" />
<Tabs.Tab name={labelRead} href="/notifications/read" />
</Tabs>
</div>
</div>
{/* Liste */}
<div className="max-h-60 overflow-y-auto">
{notifications.length === 0 ? (
<div
className={`h-80 ${
visibleNotifications.length === 0
? 'flex items-center justify-center'
: 'overflow-y-auto'
}`}
>
{visibleNotifications.length === 0 ? (
<div className="p-4 text-center text-gray-500 dark:text-neutral-400">
Keine Benachrichtigungen
{tNotifications('no-notifications')}
</div>
) : (
notifications.map((n) => {
visibleNotifications.map((n) => {
const needsAction =
!n.read && (n.actionType === 'team-invite' || n.actionType === 'team-join-request')
return (
<div
key={n.id}
className="grid grid-cols-[auto_1fr_auto] items-center gap-2 py-3 px-2 border-b border-gray-200 dark:border-neutral-700 text-sm hover:bg-gray-50 dark:hover:bg-neutral-700 cursor-pointer"
className={`grid grid-cols-[auto_1fr_auto] items-center gap-2 py-3 px-2
border-b border-gray-200 dark:border-neutral-700 text-sm
hover:bg-gray-50 dark:hover:bg-neutral-700 cursor-pointer
${!n.read ? 'bg-gray-50 dark:bg-neutral-800/60 ring-1 ring-gray-200/60 dark:ring-neutral-700/60' : ''}`}
onClick={() => {
onClickNotification?.(n)
if (!n.read) onSingleRead(n.id)

View File

@ -1,3 +1,4 @@
// Tabs.tsx
'use client'
import { usePathname } from 'next/navigation'
@ -9,7 +10,14 @@ export type TabProps = {
href: string
}
export function Tabs({ children }: { children: ReactNode }) {
type TabsProps = {
children: ReactNode
/** optional kontrollierter Modus */
value?: string // aktiver Tab-Name
onChange?: (name: string) => void
}
export function Tabs({ children, value, onChange }: TabsProps) {
const pathname = usePathname()
const tabs = Array.isArray(children) ? children : [children]
@ -24,15 +32,38 @@ export function Tabs({ children }: { children: ReactNode }) {
typeof tab.props.href === 'string'
)
.map((tab, index) => {
const base = tab.props.href.replace(/\/$/, '')
const current = pathname.replace(/\/$/, '')
// Unkontrolliert (Routing) vs. kontrolliert (onChange)
if (onChange && value !== undefined) {
const isActive = value === tab.props.name
return (
<button
key={index}
type="button"
onClick={() => onChange(tab.props.name)}
role="tab"
aria-selected={isActive}
className={`py-2 px-4 text-sm rounded-lg transition-colors ${
isActive
? 'bg-gray-100 text-gray-900 dark:bg-neutral-700 dark:text-white'
: 'text-gray-500 hover:bg-gray-100 dark:text-neutral-400 dark:hover:bg-neutral-700'
}`}
>
{tab.props.name}
</button>
)
}
const isActive = current === base || current.startsWith(base + '/');
// Standard: Link-basiert
const base = tab.props.href.replace(/\/$/, '')
const current = pathname.replace(/\/$/, '')
const isActive = current === base || current.startsWith(base + '/')
return (
<Link
key={index}
href={tab.props.href}
role="tab"
aria-selected={isActive}
className={`py-2 px-4 text-sm rounded-lg transition-colors ${
isActive
? 'bg-gray-100 text-gray-900 dark:bg-neutral-700 dark:text-white'
@ -48,6 +79,4 @@ export function Tabs({ children }: { children: ReactNode }) {
}
// Dummy-Komponente nur zur statischen Verwendung
Tabs.Tab = function Tab(_props: TabProps) {
return null
}
Tabs.Tab = function Tab(_props: TabProps) { return null }

View File

@ -1,10 +1,10 @@
'use client'
import DeleteAccountSettings from "./account/DeleteAccountSettings"
import AppearanceSettings from "./account/AppearanceSettings"
import AuthCodeSettings from "./account/AuthCodeSettings"
import LatestKnownCodeSettings from "./account/ShareCodeSettings"
import { useTranslations, useLocale } from 'next-intl'
import UserSettings from "./account/UserSettings"
export default function AccountSettings() {
@ -28,6 +28,10 @@ export default function AccountSettings() {
{/* Form */}
<form>
{/* User Settings */}
<UserSettings />
{/* End User Settings */}
{/* Auth Code Settings */}
<AuthCodeSettings />
{/* End Auth Code Settings */}
@ -39,10 +43,6 @@ export default function AccountSettings() {
{/* Appearance */}
<AppearanceSettings />
{/* End Appearance */}
{/* Appearance */}
<DeleteAccountSettings />
{/* End Appearance */}
</form>
{/* End Form */}
</div>

View File

@ -18,9 +18,9 @@ export default function AppearanceSettings() {
if (!mounted) return null
const options = [
{ id: 'system', label: 'System', img: 'account-system-image.svg' },
{ id: 'light', label: 'Hell', img: 'account-light-image.svg' },
{ id: 'dark', label: 'Dunkel', img: 'account-dark-image.svg' },
{ id: 'system', label: tSettings("tabs.account.page.AppearanceSettings.theme.system"), img: 'account-system-image.svg' },
{ id: 'light', label: tSettings("tabs.account.page.AppearanceSettings.theme.light"), img: 'account-light-image.svg' },
{ id: 'dark', label: tSettings("tabs.account.page.AppearanceSettings.theme.dark"), img: 'account-dark-image.svg' },
]
return (
@ -38,11 +38,11 @@ export default function AppearanceSettings() {
</p>
<h3 className="mt-3 text-sm font-semibold text-gray-800 dark:text-neutral-200">
Theme-Modus
{tSettings("tabs.account.page.AppearanceSettings.theme-mode")}
</h3>
<p className="text-sm text-gray-500 dark:text-neutral-500">
Die Darstellung passt sich automatisch deinem Gerät an, wenn System gewählt ist.
{tSettings("tabs.account.page.AppearanceSettings.theme-mode-description")}
</p>
<div className="mt-5">

View File

@ -14,6 +14,7 @@ export default function AuthCodeSettings() {
const [isLoading, setIsLoading] = useState(true)
// Übersetzungen
const tCommon = useTranslations('common')
const tSettings = useTranslations('settings')
const showInput = !isLoading && (!authCode || manuallySet)
@ -117,7 +118,7 @@ export default function AuthCodeSettings() {
target="_blank"
className="text-blue-600 underline hover:text-blue-800"
>
{tSettings("tabs.account.here")}
{tCommon("here")}
</Link>.
</p>
</div>
@ -147,25 +148,17 @@ export default function AuthCodeSettings() {
placeholder="XXXX-XXXXX-XXXX"
required
/>
{touched && authCodeValid && (
<div className="absolute inset-y-0 end-0 flex items-center pe-3">
<svg className="shrink-0 size-4 text-teal-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<polyline points="20 6 9 17 4 12" />
</svg>
</div>
)}
</>
) : (
<Button color="red" variant="ghost" onClick={handleDisconnect}>
{tSettings("tabs.account.page.AuthCodeSettings.button-disconnect")}
{tCommon("disconnect")}
</Button>
)}
</div>
{touched && (
<p className={`text-sm mt-2 ${authCodeValid ? 'text-teal-600' : 'text-red-600'}`}>
{authCodeValid ? '✓ Gespeichert!' : 'Ungültiger Authentifizierungscode'}
{authCodeValid ? `${tCommon("saved")}!` : `${tSettings("tabs.account.page.AuthCodeSettings.invalid")}`}
</p>
)}
</div>

View File

@ -1,25 +0,0 @@
// components/settings/DeleteAccountSettings.tsx
'use client'
import Link from "next/link"
import Button from "../../Button"
export default function DeleteAccountSettings() {
return (
<div className="py-6 sm:py-8 space-y-5 border-t border-gray-200 first:border-t-0 dark:border-neutral-700">
<div className="grid sm:grid-cols-12 gap-y-1.5 sm:gap-y-0 sm:gap-x-5">
<div className="sm:col-span-4 2xl:col-span-2">
<label className="sm:mt-2.5 inline-block text-sm text-gray-500 dark:text-neutral-500">
Account löschen
</label>
</div>
<div className="sm:col-span-8 xl:col-span-6 2xl:col-span-5">
<p className="text-sm text-gray-500 dark:text-neutral-500">
Wenn du deinen Account löschen willst, klicke hier: <Button variant="link" color="red" size="sm">Account löschen</Button>
</p>
</div>
</div>
</div>
)
}

View File

@ -17,6 +17,7 @@ export default function LatestKnownCodeSettings() {
const [isLoading, setIsLoading] = useState(true)
// Übersetzungen
const tCommon = useTranslations('common')
const tSettings = useTranslations('settings')
const shareCodeExpired = useMemo(() => {
@ -142,7 +143,7 @@ export default function LatestKnownCodeSettings() {
target="_blank"
className="text-blue-600 underline hover:text-blue-800"
>
{tSettings("tabs.account.here")}
{tCommon("here")}
</Link>.
</p>
</div>
@ -174,26 +175,26 @@ export default function LatestKnownCodeSettings() {
{showError && (
<p className="text-sm text-red-600 mt-2">
Abgelaufener Austauschcode! Deinen neuen Austauschcode findest du&nbsp;
{tSettings("tabs.account.page.ShareCodeSettings.invalid-share-code")}&nbsp;
<Link
href="https://help.steampowered.com/de/wizard/HelpWithGameIssue/?appid=730&issueid=128"
target="_blank"
className="text-red-600 underline hover:text-blue-800"
>
hier
{tCommon("here")}
</Link>.
</p>
)}
{isSaved && !showError && (
<p className="text-sm text-teal-600 mt-2">
Gespeichert!
{tCommon("saved")}!
</p>
)}
</>
) : (
<Button color="red" variant="ghost" onClick={handleDisconnect}>
Zurücksetzen
{tCommon("reset")}
</Button>
)}
</div>

View File

@ -0,0 +1,171 @@
'use client'
import {useEffect, useMemo, useRef, useState} from 'react'
import Popover from '../../Popover'
import {useTranslations} from 'next-intl'
// Versuche, native Liste zu nehmen; fallback auf gängige Auswahl.
const FALLBACK_TIMEZONES = [
'UTC',
'Europe/Berlin', 'Europe/Vienna', 'Europe/Zurich',
'Europe/Paris', 'Europe/Madrid', 'Europe/Rome',
'Europe/Amsterdam', 'Europe/Prague', 'Europe/Warsaw',
'Europe/London',
'America/New_York', 'America/Chicago', 'America/Denver', 'America/Los_Angeles',
'America/Sao_Paulo',
'Asia/Tokyo', 'Asia/Seoul', 'Asia/Shanghai', 'Asia/Singapore', 'Asia/Kolkata',
'Australia/Sydney'
]
function getTimeZones(): string[] {
// @ts-ignore Node/Browser, je nach Runtime verfügbar
if (typeof Intl.supportedValuesOf === 'function') {
try {
// @ts-ignore
return Intl.supportedValuesOf('timeZone') as string[]
} catch {}
}
return FALLBACK_TIMEZONES
}
export default function UserSettings() {
const tCommon = useTranslations('common')
const tSettings = useTranslations('settings')
const [timeZone, setTimeZone] = useState<string | null>(null)
const [initialTz, setInitialTz] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const [saving, setSaving] = useState(false)
const [savedOk, setSavedOk] = useState<boolean | null>(null)
const [errorMsg, setErrorMsg] = useState<string | null>(null)
const timeZones = useMemo(() => getTimeZones(), [])
const debounceTimer = useRef<number | null>(null)
const inFlight = useRef<AbortController | null>(null)
// Initial laden
useEffect(() => {
;(async () => {
try {
const res = await fetch('/api/user/timezone', { cache: 'no-store' })
const data = await res.json().catch(() => ({}))
const tz = data?.timeZone ?? null
setTimeZone(tz)
setInitialTz(tz)
} catch (e) {
console.error('[UserSettings] Laden fehlgeschlagen:', e)
} finally {
setLoading(false)
}
})()
}, [])
// Helper: Speichern (mit Abort bei schnellen Wechseln)
const persist = async (tz: string | null) => {
// laufende Anfrage abbrechen
inFlight.current?.abort()
const ctrl = new AbortController()
inFlight.current = ctrl
setSaving(true)
setSavedOk(null)
setErrorMsg(null)
try {
const res = await fetch('/api/user/timezone', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ timeZone: tz }),
signal: ctrl.signal
})
if (!res.ok) {
const j = await res.json().catch(() => ({}))
throw new Error(j?.message || `HTTP ${res.status}`)
}
setInitialTz(tz)
setSavedOk(true)
// kleines Auto-Reset des „Gespeichert“-Hinweises
window.setTimeout(() => setSavedOk(null), 2000)
} catch (e: any) {
if (e?.name === 'AbortError') return
console.error('[UserSettings] Speichern fehlgeschlagen:', e)
setSavedOk(false)
setErrorMsg(e?.message ?? 'Save failed')
} finally {
setSaving(false)
}
}
// Auto-Save mit kleinem Debounce
useEffect(() => {
if (loading) return
if (timeZone === initialTz) return
if (debounceTimer.current) window.clearTimeout(debounceTimer.current)
debounceTimer.current = window.setTimeout(() => {
persist(timeZone ?? null)
}, 400) as unknown as number
return () => {
if (debounceTimer.current) window.clearTimeout(debounceTimer.current)
}
}, [timeZone, initialTz, loading])
if (loading) {
return (
<div className="py-6 sm:py-8 border-t border-gray-200 dark:border-neutral-700">
<p className="text-sm text-gray-500 dark:text-neutral-500">Loading</p>
</div>
)
}
return (
<div className="py-6 sm:py-8 space-y-5 border-t border-gray-200 dark:border-neutral-700">
<div className="grid sm:grid-cols-12 gap-y-1.5 sm:gap-y-0 sm:gap-x-5">
{/* Label + Hilfe */}
<div className="sm:col-span-4 2xl:col-span-2">
<label htmlFor="user-timezone" className="sm:mt-2.5 inline-block text-sm text-gray-500 dark:text-neutral-500">
{tSettings('tabs.account.page.UserSettings.timezone-label')}
</label>
</div>
{/* Eingabe */}
<div className="sm:col-span-8 xl:col-span-6 2xl:col-span-5">
<div className="flex items-center gap-2">
<select
id="user-timezone"
value={timeZone ?? ''}
onChange={(e) => setTimeZone(e.target.value || null)}
disabled={saving}
className="w-full rounded-lg border border-gray-300 dark:border-neutral-700 bg-white dark:bg-neutral-800 px-3 py-2 text-sm disabled:opacity-70"
>
<option value="">{tSettings('tabs.account.page.UserSettings.timezone-system')}</option>
{timeZones.map((tz) => (
<option key={tz} value={tz}>{tz}</option>
))}
</select>
{/* Live-Status (optional dezent) */}
<span className="text-xs min-w-[80px] text-right">
{saving && <span className="text-gray-500 dark:text-neutral-400">{tCommon('saving')}</span>}
{savedOk === true && <span className="text-teal-600"> {tCommon('saved')}</span>}
{savedOk === false && <span className="text-red-600">{tCommon('save-failed')}</span>}
</span>
</div>
{/* Fehlertext detaillierter */}
{errorMsg && (
<p className="text-xs mt-1 text-red-600">{errorMsg}</p>
)}
{/* Hinweis, wenn nichts geändert wurde */}
{savedOk === null && timeZone === initialTz && (
<p className="text-xs mt-2 text-gray-500 dark:text-neutral-400">
{tCommon('no-changes')}
</p>
)}
</div>
</div>
</div>
)
}

View File

@ -41,14 +41,8 @@
font-style: normal;
}
:root {
--background: #ffffff;
--foreground: #171717;
}
html, body {
min-height: 100%;
background: var(--background);
font-family: ui-sans-serif,-apple-system,system-ui,Segoe UI,Helvetica,Apple Color Emoji,Arial,sans-serif,Segoe UI Emoji,Segoe UI Symbol;
}
@ -118,6 +112,12 @@ html, body {
overflow: hidden;
}
@media (prefers-color-scheme: light) {
:root {
--background: #ffffff;
--foreground: #171717;
}
}
@media (prefers-color-scheme: dark) {
:root {

View File

@ -0,0 +1,62 @@
// app/api/user/timezone/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
export const runtime = 'nodejs' // falls nötig
function isValidIanaOrNull(v: unknown): v is string | null {
if (v === null) return true
if (typeof v !== 'string' || v.trim() === '') return false
// Validate via Intl.supportedValuesOf if available
// @ts-ignore
const list: string[] | undefined = typeof Intl.supportedValuesOf === 'function'
// @ts-ignore
? Intl.supportedValuesOf('timeZone')
: undefined
return list ? list.includes(v) : true // wenn kein Support: großzügig erlauben
}
export async function GET(req: NextRequest) {
try {
const session = await getServerSession(authOptions(req))
if (!session?.user?.steamId) {
return NextResponse.json({ message: 'Not authenticated' }, { status: 401 })
}
const user = await prisma.user.findUnique({
where: { steamId: session.user.steamId },
select: { timeZone: true }
})
return NextResponse.json({ timeZone: user?.timeZone ?? null })
} catch (e: any) {
console.error('[TZ][GET] failed', e)
return NextResponse.json({ message: 'Internal error' }, { status: 500 })
}
}
export async function PUT(req: NextRequest) {
try {
const session = await getServerSession(authOptions(req))
if (!session?.user?.steamId) {
return NextResponse.json({ message: 'Not authenticated' }, { status: 401 })
}
const body = await req.json().catch(() => ({}))
const { timeZone } = body as { timeZone: string | null | undefined }
if (!isValidIanaOrNull(timeZone)) {
return NextResponse.json({ message: 'Invalid timeZone' }, { status: 400 })
}
await prisma.user.update({
where: { steamId: session.user.steamId },
data: { timeZone: timeZone ?? null }
})
return NextResponse.json({ ok: true })
} catch (e: any) {
console.error('[TZ][PUT] failed', e)
return NextResponse.json({ message: 'Internal error' }, { status: 500 })
}
}

View File

@ -1,4 +1,4 @@
/* !!! This is code generated by Prisma. Do not edit directly. !!!
/* eslint-disable */
module.exports = { ...require('.') }
module.exports = { ...require('#main-entry-point') }

File diff suppressed because one or more lines are too long

View File

@ -20,12 +20,12 @@ exports.Prisma = Prisma
exports.$Enums = {}
/**
* Prisma Client JS version: 6.15.0
* Query Engine version: 85179d7826409ee107a6ba334b5e305ae3fba9fb
* Prisma Client JS version: 6.16.2
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/
Prisma.prismaVersion = {
client: "6.15.0",
engine: "85179d7826409ee107a6ba334b5e305ae3fba9fb"
client: "6.16.2",
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
}
Prisma.PrismaClientKnownRequestError = () => {
@ -134,7 +134,8 @@ exports.Prisma.UserScalarFieldEnum = {
createdAt: 'createdAt',
status: 'status',
lastActiveAt: 'lastActiveAt',
pterodactylClientApiKey: 'pterodactylClientApiKey'
pterodactylClientApiKey: 'pterodactylClientApiKey',
timeZone: 'timeZone'
};
exports.Prisma.TeamScalarFieldEnum = {

View File

@ -460,8 +460,8 @@ export namespace Prisma {
export import Exact = $Public.Exact
/**
* Prisma Client JS version: 6.15.0
* Query Engine version: 85179d7826409ee107a6ba334b5e305ae3fba9fb
* Prisma Client JS version: 6.16.2
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
*/
export type PrismaVersion = {
client: string
@ -2064,6 +2064,10 @@ export namespace Prisma {
timeout?: number
isolationLevel?: Prisma.TransactionIsolationLevel
}
/**
* Instance of a Driver Adapter, e.g., like one provided by `@prisma/adapter-planetscale`
*/
adapter?: runtime.SqlDriverAdapterFactory | null
/**
* Global configuration for omitting model fields by default.
*
@ -2532,6 +2536,7 @@ export namespace Prisma {
status: $Enums.UserStatus | null
lastActiveAt: Date | null
pterodactylClientApiKey: string | null
timeZone: string | null
}
export type UserMaxAggregateOutputType = {
@ -2549,6 +2554,7 @@ export namespace Prisma {
status: $Enums.UserStatus | null
lastActiveAt: Date | null
pterodactylClientApiKey: string | null
timeZone: string | null
}
export type UserCountAggregateOutputType = {
@ -2566,6 +2572,7 @@ export namespace Prisma {
status: number
lastActiveAt: number
pterodactylClientApiKey: number
timeZone: number
_all: number
}
@ -2593,6 +2600,7 @@ export namespace Prisma {
status?: true
lastActiveAt?: true
pterodactylClientApiKey?: true
timeZone?: true
}
export type UserMaxAggregateInputType = {
@ -2610,6 +2618,7 @@ export namespace Prisma {
status?: true
lastActiveAt?: true
pterodactylClientApiKey?: true
timeZone?: true
}
export type UserCountAggregateInputType = {
@ -2627,6 +2636,7 @@ export namespace Prisma {
status?: true
lastActiveAt?: true
pterodactylClientApiKey?: true
timeZone?: true
_all?: true
}
@ -2731,6 +2741,7 @@ export namespace Prisma {
status: $Enums.UserStatus
lastActiveAt: Date | null
pterodactylClientApiKey: string | null
timeZone: string | null
_count: UserCountAggregateOutputType | null
_avg: UserAvgAggregateOutputType | null
_sum: UserSumAggregateOutputType | null
@ -2767,6 +2778,7 @@ export namespace Prisma {
status?: boolean
lastActiveAt?: boolean
pterodactylClientApiKey?: boolean
timeZone?: boolean
team?: boolean | User$teamArgs<ExtArgs>
ledTeam?: boolean | User$ledTeamArgs<ExtArgs>
matchesAsTeamA?: boolean | User$matchesAsTeamAArgs<ExtArgs>
@ -2799,6 +2811,7 @@ export namespace Prisma {
status?: boolean
lastActiveAt?: boolean
pterodactylClientApiKey?: boolean
timeZone?: boolean
team?: boolean | User$teamArgs<ExtArgs>
}, ExtArgs["result"]["user"]>
@ -2817,6 +2830,7 @@ export namespace Prisma {
status?: boolean
lastActiveAt?: boolean
pterodactylClientApiKey?: boolean
timeZone?: boolean
team?: boolean | User$teamArgs<ExtArgs>
}, ExtArgs["result"]["user"]>
@ -2835,9 +2849,10 @@ export namespace Prisma {
status?: boolean
lastActiveAt?: boolean
pterodactylClientApiKey?: boolean
timeZone?: boolean
}
export type UserOmit<ExtArgs extends $Extensions.InternalArgs = $Extensions.DefaultArgs> = $Extensions.GetOmit<"steamId" | "name" | "avatar" | "location" | "isAdmin" | "teamId" | "premierRank" | "authCode" | "lastKnownShareCode" | "lastKnownShareCodeDate" | "createdAt" | "status" | "lastActiveAt" | "pterodactylClientApiKey", ExtArgs["result"]["user"]>
export type UserOmit<ExtArgs extends $Extensions.InternalArgs = $Extensions.DefaultArgs> = $Extensions.GetOmit<"steamId" | "name" | "avatar" | "location" | "isAdmin" | "teamId" | "premierRank" | "authCode" | "lastKnownShareCode" | "lastKnownShareCodeDate" | "createdAt" | "status" | "lastActiveAt" | "pterodactylClientApiKey" | "timeZone", ExtArgs["result"]["user"]>
export type UserInclude<ExtArgs extends $Extensions.InternalArgs = $Extensions.DefaultArgs> = {
team?: boolean | User$teamArgs<ExtArgs>
ledTeam?: boolean | User$ledTeamArgs<ExtArgs>
@ -2895,6 +2910,7 @@ export namespace Prisma {
status: $Enums.UserStatus
lastActiveAt: Date | null
pterodactylClientApiKey: string | null
timeZone: string | null
}, ExtArgs["result"]["user"]>
composites: {}
}
@ -3346,6 +3362,7 @@ export namespace Prisma {
readonly status: FieldRef<"User", 'UserStatus'>
readonly lastActiveAt: FieldRef<"User", 'DateTime'>
readonly pterodactylClientApiKey: FieldRef<"User", 'String'>
readonly timeZone: FieldRef<"User", 'String'>
}
@ -20960,7 +20977,8 @@ export namespace Prisma {
createdAt: 'createdAt',
status: 'status',
lastActiveAt: 'lastActiveAt',
pterodactylClientApiKey: 'pterodactylClientApiKey'
pterodactylClientApiKey: 'pterodactylClientApiKey',
timeZone: 'timeZone'
};
export type UserScalarFieldEnum = (typeof UserScalarFieldEnum)[keyof typeof UserScalarFieldEnum]
@ -21394,6 +21412,7 @@ export namespace Prisma {
status?: EnumUserStatusFilter<"User"> | $Enums.UserStatus
lastActiveAt?: DateTimeNullableFilter<"User"> | Date | string | null
pterodactylClientApiKey?: StringNullableFilter<"User"> | string | null
timeZone?: StringNullableFilter<"User"> | string | null
team?: XOR<TeamNullableScalarRelationFilter, TeamWhereInput> | null
ledTeam?: XOR<TeamNullableScalarRelationFilter, TeamWhereInput> | null
matchesAsTeamA?: MatchListRelationFilter
@ -21425,6 +21444,7 @@ export namespace Prisma {
status?: SortOrder
lastActiveAt?: SortOrderInput | SortOrder
pterodactylClientApiKey?: SortOrderInput | SortOrder
timeZone?: SortOrderInput | SortOrder
team?: TeamOrderByWithRelationInput
ledTeam?: TeamOrderByWithRelationInput
matchesAsTeamA?: MatchOrderByRelationAggregateInput
@ -21459,6 +21479,7 @@ export namespace Prisma {
status?: EnumUserStatusFilter<"User"> | $Enums.UserStatus
lastActiveAt?: DateTimeNullableFilter<"User"> | Date | string | null
pterodactylClientApiKey?: StringNullableFilter<"User"> | string | null
timeZone?: StringNullableFilter<"User"> | string | null
team?: XOR<TeamNullableScalarRelationFilter, TeamWhereInput> | null
ledTeam?: XOR<TeamNullableScalarRelationFilter, TeamWhereInput> | null
matchesAsTeamA?: MatchListRelationFilter
@ -21490,6 +21511,7 @@ export namespace Prisma {
status?: SortOrder
lastActiveAt?: SortOrderInput | SortOrder
pterodactylClientApiKey?: SortOrderInput | SortOrder
timeZone?: SortOrderInput | SortOrder
_count?: UserCountOrderByAggregateInput
_avg?: UserAvgOrderByAggregateInput
_max?: UserMaxOrderByAggregateInput
@ -21515,6 +21537,7 @@ export namespace Prisma {
status?: EnumUserStatusWithAggregatesFilter<"User"> | $Enums.UserStatus
lastActiveAt?: DateTimeNullableWithAggregatesFilter<"User"> | Date | string | null
pterodactylClientApiKey?: StringNullableWithAggregatesFilter<"User"> | string | null
timeZone?: StringNullableWithAggregatesFilter<"User"> | string | null
}
export type TeamWhereInput = {
@ -22778,6 +22801,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -22809,6 +22833,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -22838,6 +22863,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -22869,6 +22895,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -22899,6 +22926,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
}
export type UserUpdateManyMutationInput = {
@ -22915,6 +22943,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
}
export type UserUncheckedUpdateManyInput = {
@ -22932,6 +22961,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
}
export type TeamCreateInput = {
@ -24479,6 +24509,7 @@ export namespace Prisma {
status?: SortOrder
lastActiveAt?: SortOrder
pterodactylClientApiKey?: SortOrder
timeZone?: SortOrder
}
export type UserAvgOrderByAggregateInput = {
@ -24500,6 +24531,7 @@ export namespace Prisma {
status?: SortOrder
lastActiveAt?: SortOrder
pterodactylClientApiKey?: SortOrder
timeZone?: SortOrder
}
export type UserMinOrderByAggregateInput = {
@ -24517,6 +24549,7 @@ export namespace Prisma {
status?: SortOrder
lastActiveAt?: SortOrder
pterodactylClientApiKey?: SortOrder
timeZone?: SortOrder
}
export type UserSumOrderByAggregateInput = {
@ -28555,6 +28588,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchCreateNestedManyWithoutTeamBUsersInput
@ -28585,6 +28619,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
invites?: TeamInviteUncheckedCreateNestedManyWithoutUserInput
@ -28618,6 +28653,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchCreateNestedManyWithoutTeamBUsersInput
@ -28647,6 +28683,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -29001,6 +29038,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUpdateManyWithoutTeamBUsersNestedInput
@ -29031,6 +29069,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
invites?: TeamInviteUncheckedUpdateManyWithoutUserNestedInput
@ -29079,6 +29118,7 @@ export namespace Prisma {
status?: EnumUserStatusFilter<"User"> | $Enums.UserStatus
lastActiveAt?: DateTimeNullableFilter<"User"> | Date | string | null
pterodactylClientApiKey?: StringNullableFilter<"User"> | string | null
timeZone?: StringNullableFilter<"User"> | string | null
}
export type TeamInviteUpsertWithWhereUniqueWithoutTeamInput = {
@ -29207,6 +29247,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -29237,6 +29278,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -29320,6 +29362,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -29350,6 +29393,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -29423,6 +29467,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -29453,6 +29498,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -29497,6 +29543,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -29527,6 +29574,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -29633,6 +29681,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamB?: MatchCreateNestedManyWithoutTeamBUsersInput
@ -29663,6 +29712,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
invites?: TeamInviteUncheckedCreateNestedManyWithoutUserInput
@ -29696,6 +29746,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -29726,6 +29777,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
invites?: TeamInviteUncheckedCreateNestedManyWithoutUserInput
@ -30315,6 +30367,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -30345,6 +30398,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -30576,6 +30630,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -30606,6 +30661,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -30757,6 +30813,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -30787,6 +30844,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -30898,6 +30956,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -30928,6 +30987,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -31107,6 +31167,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -31137,6 +31198,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -31170,6 +31232,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -31200,6 +31263,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -31401,6 +31465,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -31431,6 +31496,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -31470,6 +31536,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -31500,6 +31567,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -31668,6 +31736,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -31698,6 +31767,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -31815,6 +31885,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -31845,6 +31916,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -31873,6 +31945,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -31903,6 +31976,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -31947,6 +32021,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -31977,6 +32052,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -32230,6 +32306,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -32260,6 +32337,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -32384,6 +32462,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -32414,6 +32493,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -32550,6 +32630,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
team?: TeamCreateNestedOneWithoutMembersInput
ledTeam?: TeamCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchCreateNestedManyWithoutTeamAUsersInput
@ -32580,6 +32661,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
ledTeam?: TeamUncheckedCreateNestedOneWithoutLeaderInput
matchesAsTeamA?: MatchUncheckedCreateNestedManyWithoutTeamAUsersInput
matchesAsTeamB?: MatchUncheckedCreateNestedManyWithoutTeamBUsersInput
@ -32697,6 +32779,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -32727,6 +32810,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -33325,6 +33409,7 @@ export namespace Prisma {
status?: $Enums.UserStatus
lastActiveAt?: Date | string | null
pterodactylClientApiKey?: string | null
timeZone?: string | null
}
export type TeamInviteCreateManyTeamInput = {
@ -33441,6 +33526,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUpdateManyWithoutTeamBUsersNestedInput
@ -33470,6 +33556,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
@ -33499,6 +33586,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
}
export type TeamInviteUpdateWithoutTeamInput = {
@ -33871,6 +33959,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamB?: MatchUpdateManyWithoutTeamBUsersNestedInput
@ -33901,6 +33990,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamB?: MatchUncheckedUpdateManyWithoutTeamBUsersNestedInput
invites?: TeamInviteUncheckedUpdateManyWithoutUserNestedInput
@ -33930,6 +34020,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
}
export type UserUpdateWithoutMatchesAsTeamBInput = {
@ -33946,6 +34037,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
team?: TeamUpdateOneWithoutMembersNestedInput
ledTeam?: TeamUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUpdateManyWithoutTeamAUsersNestedInput
@ -33976,6 +34068,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
ledTeam?: TeamUncheckedUpdateOneWithoutLeaderNestedInput
matchesAsTeamA?: MatchUncheckedUpdateManyWithoutTeamAUsersNestedInput
invites?: TeamInviteUncheckedUpdateManyWithoutUserNestedInput
@ -34005,6 +34098,7 @@ export namespace Prisma {
status?: EnumUserStatusFieldUpdateOperationsInput | $Enums.UserStatus
lastActiveAt?: NullableDateTimeFieldUpdateOperationsInput | Date | string | null
pterodactylClientApiKey?: NullableStringFieldUpdateOperationsInput | string | null
timeZone?: NullableStringFieldUpdateOperationsInput | string | null
}
export type MatchPlayerUpdateWithoutMatchInput = {

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
{
"name": "prisma-client-dccc49918d4c87081feec825d7e8f9d86eb03460cb722e1aeb3c8b2bf7d2181c",
"name": "prisma-client-8cab75712245f682edd2dce1ca5952c94f39f37ac5ea8dd517ddd6b716af1837",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",
"browser": "default.js",
"exports": {
"./client": {
"require": {
@ -125,6 +125,12 @@
"import": "./runtime/react-native.js",
"default": "./runtime/react-native.js"
},
"./runtime/index-browser": {
"types": "./runtime/index-browser.d.ts",
"require": "./runtime/index-browser.js",
"import": "./runtime/index-browser.mjs",
"default": "./runtime/index-browser.mjs"
},
"./generator-build": {
"require": "./generator-build/index.js",
"import": "./generator-build/index.js",
@ -145,6 +151,33 @@
},
"./*": "./*"
},
"version": "6.15.0",
"sideEffects": false
"version": "6.16.2",
"sideEffects": false,
"imports": {
"#wasm-engine-loader": {
"edge-light": "./wasm-edge-light-loader.mjs",
"workerd": "./wasm-worker-loader.mjs",
"worker": "./wasm-worker-loader.mjs",
"default": "./wasm-worker-loader.mjs"
},
"#main-entry-point": {
"require": {
"node": "./index.js",
"edge-light": "./wasm.js",
"workerd": "./wasm.js",
"worker": "./wasm.js",
"browser": "./index-browser.js",
"default": "./index.js"
},
"import": {
"node": "./index.js",
"edge-light": "./wasm.js",
"workerd": "./wasm.js",
"worker": "./wasm.js",
"browser": "./index-browser.js",
"default": "./index.js"
},
"default": "./index.js"
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -52,6 +52,8 @@ model User {
readyAcceptances MatchReady[] @relation("MatchReadyUser")
pterodactylClientApiKey String?
timeZone String? // IANA-TZ, z.B. "Europe/Berlin"
}
enum UserStatus {

View File

@ -1 +1 @@
export * from "./index"
export * from "./default"

File diff suppressed because one or more lines are too long

View File

@ -32,6 +32,7 @@ export const authOptions = (req: NextRequest): NextAuthOptions => ({
avatar: steamProfile.avatarfull,
location: steamProfile.loccountrycode,
isAdmin: false,
timeZone:
...(location && { location }),
},
})

View File

@ -1,5 +1,21 @@
{
"disconnect": "Verbindung trennen",
"common": {
"save": "Speichern",
"saving": "Wrid gespeichert",
"saved": "Gespeichert",
"save-failed": "Speichern fehlgeschlagen",
"no-changes": "Keine Änderungen",
"here": "hier",
"disconnect": "Trennen",
"reset": "Zurücksetzen",
"monday": "Montag",
"tuesday": "Dienstag",
"wednesday": "Mittwoch",
"thursday": "Donnerstag",
"friday": "Freitag",
"saturday": "Samstag",
"sunday": "Sonntag"
},
"nav": {
"dashboard": "Dashboard",
"teams": {
@ -39,23 +55,36 @@
"short": "Account",
"description": "Verwalte deine Kontoeinstellungen und verbundenen Dienste.",
"find-code": "Deinen Code findest du",
"here": "hier",
"url": "https://help.steampowered.com/de/wizard/HelpWithGameIssue/?appid=730&issueid=128",
"page": {
"AuthCodeSettings": {
"name": "Authentifizierungscode",
"question": "Was ist der Authentifizierungscode?",
"description": "Drittanbieter-Webseiten und -Anwendungen können diesen Authentifizierungscode nutzen, um auf deine Match-Historie, deine Gesamtleistung in diesen Matches zuzugreifen, Wiederholungen herunterzuladen und dein Gameplay zu analysieren.",
"button-disconnect": "Trennen"
"invalid": "Ungültiger Authentifizierungscode"
},
"ShareCodeSettings": {
"name": "Austauschcode",
"question": "Was ist der Austauschcode?",
"description": "Mit dem Austauschcode können Anwendungen dein zuletzt ausgetragenes offizielles Match finden und analysieren."
"description": "Mit dem Austauschcode können Anwendungen dein zuletzt ausgetragenes offizielles Match finden und analysieren.",
"invalid-share-code": "Abgelaufener Austauschcode! Deinen neuen Austauschcode findest du"
},
"AppearanceSettings": {
"name": "Erscheinungsbild",
"description": "Wähle dein bevorzugtes Design. Du kannst einen festen Stil verwenden oder die Systemeinstellung übernehmen."
"description": "Wähle dein bevorzugtes Design. Du kannst einen festen Stil verwenden oder die Systemeinstellung übernehmen.",
"theme-mode": "Theme-Modus",
"theme-mode-description": "Die Darstellung passt sich automatisch deinem Gerät an, wenn „System“ gewählt ist.",
"theme": {
"system": "System",
"light": "Hell",
"dark": "Dunkel"
}
},
"UserSettings": {
"timezone-label": "Zeitzone",
"timezone-help": "Wird für Datums-/Zeitangaben in der App genutzt.",
"timezone-hint": "Wähle deine IANA-Zeitzone (z. B. Europe/Berlin).",
"timezone-system": "Systemstandard verwenden"
}
}
},
@ -76,7 +105,15 @@
"matches": {
"title": "Geplante Matches",
"description": "Keine Matches geplant.",
"filter": "Nur mein Team anzeigen",
"create-match": "Match erstellen"
"filter": "Nur meine Matches anzeigen",
"create-match": "Match erstellen",
"day": "Tag",
"opens-in": "öffnet in"
},
"notifications": {
"title": "Benachrichtigungen",
"no-notifications": "Keine neuen Benachrichtigungen",
"all": "Alle",
"read": "Gelesen"
}
}

View File

@ -1,5 +1,21 @@
{
"disconnect": "Disconnect",
"common": {
"save": "Save",
"saving": "Saving",
"saved": "Saved",
"save-failed": "Save failed",
"no-changes": "No changes",
"here": "here",
"disconnect": "Disconnect",
"reset": "Reset",
"monday": "Monday",
"tuesday": "Tuesday",
"wednesday": "Wednesday",
"thursday": "Thursday",
"friday": "Friday",
"saturday": "Saturday",
"sunday": "Sunday"
},
"nav": {
"dashboard": "Dashboard",
"teams": {
@ -39,23 +55,36 @@
"short": "Account",
"description": "Manage your account settings and connected services.",
"find-code": "You can find your code",
"here": "here",
"url": "https://help.steampowered.com/en/wizard/HelpWithGameIssue/?appid=730&issueid=128",
"page": {
"AuthCodeSettings": {
"name": "Authentication Code",
"question": "What is the Authentication Code?",
"description": "Third-party websites and applications can use this authentication code to access your match history, your overall performance in those matches, download replays of your matches, and analyze your gameplay.",
"button-disconnect": "Disconnect"
"invalid": "Invalid Authentication Code"
},
"ShareCodeSettings": {
"name": "Match Share Code",
"question": "What is the Match Share Code?",
"description": "With the share code, applications can find and analyze your most recent official match."
"description": "With the share code, applications can find and analyze your most recent official match.",
"invalid-share-code": "Invalid Share Code! You can find your new Share Code"
},
"AppearanceSettings": {
"name": "Appearance",
"description": "Choose your preferred theme. You can use a fixed style or follow your system setting."
"description": "Choose your preferred theme. You can use a fixed style or follow your system setting.",
"theme-mode": "Theme Mode",
"theme-mode-description": "If you choose “System”, the appearance will automatically match your device.",
"theme": {
"system": "System",
"light": "Light",
"dark": "Dark"
}
},
"UserSettings": {
"timezone-label": "Time zone",
"timezone-help": "Used for date/time formatting in the app.",
"timezone-hint": "Choose your IANA time zone (e.g., Europe/Berlin).",
"timezone-system": "Use system default"
}
}
},
@ -76,7 +105,15 @@
"matches": {
"title": "Scheduled Matches",
"description": "No matches scheduled.",
"filter": "Show my team only",
"create-match": "Create Match"
"filter": "Show my matches only",
"create-match": "Create Match",
"day": "Day",
"opens-in": "opens in"
},
"notifications": {
"title": "Notifications",
"no-notifications": "No new notifications",
"all": "All",
"read": "Read"
}
}