timezone via cookies
This commit is contained in:
parent
530425a82c
commit
c03811e860
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState, useCallback, useMemo } from 'react'
|
||||
import { useEffect, useState, useCallback } from 'react'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useRouter, usePathname } from '@/i18n/navigation'
|
||||
import { useTranslations, useLocale } from 'next-intl'
|
||||
@ -99,36 +99,19 @@ function dateKeyInTZ(date: Date | string, timeZone: string): string {
|
||||
return `${p.year}-${pad(p.month)}-${pad(p.day)}`; // YYYY-MM-DD
|
||||
}
|
||||
|
||||
function readCookieClient(name: string): string | undefined {
|
||||
if (typeof document === 'undefined') return undefined
|
||||
const m = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'))
|
||||
return m ? decodeURIComponent(m[1]) : undefined
|
||||
}
|
||||
|
||||
function isValidIanaTzClient(tz?: string): tz is string {
|
||||
if (!tz) return false
|
||||
try { new Intl.DateTimeFormat('en-US', { timeZone: tz }).format(0); return true } catch { return false }
|
||||
}
|
||||
|
||||
export default function CommunityMatchList({ matchType }: Props) {
|
||||
const { data: session } = useSession()
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const locale = useLocale()
|
||||
const [userTZ, setUserTZ] = useState<string>(() => {
|
||||
const fromCookie = readCookieClient('tz')
|
||||
if (isValidIanaTzClient(fromCookie)) return fromCookie!
|
||||
if (session?.user?.timeZone && isValidIanaTzClient(session.user.timeZone)) return session.user.timeZone
|
||||
return Intl.DateTimeFormat().resolvedOptions().timeZone || 'Europe/Berlin'
|
||||
}
|
||||
)
|
||||
console.log(userTZ);
|
||||
const weekdayFmt = useMemo(() =>
|
||||
new Intl.DateTimeFormat(locale === 'de' ? 'de-DE' : 'en-GB', {
|
||||
const userTZ = getUserTimeZone(session?.user?.timeZone);
|
||||
const weekdayFmt = new Intl.DateTimeFormat(
|
||||
locale === 'de' ? 'de-DE' : 'en-GB',
|
||||
{
|
||||
weekday: 'long',
|
||||
timeZone: userTZ,
|
||||
}),
|
||||
[locale, userTZ])
|
||||
}
|
||||
);
|
||||
|
||||
const tMatches = useTranslations('matches')
|
||||
const tMapvote = useTranslations('mapvote')
|
||||
@ -162,24 +145,6 @@ export default function CommunityMatchList({ matchType }: Props) {
|
||||
|
||||
const [now, setNow] = useState(() => Date.now())
|
||||
|
||||
// Beim Mount & Tab-Fokus Cookie neu einlesen
|
||||
useEffect(() => {
|
||||
const apply = () => {
|
||||
const fromCookie = readCookieClient('tz')
|
||||
if (isValidIanaTzClient(fromCookie)) {
|
||||
setUserTZ(prev => (prev === fromCookie ? prev : fromCookie!))
|
||||
}
|
||||
}
|
||||
apply()
|
||||
const onFocus = () => apply()
|
||||
window.addEventListener('focus', onFocus)
|
||||
document.addEventListener('visibilitychange', onFocus)
|
||||
return () => {
|
||||
window.removeEventListener('focus', onFocus)
|
||||
document.removeEventListener('visibilitychange', onFocus)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => setNow(Date.now()), 1000)
|
||||
return () => clearInterval(id)
|
||||
@ -639,4 +604,4 @@ function formatCountdown(ms: number) {
|
||||
const s = totalSec % 60
|
||||
const pad = (n:number)=>String(n).padStart(2,'0')
|
||||
return `${h}:${pad(m)}:${pad(s)}`
|
||||
}
|
||||
}
|
||||
@ -35,11 +35,11 @@ exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 6.16.2
|
||||
* Prisma Client JS version: 6.16.1
|
||||
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "6.16.2",
|
||||
client: "6.16.1",
|
||||
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ const config = {
|
||||
"value": "prisma-client-js"
|
||||
},
|
||||
"output": {
|
||||
"value": "C:\\Users\\Rother\\fork\\ironie-nextjs\\src\\generated\\prisma",
|
||||
"value": "C:\\Users\\Chris\\fork\\ironie-nextjs\\src\\generated\\prisma",
|
||||
"fromEnvVar": null
|
||||
},
|
||||
"config": {
|
||||
@ -384,7 +384,7 @@ const config = {
|
||||
}
|
||||
],
|
||||
"previewFeatures": [],
|
||||
"sourceFilePath": "C:\\Users\\Rother\\fork\\ironie-nextjs\\prisma\\schema.prisma",
|
||||
"sourceFilePath": "C:\\Users\\Chris\\fork\\ironie-nextjs\\prisma\\schema.prisma",
|
||||
"isCustomOutput": true
|
||||
},
|
||||
"relativeEnvPaths": {
|
||||
@ -392,12 +392,13 @@ const config = {
|
||||
"schemaEnvPath": "../../../.env"
|
||||
},
|
||||
"relativePath": "../../../prisma",
|
||||
"clientVersion": "6.16.2",
|
||||
"clientVersion": "6.16.1",
|
||||
"engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
|
||||
"datasourceNames": [
|
||||
"db"
|
||||
],
|
||||
"activeProvider": "postgresql",
|
||||
"postinstall": false,
|
||||
"inlineDatasources": {
|
||||
"db": {
|
||||
"url": {
|
||||
|
||||
@ -20,11 +20,11 @@ exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 6.16.2
|
||||
* Prisma Client JS version: 6.16.1
|
||||
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "6.16.2",
|
||||
client: "6.16.1",
|
||||
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
|
||||
}
|
||||
|
||||
|
||||
2
src/generated/prisma/index.d.ts
vendored
2
src/generated/prisma/index.d.ts
vendored
@ -460,7 +460,7 @@ export namespace Prisma {
|
||||
export import Exact = $Public.Exact
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 6.16.2
|
||||
* Prisma Client JS version: 6.16.1
|
||||
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
||||
*/
|
||||
export type PrismaVersion = {
|
||||
|
||||
@ -35,11 +35,11 @@ exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 6.16.2
|
||||
* Prisma Client JS version: 6.16.1
|
||||
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "6.16.2",
|
||||
client: "6.16.1",
|
||||
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
|
||||
}
|
||||
|
||||
@ -371,7 +371,7 @@ const config = {
|
||||
"value": "prisma-client-js"
|
||||
},
|
||||
"output": {
|
||||
"value": "C:\\Users\\Rother\\fork\\ironie-nextjs\\src\\generated\\prisma",
|
||||
"value": "C:\\Users\\Chris\\fork\\ironie-nextjs\\src\\generated\\prisma",
|
||||
"fromEnvVar": null
|
||||
},
|
||||
"config": {
|
||||
@ -385,7 +385,7 @@ const config = {
|
||||
}
|
||||
],
|
||||
"previewFeatures": [],
|
||||
"sourceFilePath": "C:\\Users\\Rother\\fork\\ironie-nextjs\\prisma\\schema.prisma",
|
||||
"sourceFilePath": "C:\\Users\\Chris\\fork\\ironie-nextjs\\prisma\\schema.prisma",
|
||||
"isCustomOutput": true
|
||||
},
|
||||
"relativeEnvPaths": {
|
||||
@ -393,12 +393,13 @@ const config = {
|
||||
"schemaEnvPath": "../../../.env"
|
||||
},
|
||||
"relativePath": "../../../prisma",
|
||||
"clientVersion": "6.16.2",
|
||||
"clientVersion": "6.16.1",
|
||||
"engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
|
||||
"datasourceNames": [
|
||||
"db"
|
||||
],
|
||||
"activeProvider": "postgresql",
|
||||
"postinstall": false,
|
||||
"inlineDatasources": {
|
||||
"db": {
|
||||
"url": {
|
||||
|
||||
@ -151,7 +151,7 @@
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"version": "6.16.2",
|
||||
"version": "6.16.1",
|
||||
"sideEffects": false,
|
||||
"imports": {
|
||||
"#wasm-engine-loader": {
|
||||
|
||||
BIN
src/generated/prisma/query_engine-windows.dll.node.tmp17904
Normal file
BIN
src/generated/prisma/query_engine-windows.dll.node.tmp17904
Normal file
Binary file not shown.
BIN
src/generated/prisma/query_engine-windows.dll.node.tmp24668
Normal file
BIN
src/generated/prisma/query_engine-windows.dll.node.tmp24668
Normal file
Binary file not shown.
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
6
src/generated/prisma/runtime/react-native.js
vendored
6
src/generated/prisma/runtime/react-native.js
vendored
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
@ -54,6 +54,9 @@ model User {
|
||||
pterodactylClientApiKey String?
|
||||
|
||||
timeZone String? // IANA-TZ, z.B. "Europe/Berlin"
|
||||
|
||||
// ✅ Datenschutz: darf eingeladen werden?
|
||||
canBeInvited Boolean @default(true)
|
||||
}
|
||||
|
||||
enum UserStatus {
|
||||
@ -173,7 +176,7 @@ model MatchPlayer {
|
||||
teamId String?
|
||||
team Team? @relation(fields: [teamId], references: [id])
|
||||
|
||||
match Match @relation(fields: [matchId], references: [id])
|
||||
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [steamId], references: [steamId])
|
||||
|
||||
stats PlayerStats?
|
||||
@ -239,7 +242,7 @@ model RankHistory {
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
user User @relation("UserRankHistory", fields: [steamId], references: [steamId])
|
||||
match Match? @relation("MatchRankHistory", fields: [matchId], references: [id])
|
||||
match Match? @relation("MatchRankHistory", fields: [matchId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model Schedule {
|
||||
@ -263,7 +266,7 @@ model Schedule {
|
||||
confirmedBy User? @relation("ConfirmedSchedules", fields: [confirmedById], references: [steamId])
|
||||
|
||||
linkedMatchId String? @unique
|
||||
linkedMatch Match? @relation(fields: [linkedMatchId], references: [id])
|
||||
linkedMatch Match? @relation(fields: [linkedMatchId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@ -293,7 +296,7 @@ model DemoFile {
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
match Match @relation(fields: [matchId], references: [id])
|
||||
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [steamId], references: [steamId])
|
||||
}
|
||||
|
||||
@ -326,7 +329,7 @@ enum MapVoteAction {
|
||||
model MapVote {
|
||||
id String @id @default(uuid())
|
||||
matchId String @unique
|
||||
match Match @relation(fields: [matchId], references: [id])
|
||||
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
||||
|
||||
bestOf Int @default(3)
|
||||
mapPool String[]
|
||||
@ -359,7 +362,7 @@ model MapVoteStep {
|
||||
chosenBy String?
|
||||
chooser User? @relation("VoteStepChooser", fields: [chosenBy], references: [steamId])
|
||||
|
||||
vote MapVote @relation(fields: [voteId], references: [id])
|
||||
vote MapVote @relation(fields: [voteId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([voteId, order])
|
||||
@@index([teamId])
|
||||
@ -371,7 +374,7 @@ model MatchReady {
|
||||
steamId String
|
||||
acceptedAt DateTime @default(now())
|
||||
|
||||
match Match @relation("MatchReadyMatch", fields: [matchId], references: [id])
|
||||
match Match @relation("MatchReadyMatch", fields: [matchId], references: [id], onDelete: Cascade)
|
||||
user User @relation("MatchReadyUser", fields: [steamId], references: [steamId])
|
||||
|
||||
@@id([matchId, steamId])
|
||||
|
||||
@ -35,11 +35,11 @@ exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 6.16.2
|
||||
* Prisma Client JS version: 6.16.1
|
||||
* Query Engine version: 1c57fdcd7e44b29b9313256c76699e91c3ac3c43
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "6.16.2",
|
||||
client: "6.16.1",
|
||||
engine: "1c57fdcd7e44b29b9313256c76699e91c3ac3c43"
|
||||
}
|
||||
|
||||
@ -370,7 +370,7 @@ const config = {
|
||||
"value": "prisma-client-js"
|
||||
},
|
||||
"output": {
|
||||
"value": "C:\\Users\\Rother\\fork\\ironie-nextjs\\src\\generated\\prisma",
|
||||
"value": "C:\\Users\\Chris\\fork\\ironie-nextjs\\src\\generated\\prisma",
|
||||
"fromEnvVar": null
|
||||
},
|
||||
"config": {
|
||||
@ -384,7 +384,7 @@ const config = {
|
||||
}
|
||||
],
|
||||
"previewFeatures": [],
|
||||
"sourceFilePath": "C:\\Users\\Rother\\fork\\ironie-nextjs\\prisma\\schema.prisma",
|
||||
"sourceFilePath": "C:\\Users\\Chris\\fork\\ironie-nextjs\\prisma\\schema.prisma",
|
||||
"isCustomOutput": true
|
||||
},
|
||||
"relativeEnvPaths": {
|
||||
@ -392,12 +392,13 @@ const config = {
|
||||
"schemaEnvPath": "../../../.env"
|
||||
},
|
||||
"relativePath": "../../../prisma",
|
||||
"clientVersion": "6.16.2",
|
||||
"clientVersion": "6.16.1",
|
||||
"engineVersion": "1c57fdcd7e44b29b9313256c76699e91c3ac3c43",
|
||||
"datasourceNames": [
|
||||
"db"
|
||||
],
|
||||
"activeProvider": "postgresql",
|
||||
"postinstall": false,
|
||||
"inlineDatasources": {
|
||||
"db": {
|
||||
"url": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user