rebreak-monorepo/apps/rebreak-native/hooks/useWebContentDomains.ts
chahinebrini f555c5e4d8 feat(vip): Tunesien (TN) als VIP-Land + kuratierte Starter-Liste
TN-User fielen bisher mangels TN-Liste auf die DE-Liste zurück. Jetzt
eigene (kurze) TN-Starter-Liste: mbet216.com, 2xbet365.com, cesar365.com,
icombet.com, unibet365.net (von einem TN-Test-User gemeldet).

TN in COUNTRY_KEYS (webcontent-Endpoint) + VIP_COUNTRIES (Geräte-Region-
Auflösung + Add-Check). Native Region-Logik ist generisch (Locale.region
→ JSON-Key) — kein Native-Code nötig. gambling-domains.json _meta v3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 20:52:20 +02:00

67 lines
2.1 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from 'react';
import * as Localization from 'expo-localization';
import { apiFetch } from '../lib/api';
/**
* Landabhängige VIP-Layer-2-Liste.
*
* Das Backend (`GET /api/protection/webcontent-domains`) liefert die
* komponierte Liste pro Land (Custom-Domains gekappt auf 30 + kuratierte
* Auffüllung, dedup, Cap 50). Hier wählen wir die Country-Slice nach der
* GERÄTE-Region aus — dasselbe Signal, das auch der native iOS-webContent-
* Filter nutzt (`Locale.current.region`).
*/
const VIP_COUNTRIES = ['DE', 'GB', 'FR', 'TN'] as const;
export type VipCountry = (typeof VIP_COUNTRIES)[number];
/** Geräte-Region → unterstützter VIP-Ländercode. Fallback DE. */
export function resolveVipCountry(): VipCountry {
const region = Localization.getLocales()[0]?.regionCode?.toUpperCase();
if (region && (VIP_COUNTRIES as readonly string[]).includes(region)) {
return region as VipCountry;
}
return 'DE';
}
type WebContentResponse = { _meta?: unknown } & Record<string, string[]>;
export function useWebContentDomains() {
const [country] = useState<VipCountry>(resolveVipCountry);
const [domains, setDomains] = useState<string[] | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const mountedRef = useRef(true);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
const refetch = useCallback(async () => {
try {
const res = await apiFetch<WebContentResponse>(
'/api/protection/webcontent-domains',
);
if (!mountedRef.current) return;
const list = Array.isArray(res?.[country]) ? res[country] : [];
setDomains(list);
setError(null);
} catch (e: any) {
if (!mountedRef.current) return;
console.warn('[useWebContentDomains] fetch failed:', e?.message ?? e);
setError(e?.message ?? 'fetch_failed');
} finally {
if (mountedRef.current) setLoading(false);
}
}, [country]);
useEffect(() => {
refetch();
}, [refetch]);
return { country, domains, loading, error, refetch };
}