@splpi/estore-shared-components 7.0.1 → 7.0.2

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/dist/index.d.mts CHANGED
@@ -70,10 +70,40 @@ interface LifePlanApplication1Props {
70
70
  }
71
71
  declare const LifePlanApplication1: ({ initialData, onUpdate, }: LifePlanApplication1Props) => react_jsx_runtime.JSX.Element;
72
72
 
73
+ interface IOcrValue {
74
+ firstName?: string;
75
+ middleName?: string;
76
+ lastName?: string;
77
+ birthDate?: string;
78
+ idType?: string;
79
+ idNumber?: string;
80
+ addressLine?: string;
81
+ }
82
+ /** Shape returned by the host app's address parser (e.g. GeoApifyService.parseAddress). */
83
+ interface IParsedAddress {
84
+ lot: string;
85
+ street: string;
86
+ barangay: string;
87
+ district: string;
88
+ city: string;
89
+ province: string;
90
+ zipCode: string;
91
+ barangayCandidates: string[];
92
+ districtCandidates: string[];
93
+ cityCandidates: string[];
94
+ provinceCandidates: string[];
95
+ geoapifyUsed: boolean;
96
+ }
97
+
73
98
  interface LifePlanApplication2Props {
74
99
  onAddressUpdate?: (address: IAddress) => void;
100
+ /**
101
+ * Optional address parser from the host app (e.g. GeoApifyService.parseAddress).
102
+ * When provided, the scanned ID address (OCR) is split into the form fields.
103
+ */
104
+ parseAddress?: (addressLine: string) => Promise<IParsedAddress>;
75
105
  }
76
- declare const LifePlanApplication2: ({ onAddressUpdate, }: LifePlanApplication2Props) => react_jsx_runtime.JSX.Element;
106
+ declare const LifePlanApplication2: ({ onAddressUpdate, parseAddress, }: LifePlanApplication2Props) => react_jsx_runtime.JSX.Element;
77
107
 
