Skip to content

Commit

Permalink
feat: mise en palce de l'outil de recherche
Browse files Browse the repository at this point in the history
  • Loading branch information
pprev94 committed Oct 15, 2024
1 parent 310dabe commit 9642940
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 8 deletions.
33 changes: 33 additions & 0 deletions assets/@types/app_espaceco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,36 @@ export type GetResponse<T> = {

export const arrCommunityListFilters = ["public", "iam_member", "affiliation"];
export type CommunityListFilter = (typeof arrCommunityListFilters)[number];

export type Address = {
country: string;
city: string;
x: number;
y: number;
zipcode: string;
street: string;
classification: number;
kind: string;
fulltext: string;
metropole: boolean;
};

export type Poi = {
country: string;
city: string;
x: number;
y: number;
zipcode: string;
zipcodes: string[];
poiType: string[];
street: string;
classification: number;
kind: string;
fulltext: string;
metropole: boolean;
};

export type SearchResult = {
status: string;
results: (Address | Poi)[];
};
2 changes: 1 addition & 1 deletion assets/@types/espaceco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface CommunityResponseDTO {
email: string | null;
attributes: object[];
default_comment: string | null;
position: string;
position: string | null;
zoom: number;
all_members_can_valid: boolean;
open_without_affiliation: boolean;
Expand Down
4 changes: 2 additions & 2 deletions assets/espaceco/api/community.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ const getAsMember = (queryParams: Record<string, unknown>, signal: AbortSignal)
};

const getCommunity = (communityId: number) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_espaceco_community_get_community", { communityId: communityId });
const url = SymfonyRouting.generate("cartesgouvfr_api_espaceco_community_get_community", { communityId });
return jsonFetch<CommunityResponseDTO>(url);
};

