|
@@ -22,6 +22,17 @@ import {
|
|
|
BRANCH_LIST_STATE,
|
|
BRANCH_LIST_STATE,
|
|
|
} from "@/lib/frontend/search/useSearchBranches";
|
|
} from "@/lib/frontend/search/useSearchBranches";
|
|
|
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ buildSearchHref,
|
|
|
|
|
+ buildSearchKey,
|
|
|
|
|
+ getScopeLabel,
|
|
|
|
|
+ needsMultiBranchSelectionHint,
|
|
|
|
|
+ buildNextStateForScopeChange,
|
|
|
|
|
+ buildNextStateForToggleBranch,
|
|
|
|
|
+ buildNextStateForClearAllBranches,
|
|
|
|
|
+ buildHrefForSingleBranchSwitch,
|
|
|
|
|
+} from "@/lib/frontend/search/pageHelpers";
|
|
|
|
|
+
|
|
|
import ExplorerPageShell from "@/components/explorer/ExplorerPageShell";
|
|
import ExplorerPageShell from "@/components/explorer/ExplorerPageShell";
|
|
|
import ExplorerSectionCard from "@/components/explorer/ExplorerSectionCard";
|
|
import ExplorerSectionCard from "@/components/explorer/ExplorerSectionCard";
|
|
|
import ForbiddenView from "@/components/system/ForbiddenView";
|
|
import ForbiddenView from "@/components/system/ForbiddenView";
|
|
@@ -30,12 +41,6 @@ import { Button } from "@/components/ui/button";
|
|
|
import SearchForm from "@/components/search/SearchForm";
|
|
import SearchForm from "@/components/search/SearchForm";
|
|
|
import SearchResults from "@/components/search/SearchResults";
|
|
import SearchResults from "@/components/search/SearchResults";
|
|
|
|
|
|
|
|
-function buildSearchHref({ routeBranch, state }) {
|
|
|
|
|
- const base = searchPath(routeBranch);
|
|
|
|
|
- const qs = serializeSearchUrlState(state);
|
|
|
|
|
- return qs ? `${base}?${qs}` : base;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
export default function SearchPage({ branch: routeBranch }) {
|
|
export default function SearchPage({ branch: routeBranch }) {
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
const searchParams = useSearchParams();
|
|
const searchParams = useSearchParams();
|
|
@@ -57,8 +62,7 @@ export default function SearchPage({ branch: routeBranch }) {
|
|
|
}, [parsedUrlState, routeBranch, user]);
|
|
}, [parsedUrlState, routeBranch, user]);
|
|
|
|
|
|
|
|
const searchKey = React.useMemo(() => {
|
|
const searchKey = React.useMemo(() => {
|
|
|
- const qs = serializeSearchUrlState(urlState);
|
|
|
|
|
- return `${routeBranch}|${qs}`;
|
|
|
|
|
|
|
+ return buildSearchKey({ routeBranch, urlState });
|
|
|
}, [routeBranch, urlState]);
|
|
}, [routeBranch, urlState]);
|
|
|
|
|
|
|
|
const [qDraft, setQDraft] = React.useState(urlState.q || "");
|
|
const [qDraft, setQDraft] = React.useState(urlState.q || "");
|
|
@@ -113,25 +117,13 @@ export default function SearchPage({ branch: routeBranch }) {
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
const handleSubmit = React.useCallback(() => {
|
|
const handleSubmit = React.useCallback(() => {
|
|
|
- const nextState = {
|
|
|
|
|
- ...urlState,
|
|
|
|
|
- q: qDraft,
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- pushStateToUrl(nextState);
|
|
|
|
|
- }, [urlState, qDraft, pushStateToUrl]);
|
|
|
|
|
|
|
+ pushStateToUrl({ ...urlState, q: qDraft });
|
|
|
|
|
+ }, [pushStateToUrl, urlState, qDraft]);
|
|
|
|
|
|
|
|
const handleScopeChange = React.useCallback(
|
|
const handleScopeChange = React.useCallback(
|
|
|
(nextScope) => {
|
|
(nextScope) => {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
-
|
|
|
|
|
- const nextState = {
|
|
|
|
|
- ...urlState,
|
|
|
|
|
- scope: nextScope,
|
|
|
|
|
- branches: nextScope === SEARCH_SCOPE.MULTI ? urlState.branches : [],
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- replaceStateToUrl(nextState);
|
|
|
|
|
|
|
+ replaceStateToUrl(buildNextStateForScopeChange({ urlState, nextScope }));
|
|
|
},
|
|
},
|
|
|
[isAdminDev, urlState, replaceStateToUrl]
|
|
[isAdminDev, urlState, replaceStateToUrl]
|
|
|
);
|
|
);
|
|
@@ -139,44 +131,19 @@ export default function SearchPage({ branch: routeBranch }) {
|
|
|
const handleToggleBranch = React.useCallback(
|
|
const handleToggleBranch = React.useCallback(
|
|
|
(branchId) => {
|
|
(branchId) => {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
-
|
|
|
|
|
- const current = Array.isArray(urlState.branches) ? urlState.branches : [];
|
|
|
|
|
- const set = new Set(current);
|
|
|
|
|
-
|
|
|
|
|
- if (set.has(branchId)) set.delete(branchId);
|
|
|
|
|
- else set.add(branchId);
|
|
|
|
|
-
|
|
|
|
|
- const nextState = {
|
|
|
|
|
- ...urlState,
|
|
|
|
|
- scope: SEARCH_SCOPE.MULTI,
|
|
|
|
|
- branches: Array.from(set),
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- replaceStateToUrl(nextState);
|
|
|
|
|
|
|
+ replaceStateToUrl(buildNextStateForToggleBranch({ urlState, branchId }));
|
|
|
},
|
|
},
|
|
|
[isAdminDev, urlState, replaceStateToUrl]
|
|
[isAdminDev, urlState, replaceStateToUrl]
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
const handleClearAllBranches = React.useCallback(() => {
|
|
const handleClearAllBranches = React.useCallback(() => {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
-
|
|
|
|
|
- const nextState = {
|
|
|
|
|
- ...urlState,
|
|
|
|
|
- scope: SEARCH_SCOPE.MULTI,
|
|
|
|
|
- branches: [],
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- replaceStateToUrl(nextState);
|
|
|
|
|
|
|
+ replaceStateToUrl(buildNextStateForClearAllBranches({ urlState }));
|
|
|
}, [isAdminDev, urlState, replaceStateToUrl]);
|
|
}, [isAdminDev, urlState, replaceStateToUrl]);
|
|
|
|
|
|
|
|
const handleLimitChange = React.useCallback(
|
|
const handleLimitChange = React.useCallback(
|
|
|
(nextLimit) => {
|
|
(nextLimit) => {
|
|
|
- const nextState = {
|
|
|
|
|
- ...urlState,
|
|
|
|
|
- limit: nextLimit,
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- replaceStateToUrl(nextState);
|
|
|
|
|
|
|
+ replaceStateToUrl({ ...urlState, limit: nextLimit });
|
|
|
},
|
|
},
|
|
|
[urlState, replaceStateToUrl]
|
|
[urlState, replaceStateToUrl]
|
|
|
);
|
|
);
|
|
@@ -186,16 +153,10 @@ export default function SearchPage({ branch: routeBranch }) {
|
|
|
if (!isAdminDev) return;
|
|
if (!isAdminDev) return;
|
|
|
if (!isValidBranchParam(nextBranch)) return;
|
|
if (!isValidBranchParam(nextBranch)) return;
|
|
|
|
|
|
|
|
- const nextState = {
|
|
|
|
|
- ...urlState,
|
|
|
|
|
- scope: SEARCH_SCOPE.SINGLE,
|
|
|
|
|
- branches: [],
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ const href = buildHrefForSingleBranchSwitch({ nextBranch, urlState });
|
|
|
|
|
+ if (!href) return;
|
|
|
|
|
|
|
|
- const base = searchPath(nextBranch);
|
|
|
|
|
- const qs = serializeSearchUrlState(nextState);
|
|
|
|
|
-
|
|
|
|
|
- router.push(qs ? `${base}?${qs}` : base);
|
|
|
|
|
|
|
+ router.push(href);
|
|
|
},
|
|
},
|
|
|
[isAdminDev, urlState, router]
|
|
[isAdminDev, urlState, router]
|
|
|
);
|
|
);
|
|
@@ -223,28 +184,16 @@ export default function SearchPage({ branch: routeBranch }) {
|
|
|
</span>
|
|
</span>
|
|
|
) : null;
|
|
) : null;
|
|
|
|
|
|
|
|
- const multiCount = Array.isArray(urlState.branches)
|
|
|
|
|
- ? urlState.branches.length
|
|
|
|
|
- : 0;
|
|
|
|
|
-
|
|
|
|
|
- const scopeLabel =
|
|
|
|
|
- urlState.scope === SEARCH_SCOPE.ALL
|
|
|
|
|
- ? "Alle Niederlassungen"
|
|
|
|
|
- : urlState.scope === SEARCH_SCOPE.MULTI
|
|
|
|
|
- ? multiCount > 0
|
|
|
|
|
- ? `${multiCount} Niederlassung${multiCount === 1 ? "" : "en"}`
|
|
|
|
|
- : "Mehrere Niederlassungen"
|
|
|
|
|
- : `Niederlassung ${routeBranch}`;
|
|
|
|
|
|
|
+ const scopeLabel = getScopeLabel({ routeBranch, urlState });
|
|
|
|
|
|
|
|
const resultsDescription = urlState.q
|
|
const resultsDescription = urlState.q
|
|
|
? `Suchbereich: ${scopeLabel}`
|
|
? `Suchbereich: ${scopeLabel}`
|
|
|
: "Geben Sie einen Suchbegriff ein, um zu starten.";
|
|
: "Geben Sie einen Suchbegriff ein, um zu starten.";
|
|
|
|
|
|
|
|
- const needsBranchSelection =
|
|
|
|
|
- isAdminDev &&
|
|
|
|
|
- urlState.scope === SEARCH_SCOPE.MULTI &&
|
|
|
|
|
- Boolean(urlState.q) &&
|
|
|
|
|
- multiCount === 0;
|
|
|
|
|
|
|
+ const needsBranchSelection = needsMultiBranchSelectionHint({
|
|
|
|
|
+ isAdminDev,
|
|
|
|
|
+ urlState,
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<ExplorerPageShell
|
|
<ExplorerPageShell
|