fix(native): read { items, counts, limits } from custom-domains GET
The /api/custom-domains endpoint changed shape with the slot-pool split
in commit f2b81ee — it now returns { items, counts, limits } where it
used to return a bare CustomDomain[]. The hook was still matching
Array.isArray(res) or res.domains and silently fell back to an empty
list, so a successful POST went unreflected on the blocker page (user
reported "kein fehler aber domain taucht nicht in der liste" after
adding communications@only4subscribers.com).
Now reads items / counts / limits when present, prefers the API-driven
counts and limits over the client-side derivation (still kept as a
fallback for the stale-bundle window between deploys). Legacy bare-
array + { domains } shapes still resolve too in case a cached client
hits this code path before the new backend lands.
This commit is contained in:
parent
63b6d2ff11
commit
c2323c1aba
@ -97,19 +97,36 @@ export function isValidDomain(input: string): boolean {
|
||||
*/
|
||||
export function useCustomDomains(plan: Plan): UseCustomDomainsReturn {
|
||||
const [domains, setDomains] = useState<CustomDomain[]>([]);
|
||||
const [apiCounts, setApiCounts] = useState<CountsByType | null>(null);
|
||||
const [apiLimits, setApiLimits] = useState<LimitsByType | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(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<CustomDomain[] | { domains?: CustomDomain[] }>(
|
||||
'/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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user