const updateLogo = (communityId: number, formData: FormData) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_espaceco_community_update_logo", { communityId: communityId });
const url = SymfonyRouting.generate("cartesgouvfr_api_espaceco_community_update_logo", { communityId });
return jsonFetch<CommunityResponseDTO>(
url,
{
Expand Down
3 changes: 3 additions & 0 deletions assets/espaceco/pages/communities/ManageCommunity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Tabs from "@codegouvfr/react-dsfr/Tabs";
import Description from "./management/Description";
import { CommunityResponseDTO } from "../../../@types/espaceco";
import { CartesApiException } from "../../../modules/jsonFetch";
import ZoomAndCentering from "./management/ZoomAndCentering";

type ManageCommunityProps = {
communityId: number;
Expand Down Expand Up @@ -69,6 +70,8 @@ const ManageCommunity: FC<ManageCommunityProps> = ({ communityId }) => {
switch (selectedTabId) {
case "tab1":
return <Description community={communityQuery.data} />;
case "tab3":
return <ZoomAndCentering community={communityQuery.data} />;
default:
return <p>`Content of ${selectedTabId}`</p>;
}
Expand Down
2 changes: 1 addition & 1 deletion assets/espaceco/pages/communities/SearchCommunity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const SearchCommunity: FC<SearchCommunityProps> = ({ filter, onChange }) => {
const [search, setSearch] = useDebounceValue("", 500);

const searchQuery = useQuery<CommunityResponseDTO[]>({
queryKey: RQKeys.search(search, filter),
queryKey: RQKeys.searchCommunities(search, filter),
queryFn: ({ signal }) => api.community.searchByName(search, filter, signal),
enabled: search.length > 3,
});
Expand Down
80 changes: 80 additions & 0 deletions assets/espaceco/pages/communities/management/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { fr } from "@codegouvfr/react-dsfr";
import MuiDsfrThemeProvider from "@codegouvfr/react-dsfr/mui";
import Autocomplete from "@mui/material/Autocomplete";
import TextField from "@mui/material/TextField";
import { useQuery } from "@tanstack/react-query";
import { declareComponentKeys } from "i18nifty";
import { FC } from "react";
import { useDebounceValue } from "usehooks-ts";
import { SearchResult } from "../../../../@types/app_espaceco";
import { Translations, useTranslation } from "../../../../i18n/i18n";
import RQKeys from "../../../../modules/espaceco/RQKeys";
import { jsonFetch } from "../../../../modules/jsonFetch";

type SearchProps = {
filter: Record<string, unknown>;
onChange?: (value: string | null) => void;
};

const autocompleteUrl = "https://data.geopf.fr/geocodage/completion";

const Search: FC<SearchProps> = ({ filter, onChange }) => {
const { t } = useTranslation("Search");

const [text, setText] = useDebounceValue("", 500);

const searchQuery = useQuery<SearchResult>({
queryKey: RQKeys.searchAddress(text),
queryFn: ({ signal }) => {
const qParams = new URLSearchParams({ text: text, ...filter }).toString();
return jsonFetch<SearchResult>(`${autocompleteUrl}?${qParams}`, { signal });
},
enabled: text.length >= 3,
staleTime: 10 * 1000,
});
console.log(searchQuery.data);

return (
<div>
<span className={fr.cx("fr-hint-text")}>{t("position_hint")}</span>
<MuiDsfrThemeProvider>
<Autocomplete
loading={searchQuery.isPending}
loadingText={t("loading")}
noOptionsText={t("no_results")}
getOptionLabel={(option) => option.fulltext}
options={searchQuery.data?.results ?? []}
renderInput={(params) => (
<TextField
{...params}
InputProps={{
...params.InputProps,
type: "search",
}}
/>
)}
isOptionEqualToValue={(option, v) => option.fulltext === v.fulltext}
onInputChange={(_, v) => setText(v)}
// onChange={(_, v) => onChange(v)}
/>
</MuiDsfrThemeProvider>
</div>
);
};

export default Search;

// traductions
export const { i18n } = declareComponentKeys<"position_hint" | "no_results" | "loading">()("Search");

export const SearchFrTranslations: Translations<"fr">["Search"] = {
position_hint: "Fixer la position et définissez le niveau de zoom (utilisez votre souris ou la barre de recherche ci-dessous",
no_results: "Aucun résultat",
loading: "Recherche en cours ...",
};

export const SearchEnTranslations: Translations<"en">["Search"] = {
position_hint: "Fix the position and set the zoom level (use your mouse or the search bar below",
no_results: "No results",
loading: "Searching ...",
};
38 changes: 38 additions & 0 deletions assets/espaceco/pages/communities/management/ZoomAndCentering.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FC } from "react";
import { CommunityResponseDTO } from "../../../../@types/espaceco";
import WKT from "ol/format/WKT";
import { fr } from "@codegouvfr/react-dsfr";
import Input from "@codegouvfr/react-dsfr/Input";
import { useTranslation } from "../../../../i18n/i18n";
import Search from "./Search";

type ZoomAndCenteringProps = {
community: CommunityResponseDTO;
};

const ZoomAndCentering: FC<ZoomAndCenteringProps> = ({ community }) => {
let point;
if (community.position) {
const feature = new WKT().readFeature(community.position, {
dataProjection: "EPSG:4326",
});
point = feature.getGeometry().getCoordinates();
}
console.log(point);

return (
<div className={fr.cx("fr-grid-row")}>
<div className={fr.cx("fr-col-5")}>
<Search
filter={{
type: "PositionOfInterest,StreetAddress",
maximumResponses: 10,
}}
/>{" "}
</div>
<div className={fr.cx("fr-col-7")}></div>
</div>
);
};

export default ZoomAndCentering;
3 changes: 2 additions & 1 deletion assets/i18n/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export type ComponentKey =
| typeof import("../entrepot/pages/service/wms-vector/UploadStyleFile").i18n
| typeof import("../espaceco/pages/communities/CommunityListTr").i18n
| typeof import("../espaceco/pages/communities/ManageCommunityTr").i18n
| typeof import("../espaceco/pages/communities/management/validationTr").i18n;
| typeof import("../espaceco/pages/communities/management/validationTr").i18n
| typeof import("../espaceco/pages/communities/management/Search").i18n;

export type Translations<L extends Language> = GenericTranslations<ComponentKey, Language, typeof fallbackLanguage, L>;
export type LocalizedString = Parameters<typeof resolveLocalizedString>[0];
Expand Down
3 changes: 3 additions & 0 deletions assets/i18n/languages/en.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { PermissionsEnTranslations } from "../../entrepot/pages/users/permission
import { CommunityListEnTranslations } from "../../espaceco/pages/communities/CommunityListTr";
import { ManageCommunityEnTranslations } from "../../espaceco/pages/communities/ManageCommunityTr";
import { ManageCommunityValidationsEnTranslations } from "../../espaceco/pages/communities/management/validationTr";
import { SearchEnTranslations } from "../../espaceco/pages/communities/management/Search";
import { TMSStyleFilesManagerEnTranslations } from "../../modules/Style/TMSStyleFilesManager";
import { contactEnTranslations } from "../../pages/assistance/contact/Contact";
import { mapboxStyleValidationEnTranslations } from "../../validations/MapboxStyleValidator";
Expand All @@ -35,6 +36,7 @@ import { BreadcrumbEnTranslations } from "../Breadcrumb";
import { commonEnTranslations } from "../Common";
import { RightsEnTranslations } from "../Rights";
import { StyleEnTranslations } from "../Style";

import type { Translations } from "../i18n";

export const translations: Translations<"en"> = {
Expand Down Expand Up @@ -75,4 +77,5 @@ export const translations: Translations<"en"> = {
CommunityList: CommunityListEnTranslations,
ManageCommunity: ManageCommunityEnTranslations,
ManageCommunityValidations: ManageCommunityValidationsEnTranslations,
Search: SearchEnTranslations,
};
3 changes: 3 additions & 0 deletions assets/i18n/languages/fr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { PermissionsFrTranslations } from "../../entrepot/pages/users/permission
import { CommunityListFrTranslations } from "../../espaceco/pages/communities/CommunityListTr";
import { ManageCommunityFrTranslations } from "../../espaceco/pages/communities/ManageCommunityTr";
import { ManageCommunityValidationsFrTranslations } from "../../espaceco/pages/communities/management/validationTr";
import { SearchEnTranslations, SearchFrTranslations } from "../../espaceco/pages/communities/management/Search";
import { TMSStyleFilesManagerFrTranslations } from "../../modules/Style/TMSStyleFilesManager";
import { contactFrTranslations } from "../../pages/assistance/contact/Contact";
import { mapboxStyleValidationFrTranslations } from "../../validations/MapboxStyleValidator";
Expand All @@ -35,6 +36,7 @@ import { BreadcrumbFrTranslations } from "../Breadcrumb";
import { commonFrTranslations } from "../Common";
import { RightsFrTranslations } from "../Rights";
import { StyleFrTranslations } from "../Style";

import type { Translations } from "../i18n";

export const translations: Translations<"fr"> = {
Expand Down Expand Up @@ -75,4 +77,5 @@ export const translations: Translations<"fr"> = {
CommunityList: CommunityListFrTranslations,
ManageCommunity: ManageCommunityFrTranslations,
ManageCommunityValidations: ManageCommunityValidationsFrTranslations,
Search: SearchFrTranslations,
};
5 changes: 3 additions & 2 deletions assets/modules/espaceco/RQKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { CommunityListFilter } from "../../@types/app_espaceco";
const RQKeys = {
community: (communityId: number): string[] => ["community", communityId.toString()],
community_list: (page: number, limit: number): string[] => ["communities", page.toString(), limit.toString()],
search: (search: string, filter: CommunityListFilter): string[] => {
return ["search", "community", filter, search];
searchCommunities: (search: string, filter: CommunityListFilter): string[] => {
return ["searchCommunities", filter, search];
},
communities_as_member: (pending: boolean, page: number, limit: number): string[] => [
"communities_as_member",
new Boolean(pending).toString(),
page.toString(),
limit.toString(),
],
searchAddress: (search: string): string[] => ["searchAddress", search],
};

export default RQKeys;
2 changes: 1 addition & 1 deletion assets/validations/SldStyleValidationErrorsTr.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { declareComponentKeys } from "i18nifty/declareComponentKeys";
import { declareComponentKeys } from "i18nifty";
import { Translations } from "../i18n/i18n";

export const { i18n } = declareComponentKeys<
Expand Down

0 comments on commit 9642940

Please sign in to comment.