@swan-io/shared-business 13.11.3 → 14.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 +15 -12
- package/src/components/InputPhoneNumber.d.ts +9 -0
- package/src/components/InputPhoneNumber.js +8 -1
- package/src/components/PlacekitCityInput.js +2 -2
- package/src/components/SupportingDocumentCollection.d.ts +20 -12
- package/src/components/SupportingDocumentCollection.js +53 -43
- package/src/constants/countries.js +0 -1
- package/src/locales/fr.json +2 -2
- package/src/locales/nl.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swan-io/shared-business",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">22.12.0"
|
|
6
6
|
},
|
|
@@ -25,31 +25,34 @@
|
|
|
25
25
|
],
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"
|
|
28
|
+
"react": ">=19.0.0",
|
|
29
|
+
"react-dom": ">=19.0.0",
|
|
30
|
+
"react-native-web": ">=0.21.2",
|
|
31
|
+
"@swan-io/lake": "14.0.0"
|
|
29
32
|
},
|
|
30
33
|
"dependencies": {
|
|
31
|
-
"@formatjs/intl": "^4.1.
|
|
34
|
+
"@formatjs/intl": "^4.1.11",
|
|
32
35
|
"@placekit/client-js": "^2.3.0",
|
|
33
36
|
"@swan-io/boxed": "^3.2.1",
|
|
34
37
|
"@swan-io/request": "^3.1.0",
|
|
35
38
|
"@swan-io/use-form": "^3.1.0",
|
|
36
|
-
"dayjs": "^1.11.
|
|
39
|
+
"dayjs": "^1.11.20",
|
|
37
40
|
"iban": "^0.0.14",
|
|
38
|
-
"react": "^19.2.4",
|
|
39
41
|
"react-atomic-state": "^2.1.0",
|
|
40
|
-
"react-
|
|
41
|
-
"react-dropzone": "^14.4.0",
|
|
42
|
-
"react-native-web": "^0.21.2",
|
|
42
|
+
"react-dropzone": "^15.0.0",
|
|
43
43
|
"rifm": "^0.12.1",
|
|
44
44
|
"ts-pattern": "^5.9.0",
|
|
45
|
-
"uuid": "^
|
|
45
|
+
"uuid": "^14.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/iban": "0.0.35",
|
|
49
|
-
"@types/react": "^19.2.
|
|
49
|
+
"@types/react": "^19.2.14",
|
|
50
50
|
"@types/react-dom": "^19.2.3",
|
|
51
51
|
"@types/react-native": "^0.72.8",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
52
|
+
"react": "^19.2.6",
|
|
53
|
+
"react-dom": "^19.2.6",
|
|
54
|
+
"react-native-web": "^0.21.2",
|
|
55
|
+
"type-fest": "^5.6.0",
|
|
56
|
+
"@swan-io/lake": "14.0.0"
|
|
54
57
|
}
|
|
55
58
|
}
|
|
@@ -23,5 +23,14 @@ type Props = {
|
|
|
23
23
|
onSubmitEditing?: () => void;
|
|
24
24
|
onBlur?: () => void;
|
|
25
25
|
};
|
|
26
|
+
export declare const getInitialPhoneCountry: (phoneNumber: string | undefined, defaultCountry: Country) => {
|
|
27
|
+
readonly cca2: "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" | "FR" | "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";
|
|
28
|
+
readonly cca3: "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" | "FRA" | "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" | "XKX" | "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";
|
|
29
|
+
name: string;
|
|
30
|
+
deburr: string;
|
|
31
|
+
idd: string;
|
|
32
|
+
uid: string;
|
|
33
|
+
flag: string;
|
|
34
|
+
};
|
|
26
35
|
export declare const InputPhoneNumber: ({ ref, id, country, value, countries, error, help, valid, autofocus, disabled, readOnly, countryAriaLabel, hideErrors, onCountryChange, onChangeText, onSubmitEditing, onBlur, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
27
36
|
export {};
|
|
@@ -7,7 +7,7 @@ import { colors } from "@swan-io/lake/src/constants/design";
|
|
|
7
7
|
import { isNotNullishOrEmpty } from "@swan-io/lake/src/utils/nullish";
|
|
8
8
|
import { useEffect, useImperativeHandle, useRef } from "react";
|
|
9
9
|
import { StyleSheet } from "react-native";
|
|
10
|
-
import { phoneCountries } from "../constants/countries";
|
|
10
|
+
import { countries, phoneCountries } from "../constants/countries";
|
|
11
11
|
import { PhoneCountryPicker } from "./PhoneCountryPicker";
|
|
12
12
|
const styles = StyleSheet.create({
|
|
13
13
|
picker: {
|
|
@@ -24,6 +24,13 @@ const styles = StyleSheet.create({
|
|
|
24
24
|
borderBottomLeftRadius: 0,
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
|
+
export const getInitialPhoneCountry = (phoneNumber, defaultCountry) => {
|
|
28
|
+
var _a;
|
|
29
|
+
if (phoneNumber == null) {
|
|
30
|
+
return defaultCountry;
|
|
31
|
+
}
|
|
32
|
+
return (_a = countries.find(country => phoneNumber.startsWith(`+${country.idd}`))) !== null && _a !== void 0 ? _a : defaultCountry;
|
|
33
|
+
};
|
|
27
34
|
export const InputPhoneNumber = ({ ref, id, country, value, countries, error, help, valid = false, autofocus = false, disabled = false, readOnly = false, countryAriaLabel, hideErrors = false, onCountryChange, onChangeText, onSubmitEditing, onBlur, }) => {
|
|
28
35
|
var _a;
|
|
29
36
|
const inputRef = useRef(null);
|
|
@@ -14,7 +14,7 @@ export const PlacekitCityInput = ({ value, onValueChange, country, disabled, pla
|
|
|
14
14
|
.map(cca3Codes => Array.filterMap(cca3Codes, cca3 => Option.fromNullable(getCCA2forCCA3(cca3))))
|
|
15
15
|
.flatMap(array => (array.length === 0 ? Option.None() : Option.Some(array)));
|
|
16
16
|
return Future.fromPromise(placekit.search(value, {
|
|
17
|
-
types: ["city"],
|
|
17
|
+
types: ["city", "county"],
|
|
18
18
|
countries: countries.toUndefined(),
|
|
19
19
|
})).mapOk(({ results }) => results
|
|
20
20
|
.filter((result, index, self) => self.findIndex(r => r.name === result.name && r.zipcode[0] === result.zipcode[0]) === index)
|
|
@@ -31,7 +31,7 @@ export const PlacekitCityInput = ({ value, onValueChange, country, disabled, pla
|
|
|
31
31
|
}, [placekit, country]);
|
|
32
32
|
const onSuggestionSelected = useCallback((suggestion) => {
|
|
33
33
|
onSuggestion === null || onSuggestion === void 0 ? void 0 : onSuggestion({
|
|
34
|
-
city: suggestion.value.city,
|
|
34
|
+
city: suggestion.value.city !== "" ? suggestion.value.city : suggestion.value.county, // adding this for cases such as Papeete where city is empty and county is filled with the city name
|
|
35
35
|
postalCode: suggestion.value.zipcode[0],
|
|
36
36
|
});
|
|
37
37
|
}, [onSuggestion]);
|
|
@@ -8,10 +8,21 @@ export type Document<Purpose extends string> = {
|
|
|
8
8
|
purpose: Purpose;
|
|
9
9
|
file: SwanFile;
|
|
10
10
|
};
|
|
11
|
-
type
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export type DocumentPurposeInfo = {
|
|
12
|
+
label: string;
|
|
13
|
+
description: string;
|
|
14
|
+
purposeDetails?: string;
|
|
15
|
+
required: boolean;
|
|
16
|
+
};
|
|
17
|
+
type SupportingDocumentPurposeInput<Purpose extends string> = {
|
|
18
|
+
name: Purpose;
|
|
19
|
+
label: string;
|
|
20
|
+
description: string;
|
|
21
|
+
purposeDetails?: string | null;
|
|
14
22
|
};
|
|
23
|
+
export declare const toDocumentPurposes: <Purpose extends string>(requiredPurposes: SupportingDocumentPurposeInput<Purpose>[], documents: {
|
|
24
|
+
purpose: SupportingDocumentPurposeInput<Purpose>;
|
|
25
|
+
}[]) => Record<Purpose, DocumentPurposeInfo>;
|
|
15
26
|
export type UploadOutput = {
|
|
16
27
|
url: string;
|
|
17
28
|
fields: {
|
|
@@ -35,13 +46,12 @@ export type SupportingDocumentCollectionRef<Purpose extends string> = {
|
|
|
35
46
|
type Props<Purpose extends string> = {
|
|
36
47
|
ref?: Ref<SupportingDocumentCollectionRef<Purpose>>;
|
|
37
48
|
status: SupportingDocumentCollectionStatus;
|
|
38
|
-
generateUpload: (input:
|
|
49
|
+
generateUpload: (input: {
|
|
50
|
+
fileName: string;
|
|
51
|
+
purpose: Purpose;
|
|
52
|
+
}) => Future<Result<UploadOutputWithId<UploadOutput>, unknown>>;
|
|
39
53
|
documents: Document<Purpose>[];
|
|
40
|
-
|
|
41
|
-
label: string;
|
|
42
|
-
description: string;
|
|
43
|
-
purposeDetails?: string;
|
|
44
|
-
} | undefined>;
|
|
54
|
+
documentPurposes: Record<Purpose, DocumentPurposeInfo | undefined>;
|
|
45
55
|
uploadFile?: (config: UploadFileInput<UploadOutput>) => Future<Result<Response<string>, NetworkError | TimeoutError>>;
|
|
46
56
|
onChange?: (documents: Document<Purpose>[]) => void;
|
|
47
57
|
onRemoveFile?: (file: SwanFile) => Future<Result<unknown, unknown>>;
|
|
@@ -52,7 +62,5 @@ type Props<Purpose extends string> = {
|
|
|
52
62
|
getPurposeMetadata?: (purose: Purpose) => PurposeMetadata | undefined;
|
|
53
63
|
readonlyDocumentPurposes?: Purpose[];
|
|
54
64
|
};
|
|
55
|
-
export declare const
|
|
56
|
-
export declare const getSupportingDocumentPurposeDescriptionLabel: (purpose: string) => string;
|
|
57
|
-
export declare const SupportingDocumentCollection: <Purpose extends string>({ ref, documents, generateUpload, uploadFile, requiredDocumentPurposes, templateLanguage, status, onChange, onRemoveFile, showIds, readOnly, getPurposeMetadata, companyCountry, readonlyDocumentPurposes, }: Props<Purpose>) => import("react/jsx-runtime").JSX.Element;
|
|
65
|
+
export declare const SupportingDocumentCollection: <Purpose extends string>({ ref, documents, generateUpload, uploadFile, documentPurposes, templateLanguage, status, onChange, onRemoveFile, showIds, readOnly, getPurposeMetadata, companyCountry, readonlyDocumentPurposes, }: Props<Purpose>) => import("react/jsx-runtime").JSX.Element;
|
|
58
66
|
export {};
|
|
@@ -19,6 +19,30 @@ import { isTranslationKey, locale, t } from "../utils/i18n";
|
|
|
19
19
|
import { FilesUploader } from "./FilesUploader";
|
|
20
20
|
import { LakeModal } from "./LakeModal";
|
|
21
21
|
const ACCEPTED_FORMATS = ["application/pdf", "image/png", "image/jpeg", "image/heic"];
|
|
22
|
+
export const toDocumentPurposes = (requiredPurposes, documents) => {
|
|
23
|
+
const entries = new Map();
|
|
24
|
+
requiredPurposes.forEach(({ name, label, description, purposeDetails }) => {
|
|
25
|
+
entries.set(name, {
|
|
26
|
+
label,
|
|
27
|
+
description,
|
|
28
|
+
purposeDetails: purposeDetails !== null && purposeDetails !== void 0 ? purposeDetails : undefined,
|
|
29
|
+
required: true,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
documents.forEach(({ purpose }) => {
|
|
33
|
+
var _a;
|
|
34
|
+
if (entries.has(purpose.name)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
entries.set(purpose.name, {
|
|
38
|
+
label: purpose.label,
|
|
39
|
+
description: purpose.description,
|
|
40
|
+
purposeDetails: (_a = purpose.purposeDetails) !== null && _a !== void 0 ? _a : undefined,
|
|
41
|
+
required: false,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return Object.fromEntries(entries);
|
|
45
|
+
};
|
|
22
46
|
const styles = StyleSheet.create({
|
|
23
47
|
button: { opacity: 1 },
|
|
24
48
|
buttonWithDefaultCursor: { opacity: 1, cursor: "default" },
|
|
@@ -43,65 +67,52 @@ const getSupportLink = (language, country) => match({ language, country })
|
|
|
43
67
|
.with(P.union({ country: "NLD" }, { country: P.nullish, language: "nl" }), () => `https://support.swan.io/hc/${language}/articles/22543228421277`)
|
|
44
68
|
.with(P.union({ country: "BEL" }), () => `https://support.swan.io/hc/${language}/articles/31233251462173`)
|
|
45
69
|
.otherwise(() => "https://support.swan.io/hc/en-150/articles/22620756787869-Proof-of-company-registration");
|
|
46
|
-
|
|
70
|
+
// Fallback helpers kept temporarily as a safety net
|
|
71
|
+
// Remove after ~1 month if backend reliably returns translated label/description for every purpose.
|
|
72
|
+
const getSupportingDocumentPurposeLabel = (purpose) => {
|
|
47
73
|
const key = `supportingDocuments.purpose.${purpose}`;
|
|
48
74
|
return isTranslationKey(key) ? t(key) : purpose;
|
|
49
75
|
};
|
|
50
|
-
|
|
76
|
+
const getSupportingDocumentPurposeDescriptionLabel = (purpose) => {
|
|
51
77
|
const key = `supportingDocuments.purpose.${purpose}.description`;
|
|
52
78
|
return isTranslationKey(key) ? t(key) : "";
|
|
53
79
|
};
|
|
54
|
-
export const SupportingDocumentCollection = ({ ref, documents, generateUpload, uploadFile,
|
|
80
|
+
export const SupportingDocumentCollection = ({ ref, documents, generateUpload, uploadFile, documentPurposes, templateLanguage = locale.language, status, onChange, onRemoveFile, showIds = false, readOnly = false, getPurposeMetadata, companyCountry, readonlyDocumentPurposes = [], }) => {
|
|
55
81
|
const [showPowerOfAttorneyModal, setShowPowerOfAttorneyModal] = useState(false);
|
|
56
82
|
const [showSwornStatementModal, setShowSwornStatementModal] = useState(false);
|
|
57
83
|
const [currentMetadata, setCurrentMetadata] = useState(undefined);
|
|
58
84
|
const [addedDocuments, setAddedDocuments] = useState([]);
|
|
59
85
|
const orderedDocumentPurposes = useMemo(() => {
|
|
60
|
-
// Get all purposes to display: the
|
|
61
|
-
const allPurposes = new Set(Object.keys(
|
|
86
|
+
// Get all purposes to display: the ones present in documentPurposes and the ones that have at least a document
|
|
87
|
+
const allPurposes = new Set(Object.keys(documentPurposes));
|
|
62
88
|
const allDocuments = [...addedDocuments, ...documents];
|
|
63
89
|
allDocuments.forEach(document => allPurposes.add(document.purpose));
|
|
64
|
-
|
|
90
|
+
// Compute, for each purpose, everything needed for rendering and sorting in one pass.
|
|
91
|
+
// Priority drives the display order (lower comes first):
|
|
92
|
+
// 0 = has documents and all are validated
|
|
93
|
+
// 1 = purpose is required
|
|
94
|
+
// 2 = otherwise
|
|
95
|
+
const entries = [...allPurposes].map(purpose => {
|
|
96
|
+
var _a, _b;
|
|
65
97
|
const purposeDocuments = allDocuments.filter(document => document.purpose === purpose);
|
|
66
|
-
|
|
67
|
-
}));
|
|
68
|
-
// Map purposes to their priorities (lower priority comes first)
|
|
69
|
-
// We precompute it to avoid running on each `sort` callback call
|
|
70
|
-
const allRequiredPurposes = new Set(Object.keys(requiredDocumentPurposes));
|
|
71
|
-
// Indices:
|
|
72
|
-
// -> 0: documents aren't empty and all validated
|
|
73
|
-
// -> 1: purpose is required
|
|
74
|
-
// -> 2: purpose isn't required
|
|
75
|
-
const priorityByPurpose = new Map([...allPurposes].map(purpose => {
|
|
76
|
-
var _a;
|
|
77
|
-
const purposeDocuments = (_a = documentsByPurpose.get(purpose)) !== null && _a !== void 0 ? _a : [];
|
|
78
|
-
const areAllPurposeDocumentsValidated = purposeDocuments.length > 0 &&
|
|
98
|
+
const areAllDocumentsValidated = purposeDocuments.length > 0 &&
|
|
79
99
|
purposeDocuments.every(document => document.file.statusInfo.status === "Validated");
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
? 1
|
|
84
|
-
: 2;
|
|
85
|
-
return [purpose, priority];
|
|
86
|
-
}));
|
|
87
|
-
return [...allPurposes]
|
|
88
|
-
.sort((purposeA, purposeB) => {
|
|
89
|
-
var _a, _b;
|
|
90
|
-
const purposeAPriority = (_a = priorityByPurpose.get(purposeA)) !== null && _a !== void 0 ? _a : 2;
|
|
91
|
-
const purposeBPriority = (_b = priorityByPurpose.get(purposeB)) !== null && _b !== void 0 ? _b : 2;
|
|
92
|
-
return purposeBPriority > purposeAPriority ? -1 : 1;
|
|
93
|
-
})
|
|
94
|
-
.map(purpose => {
|
|
95
|
-
var _a;
|
|
96
|
-
const documents = (_a = documentsByPurpose.get(purpose)) !== null && _a !== void 0 ? _a : [];
|
|
100
|
+
const info = documentPurposes[purpose];
|
|
101
|
+
const isRequired = (info === null || info === void 0 ? void 0 : info.required) === true;
|
|
102
|
+
const priority = areAllDocumentsValidated ? 0 : isRequired ? 1 : 2;
|
|
97
103
|
return {
|
|
98
104
|
purpose,
|
|
99
|
-
files:
|
|
100
|
-
isRequired
|
|
101
|
-
areAllDocumentsValidated
|
|
105
|
+
files: purposeDocuments.map(item => item.file),
|
|
106
|
+
isRequired,
|
|
107
|
+
areAllDocumentsValidated,
|
|
108
|
+
priority,
|
|
109
|
+
label: (_a = info === null || info === void 0 ? void 0 : info.label) !== null && _a !== void 0 ? _a : getSupportingDocumentPurposeLabel(purpose),
|
|
110
|
+
description: (_b = info === null || info === void 0 ? void 0 : info.description) !== null && _b !== void 0 ? _b : getSupportingDocumentPurposeDescriptionLabel(purpose),
|
|
111
|
+
purposeDetails: info === null || info === void 0 ? void 0 : info.purposeDetails,
|
|
102
112
|
};
|
|
103
113
|
});
|
|
104
|
-
|
|
114
|
+
return entries.sort((a, b) => (b.priority > a.priority ? -1 : 1));
|
|
115
|
+
}, [documentPurposes, documents, addedDocuments]);
|
|
105
116
|
const filesByRequiredPurpose = useRef(new Map(Array.filterMap(orderedDocumentPurposes, ({ isRequired, purpose, files }) => isRequired ? Option.Some([purpose, files]) : Option.None())));
|
|
106
117
|
const filesUploaderRefByPurpose = useRef({});
|
|
107
118
|
useImperativeHandle(ref, () => ({
|
|
@@ -129,10 +140,9 @@ export const SupportingDocumentCollection = ({ ref, documents, generateUpload, u
|
|
|
129
140
|
}
|
|
130
141
|
return true;
|
|
131
142
|
});
|
|
132
|
-
return (_jsxs(Form, { children: [showableDocumentPurposes.map(({ purpose, files, areAllDocumentsValidated, isRequired }) => {
|
|
133
|
-
var _a, _b, _c, _d, _e, _f;
|
|
143
|
+
return (_jsxs(Form, { children: [showableDocumentPurposes.map(({ purpose, files, areAllDocumentsValidated, isRequired, label, description, purposeDetails, }) => {
|
|
134
144
|
const metadata = getPurposeMetadata === null || getPurposeMetadata === void 0 ? void 0 : getPurposeMetadata(purpose);
|
|
135
|
-
return (_jsxs(Fragment, { children: [_jsx(LakeLabel, { label:
|
|
145
|
+
return (_jsxs(Fragment, { children: [_jsx(LakeLabel, { label: label, description: purposeDetails !== null && purposeDetails !== void 0 ? purposeDetails : description, render: () => (_jsxs(_Fragment, { children: [_jsxs(Box, { direction: "row", children: [_jsx(Box, { direction: "row", children: isNotNullish(metadata) ? (purpose === "CompanyRegistration" ? (_jsxs(_Fragment, { children: [_jsx(LakeButton, { size: "small", mode: "secondary", icon: "question-circle-regular", onPress: () => window.open(getSupportLink(locale.language, companyCountry)), ariaLabel: t("supportingDocuments.help.howToSendAGoodDocument"), children: t("supportingDocuments.help.howToSendAGoodDocument") }), _jsx(Space, { width: 8 })] })) : (_jsxs(_Fragment, { children: [_jsx(Help, { type: "button", label: metadata.title, onPress: () => setCurrentMetadata(metadata) }), _jsx(Space, { width: 8 })] }))) : (match(purpose)
|
|
136
146
|
.with("CompanyRegistration", () => (_jsx(LakeButton, { size: "small", mode: "secondary", icon: "question-circle-regular", onPress: () => window.open(getSupportLink(locale.language, companyCountry)), ariaLabel: t("supportingDocuments.help.howToSendAGoodDocument"), children: t("supportingDocuments.help.howToSendAGoodDocument") })))
|
|
137
147
|
.otherwise(() => null)) }), match(purpose)
|
|
138
148
|
.with("PowerOfAttorney", () => (_jsx(Help, { type: "button", icon: "arrow-down-filled", label: t("supportingDocuments.help.downloadTemplate"), onPress: () => setShowPowerOfAttorneyModal(true) })))
|
|
@@ -1834,7 +1834,6 @@ export const companyCountries = [
|
|
|
1834
1834
|
"CYP",
|
|
1835
1835
|
"NOR",
|
|
1836
1836
|
];
|
|
1837
|
-
// Google API accepts only 5 country codes
|
|
1838
1837
|
export const countriesWithMultipleCCA3 = {
|
|
1839
1838
|
FRA: ["FRA", "GUF", "REU", "MTQ", "GLP"], // France, French Guiana, Réunion, Martinique, Guadeloupe
|
|
1840
1839
|
};
|
package/src/locales/fr.json
CHANGED
|
@@ -333,7 +333,7 @@
|
|
|
333
333
|
"supportingDocuments.purpose.CompanyLeaseAgreement": "Contrat de Location d'Entreprise",
|
|
334
334
|
"supportingDocuments.purpose.CompanyObligations": "Obligations de l'entreprise",
|
|
335
335
|
"supportingDocuments.purpose.CompanyRegistration": "Preuve d'enregistrement de moins de trois mois",
|
|
336
|
-
"supportingDocuments.purpose.CompanyRegistration.description": "Document prouvant l'inscription de l’entreprise au Registre du Commerce et des Sociétés (RCS) ou au Registre National des Entreprises (RNE)
|
|
336
|
+
"supportingDocuments.purpose.CompanyRegistration.description": "Document prouvant l'inscription de l’entreprise au Registre et attestant de son existence légale.\n\nFrance: \n- Registre: Registre du Commerce et des Sociétés (RCS) ou au Registre National des Entreprises (RNE).\n- Document: Extrait KBIS ou Avis de situation SIRENE ou Synthèse INPI, de moins de 3 mois.\n\nBelgique: \n- Registre: Banque Carrefour des Entreprises (BCE).\n- Document: Extrait BCE ou attestation d'inscription, de moins de 3 mois.",
|
|
337
337
|
"supportingDocuments.purpose.CompanyTreasury": "Trésorerie de l'entreprise",
|
|
338
338
|
"supportingDocuments.purpose.CorporateIncomeTaxReturn": "Déclaration de l'Impôt sur les Sociétés",
|
|
339
339
|
"supportingDocuments.purpose.FinancialStatements": "Dernière déclaration de l'Impôt sur les sociétés",
|
|
@@ -365,7 +365,7 @@
|
|
|
365
365
|
"supportingDocuments.purpose.ProofOfIndividualAddress": "Justificatif de domicile (datant de moins de 3 mois)",
|
|
366
366
|
"supportingDocuments.purpose.ProofOfIndividualAddress.description": "Un justificatif de domicile est un document permettant de justifier de votre adresse postale.\nDocuments autorisés :\n- Facture récente d'eau, d'électricité, de gaz\n- Certificat d'imposition ou de non-imposition\n- Quittance d'assurance ou de mutuelle\n- Titre de propriété, contrat de location ou quittance de loyer",
|
|
367
367
|
"supportingDocuments.purpose.ProofOfIndividualIncome": "Justificatif de ressources ",
|
|
368
|
-
"supportingDocuments.purpose.ProofOfIndividualIncome.description": "Un justificatif de ressources vise à identifier vos revenus perçus.\nDocuments autorisés :\n- Avis d'imposition de moins de
|
|
368
|
+
"supportingDocuments.purpose.ProofOfIndividualIncome.description": "Un justificatif de ressources vise à identifier vos revenus perçus.\n\nDocuments autorisés :\n- Avis d'imposition de moins de 2 ans (un avis d’imposition est un document officiel émis par l'administration fiscale afin de notifier à un contribuable le montant des impôts qu'il doit payer sur la base de ses revenus et de son patrimoine).\n- Fiche de paie de moins de 3 mois.\n- Entrepreneurs individuels français : dernière déclaration de Chiffre d'Affaire à l'URSSAF.\n- Entrepreneurs individuels belges : dernier avertissement-extrait de rôle.",
|
|
369
369
|
"supportingDocuments.purpose.ProofOfOriginOfFunds": "Justificatif de ressources",
|
|
370
370
|
"supportingDocuments.purpose.ProofOfOriginOfFunds.description": "Un justificatif de ressources vise à identifier vos revenus perçus.\nDocuments autorisés\n- Fiche de paie de moins de 3 mois\n- Avis d'imposition de moins de deux ans",
|
|
371
371
|
"supportingDocuments.purpose.RealEstateIncome": "Revenu immobilier",
|
package/src/locales/nl.json
CHANGED
|
@@ -365,7 +365,7 @@
|
|
|
365
365
|
"supportingDocuments.purpose.ProofOfIndividualAddress": "Bewijs van adres (niet ouder dan 3 maanden)",
|
|
366
366
|
"supportingDocuments.purpose.ProofOfIndividualAddress.description": "Elk document dat het woonadres van de persoon aantoont. Het moet de naam en het adres van de persoon bevatten en mag niet ouder zijn dan 3 maanden.\n\nToegestane documenten:\n- Documenten met betrekking tot de woning (huurovereenkomst, hypotheekuittreksel, etc.)\n- Huishoudelijke nutsrekeningen (voor elektriciteit, telefoon, internetdiensten, gas, water, etc.)\n- Salarisstrook (als het adres van de werknemer hierop staat)",
|
|
367
367
|
"supportingDocuments.purpose.ProofOfIndividualIncome": "Bewijs van inkomen",
|
|
368
|
-
"supportingDocuments.purpose.ProofOfIndividualIncome.description": "Een document of verzamelijk van documenten die het inkomen van een persoon aantonen over een specifieke periode.\n\nToegestane documenten:\n- Een
|
|
368
|
+
"supportingDocuments.purpose.ProofOfIndividualIncome.description": "Een document of verzamelijk van documenten die het inkomen van een persoon aantonen over een specifieke periode.\n\nToegestane documenten:\n- Een loonstrookje van minder dan 3 maanden oud.\n- Nederland: Een belastingaangifte van minder dan 2 jaar oud.\n- België: De meest recente aanslagbiljet.",
|
|
369
369
|
"supportingDocuments.purpose.ProofOfOriginOfFunds": "Bewijs van financiële middelen",
|
|
370
370
|
"supportingDocuments.purpose.ProofOfOriginOfFunds.description": "Officieel document dat de herkomst van de financiële middelen aantoont.\n\nAcceptabele documenten:\n- Loonstrookje (niet ouder dan 3 maanden)\n- Inkomstenbelastingaangifte (niet ouder dan 2 jaar)",
|
|
371
371
|
"supportingDocuments.purpose.RealEstateIncome": "Inkomen uit onroerend goed",
|