diff --git a/apps/rebreak-native/hooks/useCustomDomains.ts b/apps/rebreak-native/hooks/useCustomDomains.ts index 9bada2a..21d00e4 100644 --- a/apps/rebreak-native/hooks/useCustomDomains.ts +++ b/apps/rebreak-native/hooks/useCustomDomains.ts @@ -97,19 +97,36 @@ export function isValidDomain(input: string): boolean { */ export function useCustomDomains(plan: Plan): UseCustomDomainsReturn { const [domains, setDomains] = useState([]); + const [apiCounts, setApiCounts] = useState(null); + const [apiLimits, setApiLimits] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchDomains = useCallback(async () => { try { - // Backend (`server/api/custom-domains/index.get.ts`) gibt Array DIREKT zurück, - // kein { domains: [...] }-Wrapper. - const res = await apiFetch( - '/api/custom-domains', - ); - const arr = Array.isArray(res) ? res : (res?.domains ?? []); - console.log('[useCustomDomains] fetched:', arr.length, 'domains', arr.slice(0, 3)); + // Backend `GET /api/custom-domains` returns + // { items: CustomDomain[], counts: { web, mail }, limits: { web, mail } } + // since the slot-pool split (commit f2b81ee). Legacy fall-throughs cover + // an older shape (bare array or { domains }) in case a cached client + // ever hits this code path before the deploy lands. + const res = await apiFetch< + | CustomDomain[] + | { domains?: CustomDomain[] } + | { items?: CustomDomain[]; counts?: CountsByType; limits?: LimitsByType } + >('/api/custom-domains'); + let arr: CustomDomain[] = []; + let counts: CountsByType | null = null; + let limits: LimitsByType | null = null; + if (Array.isArray(res)) { + arr = res; + } else if (res) { + arr = (res as any).items ?? (res as any).domains ?? []; + counts = (res as any).counts ?? null; + limits = (res as any).limits ?? null; + } setDomains(arr); + setApiCounts(counts); + setApiLimits(limits); setError(null); } catch (e: any) { console.error('[useCustomDomains] fetch failed:', e?.message ?? e); @@ -177,22 +194,22 @@ export function useCustomDomains(plan: Plan): UseCustomDomainsReturn { const tier = deriveTier(plan, domains); - const countsByType: CountsByType = { - web: domains.filter( - (d) => d.status !== 'approved' && (d.type === 'web' || !d.type), - ).length, - mail: domains.filter( - (d) => d.status !== 'approved' && d.type === 'mail_domain', - ).length, - }; - - // Provisional client-side limits — match plan-features.ts on the backend - // (free/pro: 5+5, legend: 10+10). Will be replaced by API-driven values - // once GET /api/custom-domains routes the new { items, counts, limits } - // response shape through the hook. - const webLimit = plan === 'legend' ? 10 : 5; - const mailLimit = plan === 'legend' ? 10 : 5; - const limits: LimitsByType = { web: webLimit, mail: mailLimit }; + // Prefer API-driven counts/limits when the backend returned the new shape; + // fall back to local derivation so the UI works during a stale-bundle moment. + const countsByType: CountsByType = + apiCounts ?? { + web: domains.filter( + (d) => d.status !== 'approved' && (d.type === 'web' || !d.type), + ).length, + mail: domains.filter( + (d) => d.status !== 'approved' && d.type === 'mail_domain', + ).length, + }; + const limits: LimitsByType = + apiLimits ?? { + web: plan === 'legend' ? 10 : 5, + mail: plan === 'legend' ? 10 : 5, + }; return { domains,