78
108
  interface LifePlanApplication3Props {
79
109
  initialData?: IEmployment;
@@ -88,20 +118,58 @@ declare const Beneficiary: ({ onUpdate }: BeneficiaryProps) => react_jsx_runtime
88
118
 
89
119
  declare const HealthDeclaration: () => react_jsx_runtime.JSX.Element;
90
120
 
91
- declare const LifePlanApplicationFormWrapper: ({ openSection, openSectionKey, onValidChange, }: {
121
+ declare const LifePlanApplicationFormWrapper: ({ openSection, openSectionKey, onValidChange, parseAddress, }: {
92
122
  openSection?: string;
93
123
  openSectionKey?: number;
94
124
  onValidChange?: (valid: boolean) => void;
125
+ parseAddress?: (addressLine: string) => Promise<IParsedAddress>;
95
126
  }) => react_jsx_runtime.JSX.Element;
96
127
 
97
- declare const LifePlanApplicationStepWrapper: () => react_jsx_runtime.JSX.Element;
128
+ interface CartItem {
129
+ planDesc: string;
130
+ mode: string;
131
+ planTerm: string;
132
+ quantity: number;
133
+ price: number;
134
+ total: number;
135
+ contractPrice: number;
136
+ ipInstAmt?: number;
137
+ balance?: number;
138
+ }
98
139
 
140
+ type NewSalesCheckoutItem = {
141
+ planDesc: CartItem["planDesc"];
142
+ mode: CartItem["mode"];
143
+ ipInstAmt: number;
144
+ planTerm: CartItem["planTerm"];
145
+ quantity: number;
146
+ };
147
+ type NewSalesCheckoutRequest = {
148
+ items: NewSalesCheckoutItem[];
149
+ application: IApplicationData;
150
+ };
99
151
  type SharedLifePlanApplicationProps = {
100
152
  title?: string;
101
153
  description?: string;
102
154
  onPaymentError?: (error: unknown) => void;
155
+ /**
156
+ * Called on the payment step with the cart items and application data.
157
+ * Must return the checkout URL (e.g. from PayMongoService.createNewSalesCheckout).
158
+ */
159
+ onCheckout?: (request: NewSalesCheckoutRequest) => Promise<string | undefined>;
160
+ /** Optional address parser used to fill the address form from the scanned ID. */
161
+ parseAddress?: (addressLine: string) => Promise<IParsedAddress>;
103
162
  };
104
- declare const SharedLifePlanApplication: ({ title, description, onPaymentError, }: SharedLifePlanApplicationProps) => react_jsx_runtime.JSX.Element;
163
+ declare const SharedLifePlanApplication: ({ title, description, onPaymentError, onCheckout, parseAddress, }: SharedLifePlanApplicationProps) => react_jsx_runtime.JSX.Element;
164
+
165
+ declare const LifePlanApplicationStepWrapper: (props: SharedLifePlanApplicationProps) => react_jsx_runtime.JSX.Element;
166
+
167
+ declare const OCR_STORAGE_KEY = "ocrResult";
168
+ type OcrSection = "personal" | "address";
169
+ /** Returns the saved OCR result if it has not been applied to this section yet. */
170
+ declare const readOcrResult: (section: OcrSection) => IOcrValue | null;
171
+ /** Marks the OCR result as used for this section. Returns true the first time only. */
172
+ declare const markOcrApplied: (section: OcrSection) => boolean;
105
173
 
106
174
  type QuickAction = {
107
175
  /** React Icons icon component */
@@ -185,20 +253,8 @@ interface ReusableProfileProps {
185
253
  }
186
254
  declare function ReusableProfile({ user, colorMode: controlledColorMode, onColorModeChange, initialTwoFactorEnabled, initialQuickNavHrefs, availableNavOptions, maxQuickNavItems, enableLocalStorage, storageKey, onSaveAccount, onChangePassword, onSignOut, onTwoFactorChange, onToast, }: ReusableProfileProps): react_jsx_runtime.JSX.Element;
187
255
 
188
- interface CartItem {
189
- planDesc: string;
190
- mode: string;
191
- planTerm: string;
192
- quantity: number;
193
- price: number;
194
- total: number;
195
- contractPrice: number;
196
- ipInstAmt?: number;
197
- balance?: number;
198
- }
199
-
200
256
  declare const createEmptyApplicationData: () => IApplicationData;
201
257
  declare const loadApplicationDataFromLocalStorage: (storageKey?: string) => IApplicationData | null;
202
258
  declare const saveApplicationDataToLocalStorage: (data: IApplicationData, storageKey?: string) => void;
203
259
 
204
- export { Beneficiary, type BeneficiaryClass, BottomQuickActions, type CartItem, HealthDeclaration, type IAddress, type IApplicationData, type IBeneficiary, type IEmployment, type IHealthDeclaration, type IPersonalInfo, type ITransactionData, LifePlanApplication1, LifePlanApplication2, LifePlanApplication3, LifePlanApplicationFormWrapper, LifePlanApplicationStepWrapper, type NavOptionDef, NotifyInstall, type ProfileUser, type ReusableProfileProps, SharedLifePlanApplication, ReusableProfile as UserProfile, createEmptyApplicationData, loadApplicationDataFromLocalStorage, saveApplicationDataToLocalStorage };
260
+ export { Beneficiary, type BeneficiaryClass, BottomQuickActions, type CartItem, HealthDeclaration, type IAddress, type IApplicationData, type IBeneficiary, type IEmployment, type IHealthDeclaration, type IOcrValue, type IParsedAddress, type IPersonalInfo, type ITransactionData, LifePlanApplication1, LifePlanApplication2, LifePlanApplication3, LifePlanApplicationFormWrapper, LifePlanApplicationStepWrapper, type NavOptionDef, type NewSalesCheckoutItem, type NewSalesCheckoutRequest, NotifyInstall, OCR_STORAGE_KEY, type OcrSection, type ProfileUser, type ReusableProfileProps, SharedLifePlanApplication, type SharedLifePlanApplicationProps, ReusableProfile as UserProfile, createEmptyApplicationData, loadApplicationDataFromLocalStorage, markOcrApplied, readOcrResult, saveApplicationDataToLocalStorage };
package/dist/index.d.ts CHANGED
@@ -70,10 +70,40 @@ interface LifePlanApplication1Props {
70
70
  }
71
71
  declare const LifePlanApplication1: ({ initialData, onUpdate, }: LifePlanApplication1Props) => react_jsx_runtime.JSX.Element;
72
72
 
73
+ interface IOcrValue {
74
+ firstName?: string;
75
+ middleName?: string;
76
+ lastName?: string;
77
+ birthDate?: string;
78
+ idType?: string;
79
+ idNumber?: string;
80
+ addressLine?: string;
81
+ }
82
+ /** Shape returned by the host app's address parser (e.g. GeoApifyService.parseAddress). */
83
+ interface IParsedAddress {
84
+ lot: string;
85
+ street: string;
86
+ barangay: string;
87
+ district: string;
88
+ city: string;
89
+ province: string;
90
+ zipCode: string;
91
+ barangayCandidates: string[];
92
+ districtCandidates: string[];
93
+ cityCandidates: string[];
94
+ provinceCandidates: string[];
95
+ geoapifyUsed: boolean;
96
+ }
97
+
73
98
  interface LifePlanApplication2Props {
74
99
  onAddressUpdate?: (address: IAddress) => void;
100
+ /**
101
+ * Optional address parser from the host app (e.g. GeoApifyService.parseAddress).
102
+ * When provided, the scanned ID address (OCR) is split into the form fields.
103
+ */
104
+ parseAddress?: (addressLine: string) => Promise<IParsedAddress>;
75
105
  }
76
- declare const LifePlanApplication2: ({ onAddressUpdate, }: LifePlanApplication2Props) => react_jsx_runtime.JSX.Element;
106
+ declare const LifePlanApplication2: ({ onAddressUpdate, parseAddress, }: LifePlanApplication2Props) => react_jsx_runtime.JSX.Element;
77
107
 
78
108
  interface LifePlanApplication3Props {
79
109
  initialData?: IEmployment;
@@ -88,20 +118,58 @@ declare const Beneficiary: ({ onUpdate }: BeneficiaryProps) => react_jsx_runtime
88
118
 
89
119
  declare const HealthDeclaration: () => react_jsx_runtime.JSX.Element;
90
120
 
91
- declare const LifePlanApplicationFormWrapper: ({ openSection, openSectionKey, onValidChange, }: {
121
+ declare const LifePlanApplicationFormWrapper: ({ openSection, openSectionKey, onValidChange, parseAddress, }: {
92
122
  openSection?: string;
93
123
  openSectionKey?: number;
94
124
  onValidChange?: (valid: boolean) => void;
125
+ parseAddress?: (addressLine: string) => Promise<IParsedAddress>;
95
126
  }) => react_jsx_runtime.JSX.Element;
96
127
 
97
- declare const LifePlanApplicationStepWrapper: () => react_jsx_runtime.JSX.Element;
128
+ interface CartItem {
129
+ planDesc: string;
130
+ mode: string;
131
+ planTerm: string;
132
+ quantity: number;
133
+ price: number;
134
+ total: number;
135
+ contractPrice: number;
136
+ ipInstAmt?: number;
137
+ balance?: number;
138
+ }
98
139
 
140
+ type NewSalesCheckoutItem = {
141
+ planDesc: CartItem["planDesc"];
142
+ mode: CartItem["mode"];
143
+ ipInstAmt: number;
144
+ planTerm: CartItem["planTerm"];
145
+ quantity: number;
146
+ };
147
+ type NewSalesCheckoutRequest = {
148
+ items: NewSalesCheckoutItem[];
149
+ application: IApplicationData;
150
+ };
99
151
  type SharedLifePlanApplicationProps = {
100
152
  title?: string;
101
153
  description?: string;
102
154
  onPaymentError?: (error: unknown) => void;
155
+ /**
156
+ * Called on the payment step with the cart items and application data.
157
+ * Must return the checkout URL (e.g. from PayMongoService.createNewSalesCheckout).
158
+ */
159
+ onCheckout?: (request: NewSalesCheckoutRequest) => Promise<string | undefined>;
160
+ /** Optional address parser used to fill the address form from the scanned ID. */
161
+ parseAddress?: (addressLine: string) => Promise<IParsedAddress>;
103
162
  };
104
- declare const SharedLifePlanApplication: ({ title, description, onPaymentError, }: SharedLifePlanApplicationProps) => react_jsx_runtime.JSX.Element;
163
+ declare const SharedLifePlanApplication: ({ title, description, onPaymentError, onCheckout, parseAddress, }: SharedLifePlanApplicationProps) => react_jsx_runtime.JSX.Element;
164
+
165
+ declare const LifePlanApplicationStepWrapper: (props: SharedLifePlanApplicationProps) => react_jsx_runtime.JSX.Element;
166
+
167
+ declare const OCR_STORAGE_KEY = "ocrResult";
168
+ type OcrSection = "personal" | "address";
169
+ /** Returns the saved OCR result if it has not been applied to this section yet. */
170
+ declare const readOcrResult: (section: OcrSection) => IOcrValue | null;
171
+ /** Marks the OCR result as used for this section. Returns true the first time only. */
172
+ declare const markOcrApplied: (section: OcrSection) => boolean;
105
173
 
106
174
  type QuickAction = {
107
175
  /** React Icons icon component */
@@ -185,20 +253,8 @@ interface ReusableProfileProps {
185
253
  }
186
254
  declare function ReusableProfile({ user, colorMode: controlledColorMode, onColorModeChange, initialTwoFactorEnabled, initialQuickNavHrefs, availableNavOptions, maxQuickNavItems, enableLocalStorage, storageKey, onSaveAccount, onChangePassword, onSignOut, onTwoFactorChange, onToast, }: ReusableProfileProps): react_jsx_runtime.JSX.Element;
187
255
 
188
- interface CartItem {
189
- planDesc: string;
190
- mode: string;
191
- planTerm: string;
192
- quantity: number;
193
- price: number;
194
- total: number;
195
- contractPrice: number;
196
- ipInstAmt?: number;
197
- balance?: number;
198
- }
199
-
200
256
  declare const createEmptyApplicationData: () => IApplicationData;
201
257
  declare const loadApplicationDataFromLocalStorage: (storageKey?: string) => IApplicationData | null;
202
258
  declare const saveApplicationDataToLocalStorage: (data: IApplicationData, storageKey?: string) => void;
203
259
 
204
- export { Beneficiary, type BeneficiaryClass, BottomQuickActions, type CartItem, HealthDeclaration, type IAddress, type IApplicationData, type IBeneficiary, type IEmployment, type IHealthDeclaration, type IPersonalInfo, type ITransactionData, LifePlanApplication1, LifePlanApplication2, LifePlanApplication3, LifePlanApplicationFormWrapper, LifePlanApplicationStepWrapper, type NavOptionDef, NotifyInstall, type ProfileUser, type ReusableProfileProps, SharedLifePlanApplication, ReusableProfile as UserProfile, createEmptyApplicationData, loadApplicationDataFromLocalStorage, saveApplicationDataToLocalStorage };
260
+ export { Beneficiary, type BeneficiaryClass, BottomQuickActions, type CartItem, HealthDeclaration, type IAddress, type IApplicationData, type IBeneficiary, type IEmployment, type IHealthDeclaration, type IOcrValue, type IParsedAddress, type IPersonalInfo, type ITransactionData, LifePlanApplication1, LifePlanApplication2, LifePlanApplication3, LifePlanApplicationFormWrapper, LifePlanApplicationStepWrapper, type NavOptionDef, type NewSalesCheckoutItem, type NewSalesCheckoutRequest, NotifyInstall, OCR_STORAGE_KEY, type OcrSection, type ProfileUser, type ReusableProfileProps, SharedLifePlanApplication, type SharedLifePlanApplicationProps, ReusableProfile as UserProfile, createEmptyApplicationData, loadApplicationDataFromLocalStorage, markOcrApplied, readOcrResult, saveApplicationDataToLocalStorage };
package/dist/index.js CHANGED
@@ -39,10 +39,13 @@ __export(index_exports, {
39
39
  LifePlanApplicationFormWrapper: () => LifePlanApplicationFormWrapper_default,
40
40
  LifePlanApplicationStepWrapper: () => LifePlanApplicationStepWrapper_default,
41
41
  NotifyInstall: () => NotifyInstall,
42
+ OCR_STORAGE_KEY: () => OCR_STORAGE_KEY,
42
43
  SharedLifePlanApplication: () => SharedLifePlanApplication_default,
43
44
  UserProfile: () => UserProfile_default,
44
45
  createEmptyApplicationData: () => createEmptyApplicationData,
45
46
  loadApplicationDataFromLocalStorage: () => loadApplicationDataFromLocalStorage,
47
+ markOcrApplied: () => markOcrApplied,
48
+ readOcrResult: () => readOcrResult,
46
49
  saveApplicationDataToLocalStorage: () => saveApplicationDataToLocalStorage
47
50
  });
48
51
  module.exports = __toCommonJS(index_exports);
@@ -269,6 +272,37 @@ var STANDARD_ICON_BUTTON_STYLES = {
269
272
  }
270
273
  };
271
274
 
275
+ // src/hooks/ocrStorage.ts
276
+ var OCR_STORAGE_KEY = "ocrResult";
277
+ var readStored = () => {
278
+ try {
279
+ const raw = localStorage.getItem(OCR_STORAGE_KEY);
280
+ return raw ? JSON.parse(raw) : null;
281
+ } catch {
282
+ return null;
283
+ }
284
+ };
285
+ var readOcrResult = (section) => {
286
+ if (typeof window === "undefined") return null;
287
+ const stored = readStored();
288
+ if (!stored || stored.applied?.[section]) return null;
289
+ return stored;
290
+ };
291
+ var markOcrApplied = (section) => {
292
+ if (typeof window === "undefined") return false;
293
+ const stored = readStored();
294
+ if (!stored || stored.applied?.[section]) return false;
295
+ try {
296
+ localStorage.setItem(
297
+ OCR_STORAGE_KEY,
298
+ JSON.stringify({ ...stored, applied: { ...stored.applied, [section]: true } })
299
+ );
300
+ } catch {
301
+ return false;
302
+ }
303
+ return true;
304
+ };
305
+
272
306
  // src/NewSaleForm/LifePlanApplication1.tsx
273
307
  var import_react4 = require("react");
274
308
 
@@ -366,11 +400,20 @@ var civilStatusCollection = (0, import_react3.createListCollection)({
366
400
  { label: "Annulled", value: "annulled" }
367
401
  ]
368
402
  });
403
+ var applyOcr = (data, ocr) => ocr ? {
404
+ ...data,
405
+ firstName: ocr.firstName || data.firstName || "",
406
+ middleName: ocr.middleName || data.middleName || "",
407
+ lastName: ocr.lastName || data.lastName || "",
408
+ birthDate: ocr.birthDate || data.birthDate || "",
409
+ idType: ocr.idType || data.idType || "",
410
+ idNumber: ocr.idNumber || data.idNumber || ""
411
+ } : data;
369
412
  var LifePlanApplication1 = ({
370
413
  initialData,
371
414
  onUpdate
372
415
  }) => {
373
- const [formData, setFormData] = (0, import_react4.useState)({
416
+ const [formData, setFormData] = (0, import_react4.useState)(() => applyOcr({
374
417
  firstName: initialData?.firstName ?? "Juan",
375
418
  middleName: initialData?.middleName ?? "Santos",
376
419
  lastName: initialData?.lastName ?? "Dela Cruz",
@@ -387,49 +430,14 @@ var LifePlanApplication1 = ({
387
430
  emailAddress: initialData?.emailAddress ?? "juan.delacruz@example.com",
388
431
  mailingAddress: initialData?.mailingAddress ?? "123 Mabini Street, Barangay San Antonio, Makati City",
389
432
  landLineNumber: initialData?.landLineNumber ?? "02-8123-4567"
390
- });
433
+ }, readOcrResult("personal")));
391
434
  const updateFormData = (nextData) => {
392
435
  setFormData(nextData);
393
436
  onUpdate?.(nextData);
394
437
  };
395
438
  (0, import_react4.useEffect)(() => {
396
- const OCRValue = typeof window === "undefined" ? null : localStorage.getItem("ocrResult");
397
- if (OCRValue != null) {
398
- try {
399
- const ocrData = JSON.parse(OCRValue);
400
- let formattedBirthDate = "";
401
- if (typeof ocrData?.birthDate === "string") {
402
- const [month, day, year] = ocrData.birthDate.split("/").map((part) => part.trim());
403
- if (month && day && year) {
404
- formattedBirthDate = `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
405
- }
406
- }
407
- let mappedIdType = "";
408
- if (ocrData?.idType) {
409
- const normalizedIdType = ocrData.idType.toLowerCase().replace(/\s+/g, "_").replace(/'/g, "");
410
- if (normalizedIdType.includes("passport")) {
411
- mappedIdType = "passport";
412
- } else if (normalizedIdType.includes("driver")) {
413
- mappedIdType = "driver_license";
414
- } else if (normalizedIdType.includes("national") || normalizedIdType.includes("id")) {
415
- mappedIdType = "national_id";
416
- }
417
- }
418
- const updatedData = {
419
- ...formData,
420
- firstName: ocrData?.firstName || "",
421
- lastName: ocrData?.lastName || "",
422
- middleName: ocrData?.middleName || "",
423
- birthDate: formattedBirthDate || "",
424
- idType: mappedIdType || ""
425
- };
426
- updateFormData(updatedData);
427
- } catch (e) {
428
- console.error("Failed to parse OCR value:", e);
429
- localStorage.removeItem("ocrResult");
430
- }
431
- }
432
- }, []);
439
+ if (markOcrApplied("personal")) onUpdate?.(formData);
440
+ }, [formData, onUpdate]);
433
441
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
434
442
  import_react3.Grid,
435
443
  {
@@ -878,22 +886,45 @@ var cityOptions = [
878
886
  "Bongao",
879
887
  "Ipil"
880
888
  ].map((city) => ({ label: city, value: city }));
881
- var districtOptions = cityOptions;
882
- var barangayOptions = cityOptions;
883
889
  var provinceCollection = (0, import_react5.createListCollection)({ items: provinceOptions });
884
890
  var cityCollection = (0, import_react5.createListCollection)({ items: cityOptions });
885
- var districtCollection = (0, import_react5.createListCollection)({ items: districtOptions });
886
- var barangayCollection = (0, import_react5.createListCollection)({ items: barangayOptions });
891
+ var normalizePlace = (value) => value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/^city of\s+/, "").replace(/\s+city$/, "").replace(/[^a-z0-9]/g, "");
892
+ var matchOption = (candidates, options) => {
893
+ for (const candidate of candidates ?? []) {
894
+ const key = normalizePlace(candidate);
895
+ const match = options.find(
896
+ (option) => normalizePlace(option.value) === key
897
+ );
898
+ if (match) return match.value;
899
+ }
900
+ return "";
901
+ };
887
902
  var LifePlanApplication2 = ({
888
- onAddressUpdate
903
+ onAddressUpdate,
904
+ parseAddress
889
905
  }) => {
890
- const OCRValue = typeof window === "undefined" ? null : localStorage.getItem("ocrResult");
891
- const [lot, setLot] = (0, import_react6.useState)("123");
892
- const [street, setStreet] = (0, import_react6.useState)("Mabini Street");
893
- const [city, setCity] = (0, import_react6.useState)("Makati");
894
- const [province, setProvince] = (0, import_react6.useState)("Metro Manila");
895
- const [district, setDistrict] = (0, import_react6.useState)("Taguig");
896
- const [barangay, setBarangay] = (0, import_react6.useState)("San Juan");
906
+ const [lot, setLot] = (0, import_react6.useState)("");
907
+ const [street, setStreet] = (0, import_react6.useState)("");
908
+ const [city, setCity] = (0, import_react6.useState)("");
909
+ const [province, setProvince] = (0, import_react6.useState)("");
910
+ const [district, setDistrict] = (0, import_react6.useState)("");
911
+ const [barangay, setBarangay] = (0, import_react6.useState)("");
912
+ (0, import_react6.useEffect)(() => {
913
+ if (!parseAddress) return;
914
+ const ocr = readOcrResult("address");
915
+ if (!ocr?.addressLine) return;
916
+ markOcrApplied("address");
917
+ parseAddress(ocr.addressLine).then((result) => {
918
+ setLot(result.lot ?? "");
919
+ setStreet(result.street ?? "");
920
+ setProvince(matchOption(result.provinceCandidates, provinceOptions));
921
+ setCity(matchOption(result.cityCandidates, cityOptions));
922
+ setDistrict(result.district ?? "");
923
+ setBarangay(result.barangay ?? "");
924
+ }).catch((error) => {
925
+ console.error("Error parsing address:", error);
926
+ });
927
+ }, [parseAddress]);
897
928
  (0, import_react6.useEffect)(() => {
898
929
  onAddressUpdate?.({
899
930
  lot,
@@ -949,44 +980,22 @@ var LifePlanApplication2 = ({
949
980
  ]
950
981
  }
951
982
  ) }),
952
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Field.Root, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
953
- import_react5.Select.Root,
983
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Field.Root, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
984
+ FloatingLabelInput,
954
985
  {
955
- value: [district],
956
- onValueChange: (e) => setDistrict(e.value[0] ?? ""),
957
- collection: districtCollection,
958
- width: "100%",
959
- children: [
960
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.HiddenSelect, {}),
961
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react5.Select.Control, { children: [
962
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.ValueText, { placeholder: "Select District" }) }),
963
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.IndicatorGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Indicator, {}) })
964
- ] }),
965
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Content, { children: districtOptions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react5.Select.Item, { item, children: [
966
- item.label,
967
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.ItemIndicator, {})
968
- ] }, item.value)) }) }) })
969
- ]
986
+ id: "district",
987
+ label: "District",
988
+ value: district,
989
+ onChange: (e) => setDistrict(e.target.value)
970
990
  }
971
991
  ) }),
972
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Field.Root, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
973
- import_react5.Select.Root,
992
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Field.Root, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
993
+ FloatingLabelInput,
974
994
  {
975
- value: [barangay],
976
- onValueChange: (e) => setBarangay(e.value[0] ?? ""),
977
- collection: barangayCollection,
978
- width: "100%",
979
- children: [
980
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.HiddenSelect, {}),
981
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react5.Select.Control, { children: [
982
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.ValueText, { placeholder: "Select Barangay" }) }),
983
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.IndicatorGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Indicator, {}) })
984
- ] }),
985
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Positioner, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.Content, { children: barangayOptions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react5.Select.Item, { item, children: [
986
- item.label,
987
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Select.ItemIndicator, {})
988
- ] }, item.value)) }) }) })
989
- ]
995
+ id: "barangay",
996
+ label: "Barangay",
997
+ value: barangay,
998
+ onChange: (e) => setBarangay(e.target.value)
990
999
  }
991
1000
  ) }),
992
1001
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react5.Field.Root, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -2260,7 +2269,8 @@ var isEmploymentComplete = (e) => !!e && [
2260
2269
  var LifePlanApplicationFormWrapper = ({
2261
2270
  openSection,
2262
2271
  openSectionKey,
2263
- onValidChange
2272
+ onValidChange,
2273
+ parseAddress
2264
2274
  }) => {
2265
2275
  const [applicationData, setApplicationData] = (0, import_react18.useState)(
2266
2276
  createEmptyApplicationData
@@ -2335,7 +2345,13 @@ var LifePlanApplicationFormWrapper = ({
2335
2345
  description: "Where you currently live",
2336
2346
  value: "address",
2337
2347
  complete: isAddressComplete(applicationData.address),
2338
- page: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LifePlanApplication2_default, { onAddressUpdate: handleAddressUpdate })
2348
+ page: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2349
+ LifePlanApplication2_default,
2350
+ {
2351
+ onAddressUpdate: handleAddressUpdate,
2352
+ ...parseAddress ? { parseAddress } : {}
2353
+ }
2354
+ )
2339
2355
  },
2340
2356
  {
2341
2357
  icon: import_io.IoIosInformationCircleOutline,
@@ -3076,6 +3092,9 @@ var createLifePlanSteps = (confirmationProps) => [
3076
3092
  if (confirmationProps?.onApplicationValidChange !== void 0) {
3077
3093
  applicationFormWrapperProps.onValidChange = confirmationProps.onApplicationValidChange;
3078
3094
  }
3095
+ if (confirmationProps?.parseAddress !== void 0) {
3096
+ applicationFormWrapperProps.parseAddress = confirmationProps.parseAddress;
3097
+ }
3079
3098
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LifePlanApplicationFormWrapper_default, { ...applicationFormWrapperProps });
3080
3099
  })()
3081
3100
  },
@@ -3459,10 +3478,20 @@ var horizontal_stepper_default = HorizontalStepper;
3459
3478
 
3460
3479
  // src/NewSaleForm/SharedLifePlanApplication.tsx
3461
3480
  var import_jsx_runtime16 = require("react/jsx-runtime");
3481
+ var safeParse = (value) => {
3482
+ if (!value) return null;
3483
+ try {
3484
+ return JSON.parse(value);
3485
+ } catch {
3486
+ return null;
3487
+ }
3488
+ };
3462
3489
  var SharedLifePlanApplication = ({
3463
3490
  title = "Life Plan Application",
3464
3491
  description = "Please fill out the form below to apply for a life plan.",
3465
- onPaymentError
3492
+ onPaymentError,
3493
+ onCheckout,
3494
+ parseAddress
3466
3495
  }) => {
3467
3496
  const [currentStep, setCurrentStep] = (0, import_react27.useState)(0);
3468
3497
  const [loading, setLoading] = (0, import_react27.useState)(false);
@@ -3475,6 +3504,7 @@ var SharedLifePlanApplication = ({
3475
3504
  ...applicationSection ? { applicationSection } : {},
3476
3505
  applicationSectionKey,
3477
3506
  onApplicationValidChange: setApplicationValid,
3507
+ ...parseAddress ? { parseAddress } : {},
3478
3508
  onEdit: (section) => {
3479
3509
  setApplicationSection(section ?? "personal");
3480
3510
  setApplicationSectionKey((key) => key + 1);
@@ -3485,6 +3515,38 @@ var SharedLifePlanApplication = ({
3485
3515
  const handleCheckout = async () => {
3486
3516
  if (!allAgreementsAccepted) return;
3487
3517
  setLoading(true);
3518
+ try {
3519
+ if (!onCheckout) {
3520
+ throw new Error("onCheckout prop is not provided");
3521
+ }
3522
+ const checkoutRaw = sessionStorage.getItem("CheckoutCart");
3523
+ const cartRaw = sessionStorage.getItem("Cart");
3524
+ const parsed = safeParse(checkoutRaw) ?? safeParse(cartRaw);
3525
+ const items = Array.isArray(parsed) ? parsed : parsed ? [parsed] : [];
3526
+ if (items.length === 0) {
3527
+ throw new Error("No items to checkout");
3528
+ }
3529
+ const applicationData = loadApplicationDataFromLocalStorage() ?? createEmptyApplicationData();
3530
+ const checkoutPayload = items.map((item) => ({
3531
+ planDesc: item.planDesc,
3532
+ mode: item.mode,
3533
+ ipInstAmt: Number(item.price),
3534
+ planTerm: item.planTerm,
3535
+ quantity: item.quantity ?? 1
3536
+ }));
3537
+ const checkoutUrl = await onCheckout({
3538
+ items: checkoutPayload,
3539
+ application: applicationData
3540
+ });
3541
+ if (!checkoutUrl) throw new Error("Checkout URL not found");
3542
+ window.location.href = checkoutUrl;
3543
+ } catch (error) {
3544
+ console.error(error);
3545
+ onPaymentError?.(error);
3546
+ alert("Failed to proceed to payment");
3547
+ } finally {
3548
+ setLoading(false);
3549
+ }
3488
3550
  };
3489
3551
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react26.Box, { w: "full", overflowX: "hidden", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3490
3552
  horizontal_stepper_default,
@@ -3502,8 +3564,8 @@ var SharedLifePlanApplication_default = SharedLifePlanApplication;
3502
3564
 
3503
3565
  // src/NewSaleForm/LifePlanApplicationStepWrapper.tsx
3504
3566
  var import_jsx_runtime17 = require("react/jsx-runtime");
3505
- var LifePlanApplicationStepWrapper = () => {
3506
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SharedLifePlanApplication_default, {});
3567
+ var LifePlanApplicationStepWrapper = (props) => {
3568
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SharedLifePlanApplication_default, { ...props });
3507
3569
  };
3508
3570
  var LifePlanApplicationStepWrapper_default = LifePlanApplicationStepWrapper;
3509
3571
 
@@ -5475,10 +5537,13 @@ var UserProfile_default = ReusableProfile;
5475
5537
  LifePlanApplicationFormWrapper,
5476
5538
  LifePlanApplicationStepWrapper,
5477
5539
  NotifyInstall,
5540
+ OCR_STORAGE_KEY,
5478
5541
  SharedLifePlanApplication,
5479
5542
  UserProfile,
5480
5543
  createEmptyApplicationData,
5481
5544
  loadApplicationDataFromLocalStorage,
5545
+ markOcrApplied,
5546
+ readOcrResult,
5482
5547
  saveApplicationDataToLocalStorage
5483
5548
  });
5484
5549
  //# sourceMappingURL=index.js.map