@swan-io/shared-business 3.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/components/AddressFormPart.js +5 -3
- package/src/components/BeneficiaryForm.d.ts +1 -1
- package/src/components/BeneficiaryForm.js +7 -5
- package/src/components/{GMapAddressSearchInput.d.ts → PlacekitAddressSearchInput.d.ts} +8 -4
- package/src/components/PlacekitAddressSearchInput.js +33 -0
- package/src/components/PlacekitCityInput.d.ts +19 -0
- package/src/components/PlacekitCityInput.js +34 -0
- package/src/constants/countries.d.ts +3 -3
- package/src/hooks/usePlacekit.d.ts +4 -0
- package/src/hooks/usePlacekit.js +12 -0
- package/src/components/GMapAddressSearchInput.js +0 -50
- package/src/components/GMapCityInput.d.ts +0 -16
- package/src/components/GMapCityInput.js +0 -48
- package/src/hooks/useGoogleMapSDK.d.ts +0 -16
- package/src/hooks/useGoogleMapSDK.js +0 -63
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swan-io/shared-business",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=18.0.0",
|
|
6
6
|
"yarn": "^1.22.0"
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@formatjs/intl": "^2.9.6",
|
|
33
33
|
"@googlemaps/js-api-loader": "1.16.2",
|
|
34
|
+
"@placekit/client-js": "^2.0.0",
|
|
34
35
|
"@swan-io/boxed": "^1.2.0",
|
|
35
36
|
"dayjs": "^1.11.10",
|
|
36
37
|
"react": "^18.2.0",
|
|
@@ -6,7 +6,7 @@ import { Space } from "@swan-io/lake/src/components/Space";
|
|
|
6
6
|
import { useBoolean } from "@swan-io/lake/src/hooks/useBoolean";
|
|
7
7
|
import { useCallback, useEffect } from "react";
|
|
8
8
|
import { locale, t } from "../utils/i18n";
|
|
9
|
-
import {
|
|
9
|
+
import { PlacekitAddressSearchInput } from "./PlacekitAddressSearchInput";
|
|
10
10
|
export const AddressFormPart = ({ initialAddress, initialCity, initialPostalCode, country, label, optionalLabel, placeholder, Field, setFieldValue, listenFields, isLarge, apiKey, }) => {
|
|
11
11
|
const [manualModeEnabled, setManualMode] = useBoolean(initialAddress !== "" || initialCity !== "" || initialPostalCode !== "");
|
|
12
12
|
useEffect(() => {
|
|
@@ -19,8 +19,10 @@ export const AddressFormPart = ({ initialAddress, initialCity, initialPostalCode
|
|
|
19
19
|
const onSuggestion = useCallback((place) => {
|
|
20
20
|
setFieldValue("address", place.completeAddress);
|
|
21
21
|
setFieldValue("city", place.city);
|
|
22
|
-
|
|
22
|
+
if (place.postalCode != null) {
|
|
23
|
+
setFieldValue("postalCode", place.postalCode);
|
|
24
|
+
}
|
|
23
25
|
setManualMode.on();
|
|
24
26
|
}, [setManualMode, setFieldValue]);
|
|
25
|
-
return (_jsxs(_Fragment, { children: [_jsx(Field, { name: "address", children: ({ ref, value, onChange, error }) => (_jsx(LakeLabel, { label: label ?? t("addressFormPart.addressLabel"), optionalLabel: optionalLabel, render: id => (_jsx(
|
|
27
|
+
return (_jsxs(_Fragment, { children: [_jsx(Field, { name: "address", children: ({ ref, value, onChange, error }) => (_jsx(LakeLabel, { label: label ?? t("addressFormPart.addressLabel"), optionalLabel: optionalLabel, render: id => (_jsx(PlacekitAddressSearchInput, { inputRef: ref, apiKey: apiKey, emptyResultText: t("common.noResult"), placeholder: placeholder ?? t("addressFormPart.placeholder"), language: locale.language, id: id, country: country, value: value, error: error, onValueChange: onChange, onSuggestion: onSuggestion })), actions: !manualModeEnabled && isLarge ? (_jsx(LakeButton, { mode: "secondary", size: "small", onPress: setManualMode.on, children: t("addressFormPart.setManual") })) : null })) }), !manualModeEnabled && !isLarge ? (_jsx(LakeButton, { mode: "secondary", size: "small", onPress: setManualMode.on, children: t("addressFormPart.setManual") })) : null, manualModeEnabled ? (_jsxs(_Fragment, { children: [_jsx(Space, { height: 12 }), _jsx(Field, { name: "city", children: ({ ref, value, valid, error, onChange }) => (_jsx(LakeLabel, { label: t("addressFormPart.cityLabel"), render: id => (_jsx(LakeTextInput, { ref: ref, id: id, value: value, valid: valid, error: error, onChangeText: onChange })) })) }), _jsx(Space, { height: 12 }), _jsx(Field, { name: "postalCode", children: ({ ref, value, valid, error, onChange }) => (_jsx(LakeLabel, { label: t("addressFormPart.postCodeLabel"), render: id => (_jsx(LakeTextInput, { ref: ref, id: id, value: value, valid: valid, error: error, onChangeText: onChange })) })) })] })) : null] }));
|
|
26
28
|
};
|
|
@@ -25,7 +25,7 @@ type Props = {
|
|
|
25
25
|
initialState?: EditorState;
|
|
26
26
|
accountCountry: AccountCountry;
|
|
27
27
|
step: BeneficiaryFormStep;
|
|
28
|
-
|
|
28
|
+
placekitApiKey: string;
|
|
29
29
|
onStepChange: (step: BeneficiaryFormStep) => void;
|
|
30
30
|
onSave: (editorState: EditorState) => void | Promise<void>;
|
|
31
31
|
onClose: () => void;
|
|
@@ -23,7 +23,7 @@ import { locale, rifmDateProps, t } from "../utils/i18n";
|
|
|
23
23
|
import { validateBooleanRequired, validateIndividualTaxNumber, validateNullableRequired, validateRequired, } from "../utils/validation";
|
|
24
24
|
import { AddressFormPart } from "./AddressFormPart";
|
|
25
25
|
import { CountryPicker } from "./CountryPicker";
|
|
26
|
-
import {
|
|
26
|
+
import { PlacekitCityInput } from "./PlacekitCityInput";
|
|
27
27
|
import { TaxIdentificationNumberInput } from "./TaxIdentificationNumberInput";
|
|
28
28
|
const styles = StyleSheet.create({
|
|
29
29
|
inputContainer: {
|
|
@@ -154,7 +154,7 @@ const requiredStepFields = [
|
|
|
154
154
|
"birthCityPostalCode",
|
|
155
155
|
"type",
|
|
156
156
|
];
|
|
157
|
-
export const BeneficiaryForm = forwardRef(({ initialState, accountCountry, step,
|
|
157
|
+
export const BeneficiaryForm = forwardRef(({ initialState, accountCountry, step, placekitApiKey, onStepChange, onClose, onSave, onCityLoadError, }, ref) => {
|
|
158
158
|
const [reference] = useState(() => initialState?.reference ?? uuid());
|
|
159
159
|
const isAddressRequired = match(accountCountry)
|
|
160
160
|
.with("DEU", "ESP", () => true)
|
|
@@ -329,15 +329,17 @@ export const BeneficiaryForm = forwardRef(({ initialState, accountCountry, step,
|
|
|
329
329
|
};
|
|
330
330
|
});
|
|
331
331
|
return (_jsx(ResponsiveContainer, { breakpoint: breakpoints.tiny, children: ({ small, large }) => (_jsxs(_Fragment, { children: [match(step)
|
|
332
|
-
.with("common", () => (_jsxs(View, { role: "form", children: [_jsxs(Box, { direction: small ? "column" : "row", children: [_jsx(Field, { name: "firstName", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.firstName"), style: styles.inputContainer, render: id => (_jsx(LakeTextInput, { error: error, placeholder: t("beneficiaryForm.beneficiary.firstNamePlaceholder"), id: id, value: value, onChangeText: onChange })) })) }), _jsx(Space, { width: 12 }), _jsx(Field, { name: "lastName", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.lastName"), style: styles.inputContainer, render: id => (_jsx(LakeTextInput, { error: error, placeholder: t("beneficiaryForm.beneficiary.lastNamePlaceholder"), id: id, value: value, onChangeText: onChange })) })) })] }), _jsxs(Box, { direction: small ? "column" : "row", children: [_jsx(Field, { name: "birthDate", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthDate"), optionalLabel: isBirthInfoRequired ? undefined : t("common.optional"), style: styles.inputContainer, render: id => (_jsx(Rifm, { value: value ?? "", onChange: onChange, ...rifmDateProps, children: ({ value, onChange }) => (_jsx(LakeTextInput, { error: error, placeholder: locale.datePlaceholder, id: id, value: value, onChange: onChange })) })) })) }), _jsx(Space, { width: 12 }), _jsx(Field, { name: "birthCountryCode", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthCountry"), style: styles.inputContainer, render: id => (_jsx(CountryPicker, { id: id, error: error, value: value, placeholder: t("beneficiaryForm.beneficiary.birthCountryPlaceholder"), countries: allCountries, onValueChange: onChange })) })) })] }), _jsx(Box, { direction: small ? "column" : "row", children: _jsx(FieldsListener, { names: ["birthCountryCode"], children: ({ birthCountryCode }) => (_jsxs(_Fragment, { children: [_jsx(Field, { name: "birthCity", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthCity"), optionalLabel: isBirthInfoRequired ? undefined : t("common.optional"), style: styles.inputContainer, render: id => (_jsx(
|
|
332
|
+
.with("common", () => (_jsxs(View, { role: "form", children: [_jsxs(Box, { direction: small ? "column" : "row", children: [_jsx(Field, { name: "firstName", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.firstName"), style: styles.inputContainer, render: id => (_jsx(LakeTextInput, { error: error, placeholder: t("beneficiaryForm.beneficiary.firstNamePlaceholder"), id: id, value: value, onChangeText: onChange })) })) }), _jsx(Space, { width: 12 }), _jsx(Field, { name: "lastName", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.lastName"), style: styles.inputContainer, render: id => (_jsx(LakeTextInput, { error: error, placeholder: t("beneficiaryForm.beneficiary.lastNamePlaceholder"), id: id, value: value, onChangeText: onChange })) })) })] }), _jsxs(Box, { direction: small ? "column" : "row", children: [_jsx(Field, { name: "birthDate", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthDate"), optionalLabel: isBirthInfoRequired ? undefined : t("common.optional"), style: styles.inputContainer, render: id => (_jsx(Rifm, { value: value ?? "", onChange: onChange, ...rifmDateProps, children: ({ value, onChange }) => (_jsx(LakeTextInput, { error: error, placeholder: locale.datePlaceholder, id: id, value: value, onChange: onChange })) })) })) }), _jsx(Space, { width: 12 }), _jsx(Field, { name: "birthCountryCode", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthCountry"), style: styles.inputContainer, render: id => (_jsx(CountryPicker, { id: id, error: error, value: value, placeholder: t("beneficiaryForm.beneficiary.birthCountryPlaceholder"), countries: allCountries, onValueChange: onChange })) })) })] }), _jsx(Box, { direction: small ? "column" : "row", children: _jsx(FieldsListener, { names: ["birthCountryCode"], children: ({ birthCountryCode }) => (_jsxs(_Fragment, { children: [_jsx(Field, { name: "birthCity", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthCity"), optionalLabel: isBirthInfoRequired ? undefined : t("common.optional"), style: styles.inputContainer, render: id => (_jsx(PlacekitCityInput, { id: id, apiKey: placekitApiKey, error: error, country: birthCountryCode.value, value: value ?? "", onValueChange: onChange, placeholder: birthCountryCode.value == null
|
|
333
333
|
? t("beneficiaryForm.beneficiary.fillBirthCountry")
|
|
334
334
|
: t("beneficiaryForm.beneficiary.birthCityPlaceholder"), onSuggestion: place => {
|
|
335
335
|
onChange(place.city);
|
|
336
|
-
|
|
336
|
+
if (place.postalCode != null) {
|
|
337
|
+
setFieldValue("birthCityPostalCode", place.postalCode);
|
|
338
|
+
}
|
|
337
339
|
}, onLoadError: onCityLoadError })) })) }), _jsx(Space, { width: 12 }), _jsx(Field, { name: "birthCityPostalCode", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.birthPostalCode"), optionalLabel: isBirthInfoRequired ? undefined : t("common.optional"), style: styles.inputContainer, render: id => (_jsx(LakeTextInput, { error: error, placeholder: birthCountryCode.value == null
|
|
338
340
|
? t("beneficiaryForm.beneficiary.fillBirthCountry")
|
|
339
341
|
: t("beneficiaryForm.beneficiary.birthPostalCodePlaceholder"), id: id, disabled: birthCountryCode.value === undefined, value: value, onChangeText: onChange })) })) })] })) }) }), _jsx(Field, { name: "type", children: ({ value, onChange }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.type"), type: "radioGroup", render: () => (_jsx(RadioGroup, { direction: "row", value: value, onValueChange: onChange, items: beneficiaryTypes })) })) }), _jsx(FieldsListener, { names: ["type"], children: ({ type }) => type.value === "HasCapital" ? (_jsxs(_Fragment, { children: [_jsx(Field, { name: "totalCapitalPercentage", children: ({ value, onChange, error }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.totalCapitalPercentage"), render: id => (_jsx(LakeTextInput, { error: error, unit: "%", inputMode: "decimal", "aria-valuemin": 0, "aria-valuemax": 100, id: id, value: value, onChangeText: onChange })) })) }), _jsx(Space, { height: 12 }), _jsx(Field, { name: "capitalType", children: ({ value, error, onChange }) => (_jsx(CapitalTypeCheckboxes, { value: value ?? "none", error: error, onChange: onChange })) })] })) : null })] })))
|
|
340
|
-
.with("address", () => (_jsxs(View, { role: "form", children: [_jsx(Field, { name: "country", children: ({ value, onChange }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.country"), render: id => (_jsx(CountryPicker, { id: id, value: value, countries: allCountries, onValueChange: onChange })) })) }), _jsx(Space, { height: 12 }), _jsx(FieldsListener, { names: ["country"], children: ({ country }) => (_jsxs(_Fragment, { children: [_jsx(AddressFormPart, { apiKey:
|
|
342
|
+
.with("address", () => (_jsxs(View, { role: "form", children: [_jsx(Field, { name: "country", children: ({ value, onChange }) => (_jsx(LakeLabel, { label: t("beneficiaryForm.beneficiary.country"), render: id => (_jsx(CountryPicker, { id: id, value: value, countries: allCountries, onValueChange: onChange })) })) }), _jsx(Space, { height: 12 }), _jsx(FieldsListener, { names: ["country"], children: ({ country }) => (_jsxs(_Fragment, { children: [_jsx(AddressFormPart, { apiKey: placekitApiKey, initialAddress: initialAddress.current.residencyAddressLine1 ?? "", initialCity: initialAddress.current.residencyAddressCity ?? "", initialPostalCode: initialAddress.current.residencyAddressPostalCode ?? "", country: country?.value ?? accountCountry, label: t("beneficiaryForm.beneficiary.address"), Field: Field, setFieldValue: setFieldValue, listenFields: listenFields, isLarge: large }), ((accountCountry === "DEU" && country?.value === "DEU") ||
|
|
341
343
|
accountCountry === "ESP") && (_jsxs(_Fragment, { children: [_jsx(Space, { height: 12 }), _jsx(Field, { name: "taxIdentificationNumber", children: ({ value, error, valid, onChange }) => (_jsx(TaxIdentificationNumberInput, { value: value ?? "", error: error, valid: valid, onChange: onChange, accountCountry: accountCountry, isCompany: false,
|
|
342
344
|
// is mandatory for German accounts with UBO living in Germany
|
|
343
345
|
required: accountCountry === "DEU" && country?.value === "DEU" })) })] }))] })) })] })))
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { CountryCCA3 } from "@swan-io/shared-business/src/constants/countries";
|
|
2
2
|
import { MutableRefObject } from "react";
|
|
3
3
|
import { StyleProp, ViewStyle } from "react-native";
|
|
4
|
-
|
|
4
|
+
export type AddressDetail = {
|
|
5
|
+
completeAddress: string;
|
|
6
|
+
city: string;
|
|
7
|
+
postalCode?: string;
|
|
8
|
+
};
|
|
5
9
|
type Props = {
|
|
6
10
|
inputRef?: MutableRefObject<unknown>;
|
|
7
11
|
id?: string;
|
|
8
12
|
country: CountryCCA3;
|
|
9
13
|
disabled?: boolean;
|
|
10
14
|
error?: string;
|
|
11
|
-
onSuggestion?: (suggestion:
|
|
15
|
+
onSuggestion?: (suggestion: AddressDetail) => void;
|
|
12
16
|
onValueChange: (value: string) => void;
|
|
13
17
|
style?: StyleProp<ViewStyle>;
|
|
14
18
|
value?: string;
|
|
@@ -16,7 +20,7 @@ type Props = {
|
|
|
16
20
|
placeholder: string;
|
|
17
21
|
shouldDisplaySuggestions?: boolean;
|
|
18
22
|
emptyResultText: string;
|
|
19
|
-
apiKey
|
|
23
|
+
apiKey?: string;
|
|
20
24
|
};
|
|
21
|
-
export declare const
|
|
25
|
+
export declare const PlacekitAddressSearchInput: ({ inputRef, id, country, disabled, error, value, onValueChange, onSuggestion, language, placeholder, shouldDisplaySuggestions, emptyResultText, apiKey, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
22
26
|
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Array, Future, Option, Result } from "@swan-io/boxed";
|
|
3
|
+
import { AutocompleteSearchInput } from "@swan-io/lake/src/components/AutocompleteSearchInput";
|
|
4
|
+
import { countriesWithMultipleCCA3, getCCA2forCCA3, } from "@swan-io/shared-business/src/constants/countries";
|
|
5
|
+
import { useCallback } from "react";
|
|
6
|
+
import { usePlacekit } from "../hooks/usePlacekit";
|
|
7
|
+
export const PlacekitAddressSearchInput = ({ inputRef, id, country, disabled, error, value, onValueChange, onSuggestion, language, placeholder, shouldDisplaySuggestions = true, emptyResultText, apiKey, }) => {
|
|
8
|
+
const placekit = usePlacekit({ apiKey });
|
|
9
|
+
const loadSuggestions = useCallback((value) => {
|
|
10
|
+
if (placekit != null) {
|
|
11
|
+
const countries = Array.filterMap(countriesWithMultipleCCA3[country] ?? [country], cca3 => Option.fromNullable(getCCA2forCCA3(cca3)));
|
|
12
|
+
const cca2Countries = countries.length === 0 ? Option.None() : Option.Some(countries);
|
|
13
|
+
return Future.fromPromise(placekit.search(value, {
|
|
14
|
+
types: ["street"],
|
|
15
|
+
language,
|
|
16
|
+
countries: cca2Countries.toUndefined(),
|
|
17
|
+
})).mapOk(({ results }) => results.map(result => ({
|
|
18
|
+
title: result.name,
|
|
19
|
+
subtitle: result.city,
|
|
20
|
+
value: result,
|
|
21
|
+
})), true);
|
|
22
|
+
}
|
|
23
|
+
return Future.value(Result.Ok([]));
|
|
24
|
+
}, [placekit, country, language]);
|
|
25
|
+
const onSuggestionSelected = useCallback((suggestion) => {
|
|
26
|
+
onSuggestion?.({
|
|
27
|
+
completeAddress: suggestion.value.name,
|
|
28
|
+
postalCode: suggestion.value.zipcode[0],
|
|
29
|
+
city: suggestion.value.city,
|
|
30
|
+
});
|
|
31
|
+
}, [onSuggestion]);
|
|
32
|
+
return (_jsx(AutocompleteSearchInput, { inputRef: inputRef, value: value, onValueChange: onValueChange, disabled: disabled, id: id, placeholder: placeholder, error: error, emptyResultText: emptyResultText, shouldDisplaySuggestions: shouldDisplaySuggestions, loadSuggestions: placekit != null ? loadSuggestions : undefined, onSuggestion: onSuggestionSelected }));
|
|
33
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CountryCCA3 } from "../constants/countries";
|
|
2
|
+
export type CityDetail = {
|
|
3
|
+
city: string;
|
|
4
|
+
postalCode?: string;
|
|
5
|
+
};
|
|
6
|
+
type Props = {
|
|
7
|
+
value: string;
|
|
8
|
+
onValueChange: (value: string) => void;
|
|
9
|
+
country?: CountryCCA3;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
id?: string;
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
onSuggestion?: (place: CityDetail) => void;
|
|
15
|
+
onLoadError: (error: unknown) => void;
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const PlacekitCityInput: ({ value, onValueChange, country, disabled, placeholder, id, error, onSuggestion, onLoadError, apiKey, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Array, Future, Option, Result } from "@swan-io/boxed";
|
|
3
|
+
import { AutocompleteSearchInput } from "@swan-io/lake/src/components/AutocompleteSearchInput";
|
|
4
|
+
import { useCallback } from "react";
|
|
5
|
+
import { countriesWithMultipleCCA3, getCCA2forCCA3 } from "../constants/countries";
|
|
6
|
+
import { usePlacekit } from "../hooks/usePlacekit";
|
|
7
|
+
import { t } from "../utils/i18n";
|
|
8
|
+
export const PlacekitCityInput = ({ value, onValueChange, country, disabled, placeholder, id, error, onSuggestion, onLoadError, apiKey, }) => {
|
|
9
|
+
const placekit = usePlacekit({ apiKey });
|
|
10
|
+
const loadSuggestions = useCallback((value) => {
|
|
11
|
+
if (placekit != null) {
|
|
12
|
+
const countries = Option.fromNullable(country)
|
|
13
|
+
.map(country => countriesWithMultipleCCA3[country] ?? [country])
|
|
14
|
+
.map(cca3Codes => Array.filterMap(cca3Codes, cca3 => Option.fromNullable(getCCA2forCCA3(cca3))))
|
|
15
|
+
.flatMap(array => (array.length === 0 ? Option.None() : Option.Some(array)));
|
|
16
|
+
return Future.fromPromise(placekit.search(value, {
|
|
17
|
+
types: ["city"],
|
|
18
|
+
countries: countries.toUndefined(),
|
|
19
|
+
})).mapOk(({ results }) => results.map(result => ({
|
|
20
|
+
title: result.name,
|
|
21
|
+
subtitle: result.city,
|
|
22
|
+
value: result,
|
|
23
|
+
})), true);
|
|
24
|
+
}
|
|
25
|
+
return Future.value(Result.Ok([]));
|
|
26
|
+
}, [placekit, country]);
|
|
27
|
+
const onSuggestionSelected = useCallback((suggestion) => {
|
|
28
|
+
onSuggestion?.({
|
|
29
|
+
city: suggestion.value.city,
|
|
30
|
+
postalCode: suggestion.value.zipcode[0],
|
|
31
|
+
});
|
|
32
|
+
}, [onSuggestion]);
|
|
33
|
+
return (_jsx(AutocompleteSearchInput, { value: value, onValueChange: onValueChange, disabled: disabled, id: id, placeholder: placeholder, error: error, emptyResultText: t("common.noResult"), loadSuggestions: placekit != null ? loadSuggestions : undefined, onSuggestion: onSuggestionSelected, onLoadError: onLoadError }));
|
|
34
|
+
};
|
|
@@ -1979,8 +1979,8 @@ export declare const countries: ({
|
|
|
1979
1979
|
export type Country = (typeof countries)[number];
|
|
1980
1980
|
export type CountryCCA2 = (typeof countries)[number]["cca2"];
|
|
1981
1981
|
export type CountryCCA3 = (typeof countries)[number]["cca3"];
|
|
1982
|
-
export declare const getCCA2forCCA3: (cca3: CountryCCA3) =>
|
|
1983
|
-
export declare const getCCA3forCCA2: (cca2: CountryCCA2) =>
|
|
1982
|
+
export declare const getCCA2forCCA3: (cca3: CountryCCA3) => CountryCCA2 | undefined;
|
|
1983
|
+
export declare const getCCA3forCCA2: (cca2: CountryCCA2) => CountryCCA3 | undefined;
|
|
1984
1984
|
export declare const companyWithUboCountries: readonly ["BEL", "DEU", "FRA", "ITA", "LTU", "LUX", "NLD"];
|
|
1985
1985
|
export type CompanyWithUboCountryCCA3 = (typeof companyWithUboCountries)[number];
|
|
1986
1986
|
export declare const allCountries: ("FRA" | "ALA" | "ASM" | "AND" | "AGO" | "AIA" | "ATA" | "ATG" | "ARG" | "ABW" | "AUS" | "AZE" | "BHS" | "BGD" | "BRB" | "BEL" | "BLZ" | "BEN" | "BMU" | "BOL" | "BES" | "BIH" | "BWA" | "BVT" | "BRA" | "VGB" | "BFA" | "BDI" | "CPV" | "CMR" | "CAN" | "CYM" | "CZE" | "CHL" | "CXR" | "CCK" | "COL" | "COK" | "CRI" | "CIV" | "CUB" | "CUW" | "DNK" | "DEU" | "DJI" | "DMA" | "ECU" | "EST" | "IRL" | "SLV" | "ESP" | "FLK" | "FJI" | "FRO" | "GAB" | "GMB" | "GHA" | "GIB" | "GRD" | "GLP" | "GUM" | "GTM" | "GGY" | "GNB" | "GNQ" | "GIN" | "GUY" | "GUF" | "HTI" | "HMD" | "HND" | "HRV" | "IDN" | "ISL" | "IMN" | "ITA" | "JAM" | "JEY" | "GRL" | "KHM" | "KAZ" | "KEN" | "KIR" | "CAF" | "COM" | "REU" | "LVA" | "LSO" | "LBR" | "LIE" | "LTU" | "LUX" | "MDG" | "HUN" | "MHL" | "MWI" | "MYS" | "MDV" | "MLI" | "MLT" | "MTQ" | "MUS" | "MYT" | "MEX" | "FSM" | "MOZ" | "MDA" | "MCO" | "MSR" | "NAM" | "NLD" | "BRN" | "NZL" | "NIC" | "NER" | "NGA" | "NIU" | "NFK" | "NOR" | "MNP" | "NCL" | "AUT" | "UZB" | "PAK" | "PLW" | "PAN" | "PNG" | "PRY" | "PER" | "PHL" | "PCN" | "POL" | "PYF" | "PRT" | "PRI" | "DOM" | "UNK" | "COD" | "COG" | "ROU" | "RWA" | "KNA" | "LCA" | "VCT" | "BLM" | "MAF" | "SPM" | "WSM" | "SMR" | "STP" | "CHE" | "SEN" | "SYC" | "ALB" | "SLE" | "SGP" | "SVN" | "SVK" | "SLB" | "SOM" | "ZAF" | "SGS" | "SSD" | "LKA" | "FIN" | "SUR" | "SWE" | "SWZ" | "TZA" | "TCD" | "ATF" | "TLS" | "TGO" | "TON" | "TTO" | "TUR" | "TKM" | "TCA" | "TUV" | "UGA" | "GBR" | "USA" | "UMI" | "VIR" | "URY" | "VUT" | "VAT" | "VEN" | "VNM" | "WLF" | "ZMB" | "ZWE" | "BTN" | "GRC" | "CYP" | "BLR" | "BGR" | "KGZ" | "MKD" | "MNG" | "RUS" | "SRB" | "TJK" | "UKR" | "MNE" | "ARM" | "ISR" | "AFG" | "JOR" | "DZA" | "SDN" | "ESH" | "IRQ" | "SAU" | "KWT" | "MAR" | "YEM" | "IRN" | "TUN" | "ARE" | "SYR" | "OMN" | "PSE" | "QAT" | "LBN" | "EGY" | "MRT" | "NPL" | "IND" | "THA" | "LAO" | "MMR" | "GEO" | "ETH" | "ERI" | "BHR" | "LBY" | "CHN" | "JPN" | "MAC" | "TWN" | "HKG" | "KOR" | "PRK")[];
|
|
@@ -1988,7 +1988,7 @@ export declare const individualCountries: ("FRA" | "BEL" | "CZE" | "DNK" | "DEU"
|
|
|
1988
1988
|
export type IndividualCountryCCA3 = (typeof individualCountries)[number];
|
|
1989
1989
|
export declare const companyCountries: ("FRA" | "BEL" | "CZE" | "DNK" | "DEU" | "EST" | "IRL" | "ESP" | "HRV" | "ISL" | "ITA" | "LVA" | "LIE" | "LTU" | "LUX" | "HUN" | "MLT" | "MCO" | "NLD" | "NOR" | "AUT" | "POL" | "PRT" | "ROU" | "SVN" | "SVK" | "FIN" | "SWE" | "GRC" | "CYP" | "BGR")[];
|
|
1990
1990
|
export type CompanyCountryCCA3 = (typeof companyCountries)[number];
|
|
1991
|
-
export declare const countriesWithMultipleCCA3: Partial<Record<CountryCCA3,
|
|
1991
|
+
export declare const countriesWithMultipleCCA3: Partial<Record<CountryCCA3, CountryCCA3[]>>;
|
|
1992
1992
|
export declare const isCountryCCA3: (value: unknown) => value is "FRA" | "ALA" | "ASM" | "AND" | "AGO" | "AIA" | "ATA" | "ATG" | "ARG" | "ABW" | "AUS" | "AZE" | "BHS" | "BGD" | "BRB" | "BEL" | "BLZ" | "BEN" | "BMU" | "BOL" | "BES" | "BIH" | "BWA" | "BVT" | "BRA" | "VGB" | "BFA" | "BDI" | "CPV" | "CMR" | "CAN" | "CYM" | "CZE" | "CHL" | "CXR" | "CCK" | "COL" | "COK" | "CRI" | "CIV" | "CUB" | "CUW" | "DNK" | "DEU" | "DJI" | "DMA" | "ECU" | "EST" | "IRL" | "SLV" | "ESP" | "FLK" | "FJI" | "FRO" | "GAB" | "GMB" | "GHA" | "GIB" | "GRD" | "GLP" | "GUM" | "GTM" | "GGY" | "GNB" | "GNQ" | "GIN" | "GUY" | "GUF" | "HTI" | "HMD" | "HND" | "HRV" | "IDN" | "ISL" | "IMN" | "ITA" | "JAM" | "JEY" | "GRL" | "KHM" | "KAZ" | "KEN" | "KIR" | "CAF" | "COM" | "REU" | "LVA" | "LSO" | "LBR" | "LIE" | "LTU" | "LUX" | "MDG" | "HUN" | "MHL" | "MWI" | "MYS" | "MDV" | "MLI" | "MLT" | "MTQ" | "MUS" | "MYT" | "MEX" | "FSM" | "MOZ" | "MDA" | "MCO" | "MSR" | "NAM" | "NLD" | "BRN" | "NZL" | "NIC" | "NER" | "NGA" | "NIU" | "NFK" | "NOR" | "MNP" | "NCL" | "AUT" | "UZB" | "PAK" | "PLW" | "PAN" | "PNG" | "PRY" | "PER" | "PHL" | "PCN" | "POL" | "PYF" | "PRT" | "PRI" | "DOM" | "UNK" | "COD" | "COG" | "ROU" | "RWA" | "KNA" | "LCA" | "VCT" | "BLM" | "MAF" | "SPM" | "WSM" | "SMR" | "STP" | "CHE" | "SEN" | "SYC" | "ALB" | "SLE" | "SGP" | "SVN" | "SVK" | "SLB" | "SOM" | "ZAF" | "SGS" | "SSD" | "LKA" | "FIN" | "SUR" | "SWE" | "SWZ" | "TZA" | "TCD" | "ATF" | "TLS" | "TGO" | "TON" | "TTO" | "TUR" | "TKM" | "TCA" | "TUV" | "UGA" | "GBR" | "USA" | "UMI" | "VIR" | "URY" | "VUT" | "VAT" | "VEN" | "VNM" | "WLF" | "ZMB" | "ZWE" | "BTN" | "GRC" | "CYP" | "BLR" | "BGR" | "KGZ" | "MKD" | "MNG" | "RUS" | "SRB" | "TJK" | "UKR" | "MNE" | "ARM" | "ISR" | "AFG" | "JOR" | "DZA" | "SDN" | "ESH" | "IRQ" | "SAU" | "KWT" | "MAR" | "YEM" | "IRN" | "TUN" | "ARE" | "SYR" | "OMN" | "PSE" | "QAT" | "LBN" | "EGY" | "MRT" | "NPL" | "IND" | "THA" | "LAO" | "MMR" | "GEO" | "ETH" | "ERI" | "BHR" | "LBY" | "CHN" | "JPN" | "MAC" | "TWN" | "HKG" | "KOR" | "PRK";
|
|
1993
1993
|
export declare const isCountryCCA2: (value: unknown) => value is "FR" | "AX" | "AS" | "AD" | "AO" | "AI" | "AQ" | "AG" | "AR" | "AW" | "AU" | "AZ" | "BS" | "BD" | "BB" | "BE" | "BZ" | "BJ" | "BM" | "BO" | "BQ" | "BA" | "BW" | "BV" | "BR" | "VG" | "BF" | "BI" | "CV" | "CM" | "CA" | "KY" | "CZ" | "CL" | "CX" | "CC" | "CO" | "CK" | "CR" | "CI" | "CU" | "CW" | "DK" | "DE" | "DJ" | "DM" | "EC" | "EE" | "IE" | "SV" | "ES" | "FK" | "FJ" | "FO" | "GA" | "GM" | "GH" | "GI" | "GD" | "GP" | "GU" | "GT" | "GG" | "GW" | "GQ" | "GN" | "GY" | "GF" | "HT" | "HM" | "HN" | "HR" | "ID" | "IS" | "IM" | "IT" | "JM" | "JE" | "GL" | "KH" | "KZ" | "KE" | "KI" | "CF" | "KM" | "RE" | "LV" | "LS" | "LR" | "LI" | "LT" | "LU" | "MG" | "HU" | "MH" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MU" | "YT" | "MX" | "FM" | "MZ" | "MD" | "MC" | "MS" | "NA" | "NL" | "BN" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "NO" | "MP" | "NC" | "AT" | "UZ" | "PK" | "PW" | "PA" | "PG" | "PY" | "PE" | "PH" | "PN" | "PL" | "PF" | "PT" | "PR" | "DO" | "XK" | "CD" | "CG" | "RO" | "RW" | "KN" | "LC" | "VC" | "BL" | "MF" | "PM" | "WS" | "SM" | "ST" | "CH" | "SN" | "SC" | "AL" | "SL" | "SG" | "SI" | "SK" | "SB" | "SO" | "ZA" | "GS" | "SS" | "LK" | "FI" | "SR" | "SE" | "SZ" | "TZ" | "TD" | "TF" | "TL" | "TG" | "TO" | "TT" | "TR" | "TM" | "TC" | "TV" | "UG" | "GB" | "US" | "UM" | "VI" | "UY" | "VU" | "VA" | "VE" | "VN" | "WF" | "ZM" | "ZW" | "BT" | "GR" | "CY" | "BY" | "BG" | "KG" | "MK" | "MN" | "RU" | "RS" | "TJ" | "UA" | "ME" | "AM" | "IL" | "AF" | "JO" | "DZ" | "SD" | "EH" | "IQ" | "SA" | "KW" | "MA" | "YE" | "IR" | "TN" | "AE" | "SY" | "OM" | "PS" | "QA" | "LB" | "EG" | "MR" | "NP" | "IN" | "TH" | "LA" | "MM" | "GE" | "ET" | "ER" | "BH" | "LY" | "CN" | "JP" | "MO" | "TW" | "HK" | "KR" | "KP";
|
|
1994
1994
|
export declare const isIndividualCountryCCA3: (value: unknown) => value is "FRA" | "BEL" | "CZE" | "DNK" | "DEU" | "EST" | "IRL" | "ESP" | "HRV" | "ISL" | "ITA" | "LVA" | "LIE" | "LTU" | "LUX" | "HUN" | "MLT" | "MCO" | "NLD" | "NOR" | "AUT" | "POL" | "PRT" | "ROU" | "SVN" | "SVK" | "FIN" | "SWE" | "GRC" | "CYP" | "BGR";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
export const usePlacekit = ({ apiKey }) => {
|
|
3
|
+
const [placekit, setPlacekit] = useState(undefined);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (apiKey != null) {
|
|
6
|
+
void import("@placekit/client-js").then(({ default: placekit }) => {
|
|
7
|
+
setPlacekit(placekit(apiKey));
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
}, [apiKey]);
|
|
11
|
+
return placekit;
|
|
12
|
+
};
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Future, Result } from "@swan-io/boxed";
|
|
3
|
-
import { AutoWidthImage } from "@swan-io/lake/src/components/AutoWidthImage";
|
|
4
|
-
import { AutocompleteSearchInput } from "@swan-io/lake/src/components/AutocompleteSearchInput";
|
|
5
|
-
import { Box } from "@swan-io/lake/src/components/Box";
|
|
6
|
-
import { countriesWithMultipleCCA3, } from "@swan-io/shared-business/src/constants/countries";
|
|
7
|
-
import { useCallback, useMemo } from "react";
|
|
8
|
-
import { StyleSheet } from "react-native";
|
|
9
|
-
import poweredByGoogle from "../assets/images/powered_by_google_on_white_hdpi.png";
|
|
10
|
-
import { getPlaceDetails, useGoogleMapSDK } from "../hooks/useGoogleMapSDK";
|
|
11
|
-
const styles = StyleSheet.create({
|
|
12
|
-
footer: {
|
|
13
|
-
padding: 12,
|
|
14
|
-
paddingBottom: 4,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
export const GMapAddressSearchInput = ({ inputRef, id, country, disabled, error, value, onValueChange, onSuggestion, language, placeholder, shouldDisplaySuggestions = true, emptyResultText, apiKey, }) => {
|
|
18
|
-
const sdk = useGoogleMapSDK({
|
|
19
|
-
language,
|
|
20
|
-
apiKey,
|
|
21
|
-
});
|
|
22
|
-
const autocomplete = useMemo(() => sdk.map(google => new google.maps.places.AutocompleteService()), [sdk]);
|
|
23
|
-
const loadSuggestions = useCallback((value) => {
|
|
24
|
-
if (autocomplete.isDone()) {
|
|
25
|
-
return Future.fromPromise(autocomplete.get().getPlacePredictions({
|
|
26
|
-
input: value,
|
|
27
|
-
componentRestrictions: { country: countriesWithMultipleCCA3[country] ?? [country] },
|
|
28
|
-
types: ["address"],
|
|
29
|
-
})).mapOk(({ predictions }) => predictions.map(p => ({
|
|
30
|
-
id: p.place_id,
|
|
31
|
-
title: p.structured_formatting.main_text,
|
|
32
|
-
subtitle: p.structured_formatting.secondary_text,
|
|
33
|
-
value: null,
|
|
34
|
-
})), true);
|
|
35
|
-
}
|
|
36
|
-
return Future.value(Result.Ok([]));
|
|
37
|
-
}, [autocomplete, country]);
|
|
38
|
-
const onSuggestionSelected = useCallback((suggestion) => {
|
|
39
|
-
getPlaceDetails(suggestion.id).onResolve(result => {
|
|
40
|
-
if (result.isOk()) {
|
|
41
|
-
const dependsOnCountriesWithMultipleCCA3 = countriesWithMultipleCCA3[country]?.includes(result.value.country);
|
|
42
|
-
onSuggestion?.({
|
|
43
|
-
...result.value,
|
|
44
|
-
country: dependsOnCountriesWithMultipleCCA3 === true ? country : result.value.country,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}, [country, onSuggestion]);
|
|
49
|
-
return (_jsx(AutocompleteSearchInput, { inputRef: inputRef, value: value, onValueChange: onValueChange, disabled: disabled, id: id, placeholder: placeholder, error: error, emptyResultText: emptyResultText, ListFooterComponent: _jsx(Box, { direction: "row", justifyContent: "end", style: styles.footer, children: _jsx(AutoWidthImage, { height: 14, sourceUri: poweredByGoogle }) }), shouldDisplaySuggestions: shouldDisplaySuggestions, loadSuggestions: loadSuggestions, onSuggestion: onSuggestionSelected }));
|
|
50
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { CountryCCA3 } from "../constants/countries";
|
|
2
|
-
import { PlaceDetail } from "../hooks/useGoogleMapSDK";
|
|
3
|
-
type Props = {
|
|
4
|
-
value: string;
|
|
5
|
-
onValueChange: (value: string) => void;
|
|
6
|
-
country?: CountryCCA3;
|
|
7
|
-
disabled?: boolean;
|
|
8
|
-
error?: string;
|
|
9
|
-
id?: string;
|
|
10
|
-
placeholder?: string;
|
|
11
|
-
onSuggestion?: (place: Pick<PlaceDetail, "city" | "postalCode">) => void;
|
|
12
|
-
onLoadError: (error: unknown) => void;
|
|
13
|
-
apiKey: string;
|
|
14
|
-
};
|
|
15
|
-
export declare const GMapCityInput: ({ value, onValueChange, country, disabled, placeholder, id, error, onSuggestion, onLoadError, apiKey, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
-
export {};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Future, Result } from "@swan-io/boxed";
|
|
3
|
-
import { AutoWidthImage } from "@swan-io/lake/src/components/AutoWidthImage";
|
|
4
|
-
import { AutocompleteSearchInput } from "@swan-io/lake/src/components/AutocompleteSearchInput";
|
|
5
|
-
import { Box } from "@swan-io/lake/src/components/Box";
|
|
6
|
-
import { isNotNullish } from "@swan-io/lake/src/utils/nullish";
|
|
7
|
-
import { useCallback, useMemo } from "react";
|
|
8
|
-
import { StyleSheet } from "react-native";
|
|
9
|
-
import poweredByGoogle from "../assets/images/powered_by_google_on_white_hdpi.png";
|
|
10
|
-
import { countriesWithMultipleCCA3 } from "../constants/countries";
|
|
11
|
-
import { getPlaceDetails, useGoogleMapSDK } from "../hooks/useGoogleMapSDK";
|
|
12
|
-
import { t } from "../utils/i18n";
|
|
13
|
-
const styles = StyleSheet.create({
|
|
14
|
-
poweredByGoogle: {
|
|
15
|
-
paddingVertical: 8,
|
|
16
|
-
paddingHorizontal: 16,
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
export const GMapCityInput = ({ value, onValueChange, country, disabled, placeholder, id, error, onSuggestion, onLoadError, apiKey, }) => {
|
|
20
|
-
const sdk = useGoogleMapSDK({ apiKey });
|
|
21
|
-
const autocomplete = useMemo(() => sdk.map(google => new google.maps.places.AutocompleteService()), [sdk]);
|
|
22
|
-
const loadSuggestions = useCallback((value) => {
|
|
23
|
-
if (autocomplete.isDone() && isNotNullish(country)) {
|
|
24
|
-
return Future.fromPromise(autocomplete.get().getPlacePredictions({
|
|
25
|
-
input: value,
|
|
26
|
-
componentRestrictions: {
|
|
27
|
-
country: [...(countriesWithMultipleCCA3[country] ?? "")],
|
|
28
|
-
},
|
|
29
|
-
types: ["(cities)"],
|
|
30
|
-
})).mapOk(({ predictions }) => predictions.map(p => ({
|
|
31
|
-
id: p.place_id,
|
|
32
|
-
title: p.structured_formatting.main_text,
|
|
33
|
-
subtitle: p.structured_formatting.secondary_text,
|
|
34
|
-
value: null,
|
|
35
|
-
})), true);
|
|
36
|
-
}
|
|
37
|
-
return Future.value(Result.Ok([]));
|
|
38
|
-
}, [autocomplete, country]);
|
|
39
|
-
const onSuggestionSelected = useCallback((suggestion) => {
|
|
40
|
-
getPlaceDetails(suggestion.id).onResolve(result => {
|
|
41
|
-
if (result.isOk()) {
|
|
42
|
-
console.log("result.value", result.value);
|
|
43
|
-
onSuggestion?.(result.value);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}, [onSuggestion]);
|
|
47
|
-
return (_jsx(AutocompleteSearchInput, { value: value, onValueChange: onValueChange, disabled: disabled, id: id, placeholder: placeholder, error: error, emptyResultText: t("common.noResult"), ListFooterComponent: _jsx(Box, { direction: "row", justifyContent: "end", style: styles.poweredByGoogle, children: _jsx(AutoWidthImage, { height: 14, sourceUri: poweredByGoogle }) }), loadSuggestions: loadSuggestions, onSuggestion: onSuggestionSelected, onLoadError: onLoadError }));
|
|
48
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/// <reference types="google.maps" />
|
|
2
|
-
import { AsyncData, Future, Result } from "@swan-io/boxed";
|
|
3
|
-
type Props = {
|
|
4
|
-
language?: string;
|
|
5
|
-
apiKey: string;
|
|
6
|
-
};
|
|
7
|
-
export declare const useGoogleMapSDK: ({ language, apiKey }: Props) => AsyncData<typeof google>;
|
|
8
|
-
export type PlaceDetail = {
|
|
9
|
-
completeAddress: string;
|
|
10
|
-
streetNumber: string;
|
|
11
|
-
city: string;
|
|
12
|
-
country: string;
|
|
13
|
-
postalCode: string;
|
|
14
|
-
};
|
|
15
|
-
export declare const getPlaceDetails: (placeId: string) => Future<Result<PlaceDetail, unknown>>;
|
|
16
|
-
export {};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Loader } from "@googlemaps/js-api-loader";
|
|
2
|
-
import { AsyncData, Future, Result } from "@swan-io/boxed";
|
|
3
|
-
import { useEffect } from "react";
|
|
4
|
-
import { atom, useAtom } from "react-atomic-state";
|
|
5
|
-
import { match } from "ts-pattern";
|
|
6
|
-
import { getCCA3forCCA2 } from "../constants/countries";
|
|
7
|
-
const sdk = atom(AsyncData.NotAsked());
|
|
8
|
-
export const useGoogleMapSDK = ({ language, apiKey }) => {
|
|
9
|
-
const googleSdk = useAtom(sdk);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
if (googleSdk.isNotAsked()) {
|
|
12
|
-
if (apiKey != undefined) {
|
|
13
|
-
sdk.set(AsyncData.Loading());
|
|
14
|
-
void new Loader({
|
|
15
|
-
apiKey,
|
|
16
|
-
language,
|
|
17
|
-
libraries: ["places"],
|
|
18
|
-
authReferrerPolicy: "origin",
|
|
19
|
-
})
|
|
20
|
-
.load()
|
|
21
|
-
.then(google => sdk.set(AsyncData.Done(google)));
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}, [language, googleSdk, apiKey]);
|
|
25
|
-
return googleSdk;
|
|
26
|
-
};
|
|
27
|
-
export const getPlaceDetails = (placeId) => {
|
|
28
|
-
return Future.make(resolve => {
|
|
29
|
-
const place = new google.maps.places.PlacesService(document.createElement("div"));
|
|
30
|
-
place.getDetails({ placeId }, placeDetail => {
|
|
31
|
-
if (placeDetail?.address_components == null) {
|
|
32
|
-
resolve(Result.Error("No place detail found"));
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
const result = {
|
|
36
|
-
completeAddress: "",
|
|
37
|
-
streetNumber: "",
|
|
38
|
-
postalCode: "",
|
|
39
|
-
country: "",
|
|
40
|
-
city: "",
|
|
41
|
-
};
|
|
42
|
-
placeDetail.address_components.forEach(({ types, short_name, long_name }) => {
|
|
43
|
-
const type = types[0];
|
|
44
|
-
match(type)
|
|
45
|
-
.with("street_number", () => (result.streetNumber = long_name))
|
|
46
|
-
.with("route", () => (result.completeAddress = long_name))
|
|
47
|
-
.with("postal_code", () => (result.postalCode = short_name))
|
|
48
|
-
.with("country", () => (result.country = getCCA3forCCA2(short_name) ?? short_name))
|
|
49
|
-
.with("locality", () => (result.city = long_name))
|
|
50
|
-
.otherwise(() => { });
|
|
51
|
-
});
|
|
52
|
-
if (result.streetNumber != "") {
|
|
53
|
-
if (placeDetail?.name === `${result.completeAddress} ${result.streetNumber}`) {
|
|
54
|
-
result.completeAddress = `${result.completeAddress} ${result.streetNumber}`;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
result.completeAddress = `${result.streetNumber} ${result.completeAddress}`;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
resolve(Result.Ok(result));
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
};
|