← back to Open Seo
src/client/features/domain/domainRouteState.ts
112 lines
import {
DEFAULT_DOMAIN_KEYWORDS_PAGE_SIZE,
type DomainSearchParams,
} from "@/types/schemas/domain";
import {
DEFAULT_LOCATION_CODE,
isLabsLocationCode,
} from "@/client/features/keywords/locations";
import type { ProjectMarket } from "@/client/features/projects/types";
import {
EMPTY_DOMAIN_FILTERS,
type DomainActiveTab,
type DomainFilterValues,
type DomainSortMode,
type KeywordsFilterValues,
type PagesFilterValues,
type SortOrder,
} from "@/client/features/domain/types";
import {
KEYWORD_FILTER_FIELDS,
PAGE_FILTER_FIELDS,
PAGE_SEARCH_PARAM_BY_FIELD,
} from "@/client/features/domain/domainFilterUtils";
import { resolveSortOrder, toSortMode, toSortOrder } from "./utils";
export type DomainOverviewRouteState = {
domain: string;
subdomains: boolean;
sort: DomainSortMode;
order: SortOrder;
tab: DomainActiveTab;
defaultLocationCode: number;
locationCode: number;
sentLocationCode: number | undefined;
page: number;
pageSize: number;
appliedFilters: DomainFilterValues;
appliedPageFilters: PagesFilterValues;
hasAppliedKeywordFilters: boolean;
hasAppliedPageFilters: boolean;
};
function numberToFilterString(value: number | undefined): string {
if (value == null || !Number.isFinite(value)) return "";
return String(value);
}
export function getDomainRouteState(
search: DomainSearchParams,
projectMarket?: ProjectMarket,
): DomainOverviewRouteState {
const normalizedSort = toSortMode(search.sort ?? null) ?? "traffic";
const defaultLocationCode =
projectMarket && isLabsLocationCode(projectMarket.locationCode)
? projectMarket.locationCode
: DEFAULT_LOCATION_CODE;
// Domain analytics is Labs-backed; Google-Ads-only countries aren't valid.
const normalizedLocationCode =
search.loc != null && isLabsLocationCode(search.loc)
? search.loc
: defaultLocationCode;
return {
domain: search.domain ?? "",
subdomains: search.subdomains ?? true,
sort: normalizedSort,
order: resolveSortOrder(normalizedSort, toSortOrder(search.order ?? null)),
tab: search.tab ?? "keywords",
defaultLocationCode,
locationCode: normalizedLocationCode,
sentLocationCode: search.loc,
page: search.page != null && search.page > 0 ? search.page : 1,
pageSize: search.size ?? DEFAULT_DOMAIN_KEYWORDS_PAGE_SIZE,
appliedFilters: {
include: search.include ?? EMPTY_DOMAIN_FILTERS.include,
exclude: search.exclude ?? EMPTY_DOMAIN_FILTERS.exclude,
minTraffic: numberToFilterString(search.minTraffic),
maxTraffic: numberToFilterString(search.maxTraffic),
minVol: numberToFilterString(search.minVol),
maxVol: numberToFilterString(search.maxVol),
minCpc: numberToFilterString(search.minCpc),
maxCpc: numberToFilterString(search.maxCpc),
minKd: numberToFilterString(search.minKd),
maxKd: numberToFilterString(search.maxKd),
minRank: numberToFilterString(search.minRank),
maxRank: numberToFilterString(search.maxRank),
},
appliedPageFilters: {
include: search.pInclude ?? EMPTY_DOMAIN_FILTERS.include,
exclude: search.pExclude ?? EMPTY_DOMAIN_FILTERS.exclude,
minTraffic: numberToFilterString(search.pMinTraffic),
maxTraffic: numberToFilterString(search.pMaxTraffic),
minVol: numberToFilterString(search.pMinVol),
maxVol: numberToFilterString(search.pMaxVol),
},
hasAppliedKeywordFilters: hasKeywordSearchFilters(search),
hasAppliedPageFilters: hasPageSearchFilters(search),
};
}
function hasKeywordSearchFilters(search: DomainSearchParams): boolean {
return KEYWORD_FILTER_FIELDS.some(
(key: keyof KeywordsFilterValues) => search[key] != null,
);
}
function hasPageSearchFilters(search: DomainSearchParams): boolean {
return PAGE_FILTER_FIELDS.some(
(key) => search[PAGE_SEARCH_PARAM_BY_FIELD[key]] != null,
);
}