@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.mjs CHANGED
@@ -226,6 +226,37 @@ var STANDARD_ICON_BUTTON_STYLES = {
226
226
  }
227
227
  };
228
228
 
229
+ // src/hooks/ocrStorage.ts
230
+ var OCR_STORAGE_KEY = "ocrResult";
231
+ var readStored = () => {
232
+ try {
233
+ const raw = localStorage.getItem(OCR_STORAGE_KEY);
234
+ return raw ? JSON.parse(raw) : null;
235
+ } catch {
236
+ return null;
237
+ }
238
+ };
239
+ var readOcrResult = (section) => {
240
+ if (typeof window === "undefined") return null;
241
+ const stored = readStored();
242
+ if (!stored || stored.applied?.[section]) return null;
243
+ return stored;
244
+ };
245
+ var markOcrApplied = (section) => {
246
+ if (typeof window === "undefined") return false;
247
+ const stored = readStored();
248
+ if (!stored || stored.applied?.[section]) return false;
249
+ try {
250
+ localStorage.setItem(
251
+ OCR_STORAGE_KEY,
252
+ JSON.stringify({ ...stored, applied: { ...stored.applied, [section]: true } })
253
+ );
254
+ } catch {
255
+ return false;
256
+ }
257
+ return true;
258
+ };
259
+
229
260
  // src/NewSaleForm/LifePlanApplication1.tsx
230
261
  import { useEffect, useState as useState2 } from "react";
231
262
 
@@ -329,11 +360,20 @@ var civilStatusCollection = createListCollection({
329
360
  { label: "Annulled", value: "annulled" }
330
361
  ]
331
362
  });
363
+ var applyOcr = (data, ocr) => ocr ? {
364
+ ...data,
365
+ firstName: ocr.firstName || data.firstName || "",
366
+ middleName: ocr.middleName || data.middleName || "",
367
+ lastName: ocr.lastName || data.lastName || "",
368
+ birthDate: ocr.birthDate || data.birthDate || "",
369
+ idType: ocr.idType || data.idType || "",
370
+ idNumber: ocr.idNumber || data.idNumber || ""
371
+ } : data;
332
372
  var LifePlanApplication1 = ({
333
373
  initialData,
334
374
  onUpdate
335
375
  }) => {
336
- const [formData, setFormData] = useState2({
376
+ const [formData, setFormData] = useState2(() => applyOcr({
337
377
  firstName: initialData?.firstName ?? "Juan",
338
378
  middleName: initialData?.middleName ?? "Santos",
339
379
  lastName: initialData?.lastName ?? "Dela Cruz",
@@ -350,49 +390,14 @@ var LifePlanApplication1 = ({
350
390
  emailAddress: initialData?.emailAddress ?? "juan.delacruz@example.com",
351
391
  mailingAddress: initialData?.mailingAddress ?? "123 Mabini Street, Barangay San Antonio, Makati City",
352
392
  landLineNumber: initialData?.landLineNumber ?? "02-8123-4567"
353
- });
393
+ }, readOcrResult("personal")));
354
394
  const updateFormData = (nextData) => {
355
395
  setFormData(nextData);
356
396
  onUpdate?.(nextData);
357
397
  };
358
398
  useEffect(() => {
359
- const OCRValue = typeof window === "undefined" ? null : localStorage.getItem("ocrResult");
360
- if (OCRValue != null) {
361
- try {
362
- const ocrData = JSON.parse(OCRValue);
363
- let formattedBirthDate = "";
364
- if (typeof ocrData?.birthDate === "string") {
365
- const [month, day, year] = ocrData.birthDate.split("/").map((part) => part.trim());
366
- if (month && day && year) {
367
- formattedBirthDate = `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
368
- }
369
- }
370
- let mappedIdType = "";
371
- if (ocrData?.idType) {
372
- const normalizedIdType = ocrData.idType.toLowerCase().replace(/\s+/g, "_").replace(/'/g, "");
373
- if (normalizedIdType.includes("passport")) {
374
- mappedIdType = "passport";
375
- } else if (normalizedIdType.includes("driver")) {
376
- mappedIdType = "driver_license";
377
- } else if (normalizedIdType.includes("national") || normalizedIdType.includes("id")) {
378
- mappedIdType = "national_id";
379
- }
380
- }
381
- const updatedData = {
382
- ...formData,
383
- firstName: ocrData?.firstName || "",
384
- lastName: ocrData?.lastName || "",
385
- middleName: ocrData?.middleName || "",
386
- birthDate: formattedBirthDate || "",
387
- idType: mappedIdType || ""
388
- };
389
- updateFormData(updatedData);
390
- } catch (e) {
391
- console.error("Failed to parse OCR value:", e);
392
- localStorage.removeItem("ocrResult");
393
- }
394
- }
395
- }, []);
399
+ if (markOcrApplied("personal")) onUpdate?.(formData);
400
+ }, [formData, onUpdate]);
396
401
  return /* @__PURE__ */ jsxs2(
397
402
  Grid,
398
403
  {
@@ -849,22 +854,45 @@ var cityOptions = [
849
854
  "Bongao",
850
855
  "Ipil"
851
856
  ].map((city) => ({ label: city, value: city }));
852
- var districtOptions = cityOptions;
853
- var barangayOptions = cityOptions;
854
857
  var provinceCollection = createListCollection2({ items: provinceOptions });
855
858
  var cityCollection = createListCollection2({ items: cityOptions });
856
- var districtCollection = createListCollection2({ items: districtOptions });
857
- var barangayCollection = createListCollection2({ items: barangayOptions });
859
+ var normalizePlace = (value) => value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/^city of\s+/, "").replace(/\s+city$/, "").replace(/[^a-z0-9]/g, "");
860
+ var matchOption = (candidates, options) => {
861
+ for (const candidate of candidates ?? []) {
862
+ const key = normalizePlace(candidate);
863
+ const match = options.find(
864
+ (option) => normalizePlace(option.value) === key
865
+ );
866
+ if (match) return match.value;
867
+ }
868
+ return "";
869
+ };
858
870
  var LifePlanApplication2 = ({
859
- onAddressUpdate
871
+ onAddressUpdate,
872
+ parseAddress
860
873
  }) => {
861
- const OCRValue = typeof window === "undefined" ? null : localStorage.getItem("ocrResult");
862
- const [lot, setLot] = useState3("123");
863
- const [street, setStreet] = useState3("Mabini Street");
864
- const [city, setCity] = useState3("Makati");
865
- const [province, setProvince] = useState3("Metro Manila");
866
- const [district, setDistrict] = useState3("Taguig");
867
- const [barangay, setBarangay] = useState3("San Juan");
874
+ const [lot, setLot] = useState3("");
875
+ const [street, setStreet] = useState3("");
876
+ const [city, setCity] = useState3("");
877
+ const [province, setProvince] = useState3("");
878
+ const [district, setDistrict] = useState3("");
879
+ const [barangay, setBarangay] = useState3("");
880
+ useEffect2(() => {
881
+ if (!parseAddress) return;
882
+ const ocr = readOcrResult("address");
883
+ if (!ocr?.addressLine) return;
884
+ markOcrApplied("address");
885
+ parseAddress(ocr.addressLine).then((result) => {
886
+ setLot(result.lot ?? "");
887
+ setStreet(result.street ?? "");
888
+ setProvince(matchOption(result.provinceCandidates, provinceOptions));
889
+ setCity(matchOption(result.cityCandidates, cityOptions));
890
+ setDistrict(result.district ?? "");
891
+ setBarangay(result.barangay ?? "");
892
+ }).catch((error) => {
893
+ console.error("Error parsing address:", error);
894
+ });
895
+ }, [parseAddress]);
868
896
  useEffect2(() => {
869
897
  onAddressUpdate?.({
870
898
  lot,
@@ -920,44 +948,22 @@ var LifePlanApplication2 = ({
920
948
  ]
921
949
  }
922
950
  ) }),
923
- /* @__PURE__ */ jsx3(Field3.Root, { children: /* @__PURE__ */ jsxs3(
924
- Select2.Root,
951
+ /* @__PURE__ */ jsx3(Field3.Root, { children: /* @__PURE__ */ jsx3(
952
+ FloatingLabelInput,
925
953
  {
926
- value: [district],
927
- onValueChange: (e) => setDistrict(e.value[0] ?? ""),
928
- collection: districtCollection,
929
- width: "100%",
930
- children: [
931
- /* @__PURE__ */ jsx3(Select2.HiddenSelect, {}),
932
- /* @__PURE__ */ jsxs3(Select2.Control, { children: [
933
- /* @__PURE__ */ jsx3(Select2.Trigger, { children: /* @__PURE__ */ jsx3(Select2.ValueText, { placeholder: "Select District" }) }),
934
- /* @__PURE__ */ jsx3(Select2.IndicatorGroup, { children: /* @__PURE__ */ jsx3(Select2.Indicator, {}) })
935
- ] }),
936
- /* @__PURE__ */ jsx3(Portal, { children: /* @__PURE__ */ jsx3(Select2.Positioner, { children: /* @__PURE__ */ jsx3(Select2.Content, { children: districtOptions.map((item) => /* @__PURE__ */ jsxs3(Select2.Item, { item, children: [
937
- item.label,
938
- /* @__PURE__ */ jsx3(Select2.ItemIndicator, {})
939
- ] }, item.value)) }) }) })
940
- ]
954
+ id: "district",
955
+ label: "District",
956
+ value: district,
957
+ onChange: (e) => setDistrict(e.target.value)
941
958
  }
942
959
  ) }),
943
- /* @__PURE__ */ jsx3(Field3.Root, { children: /* @__PURE__ */ jsxs3(
944
- Select2.Root,
960
+ /* @__PURE__ */ jsx3(Field3.Root, { children: /* @__PURE__ */ jsx3(
961
+ FloatingLabelInput,
945
962
  {
946
- value: [barangay],
947
- onValueChange: (e) => setBarangay(e.value[0] ?? ""),
948
- collection: barangayCollection,
949
- width: "100%",
950
- children: [
951
- /* @__PURE__ */ jsx3(Select2.HiddenSelect, {}),
952
- /* @__PURE__ */ jsxs3(Select2.Control, { children: [
953
- /* @__PURE__ */ jsx3(Select2.Trigger, { children: /* @__PURE__ */ jsx3(Select2.ValueText, { placeholder: "Select Barangay" }) }),
954
- /* @__PURE__ */ jsx3(Select2.IndicatorGroup, { children: /* @__PURE__ */ jsx3(Select2.Indicator, {}) })
955
- ] }),
956
- /* @__PURE__ */ jsx3(Portal, { children: /* @__PURE__ */ jsx3(Select2.Positioner, { children: /* @__PURE__ */ jsx3(Select2.Content, { children: barangayOptions.map((item) => /* @__PURE__ */ jsxs3(Select2.Item, { item, children: [
957
- item.label,
958
- /* @__PURE__ */ jsx3(Select2.ItemIndicator, {})
959
- ] }, item.value)) }) }) })
960
- ]
963
+ id: "barangay",
964
+ label: "Barangay",
965
+ value: barangay,
966
+ onChange: (e) => setBarangay(e.target.value)
961
967
  }
962
968
  ) }),
963
969
  /* @__PURE__ */ jsx3(Field3.Root, { children: /* @__PURE__ */ jsx3(
@@ -2261,7 +2267,8 @@ var isEmploymentComplete = (e) => !!e && [
2261
2267
  var LifePlanApplicationFormWrapper = ({
2262
2268
  openSection,
2263
2269
  openSectionKey,
2264
- onValidChange
2270
+ onValidChange,
2271
+ parseAddress
2265
2272
  }) => {
2266
2273
  const [applicationData, setApplicationData] = useState7(
2267
2274
  createEmptyApplicationData
@@ -2336,7 +2343,13 @@ var LifePlanApplicationFormWrapper = ({
2336
2343
  description: "Where you currently live",
2337
2344
  value: "address",
2338
2345
  complete: isAddressComplete(applicationData.address),
2339
- page: /* @__PURE__ */ jsx10(LifePlanApplication2_default, { onAddressUpdate: handleAddressUpdate })
2346
+ page: /* @__PURE__ */ jsx10(
2347
+ LifePlanApplication2_default,
2348
+ {
2349
+ onAddressUpdate: handleAddressUpdate,
2350
+ ...parseAddress ? { parseAddress } : {}
2351
+ }
2352
+ )
2340
2353
  },
2341
2354
  {
2342
2355
  icon: IoIosInformationCircleOutline,
@@ -3091,6 +3104,9 @@ var createLifePlanSteps = (confirmationProps) => [
3091
3104
  if (confirmationProps?.onApplicationValidChange !== void 0) {
3092
3105
  applicationFormWrapperProps.onValidChange = confirmationProps.onApplicationValidChange;
3093
3106
  }
3107
+ if (confirmationProps?.parseAddress !== void 0) {
3108
+ applicationFormWrapperProps.parseAddress = confirmationProps.parseAddress;
3109
+ }
3094
3110
  return /* @__PURE__ */ jsx14(LifePlanApplicationFormWrapper_default, { ...applicationFormWrapperProps });
3095
3111
  })()
3096
3112
  },
@@ -3474,10 +3490,20 @@ var horizontal_stepper_default = HorizontalStepper;
3474
3490
 
3475
3491
  // src/NewSaleForm/SharedLifePlanApplication.tsx
3476
3492
  import { jsx as jsx16 } from "react/jsx-runtime";
3493
+ var safeParse = (value) => {
3494
+ if (!value) return null;
3495
+ try {
3496
+ return JSON.parse(value);
3497
+ } catch {
3498
+ return null;
3499
+ }
3500
+ };
3477
3501
  var SharedLifePlanApplication = ({
3478
3502
  title = "Life Plan Application",
3479
3503
  description = "Please fill out the form below to apply for a life plan.",
3480
- onPaymentError
3504
+ onPaymentError,
3505
+ onCheckout,
3506
+ parseAddress
3481
3507
  }) => {
3482
3508
  const [currentStep, setCurrentStep] = useState11(0);
3483
3509
  const [loading, setLoading] = useState11(false);
@@ -3490,6 +3516,7 @@ var SharedLifePlanApplication = ({
3490
3516
  ...applicationSection ? { applicationSection } : {},
3491
3517
  applicationSectionKey,
3492
3518
  onApplicationValidChange: setApplicationValid,
3519
+ ...parseAddress ? { parseAddress } : {},
3493
3520
  onEdit: (section) => {
3494
3521
  setApplicationSection(section ?? "personal");
3495
3522
  setApplicationSectionKey((key) => key + 1);
@@ -3500,6 +3527,38 @@ var SharedLifePlanApplication = ({
3500
3527
  const handleCheckout = async () => {
3501
3528
  if (!allAgreementsAccepted) return;
3502
3529
  setLoading(true);
3530
+ try {
3531
+ if (!onCheckout) {
3532
+ throw new Error("onCheckout prop is not provided");
3533
+ }
3534
+ const checkoutRaw = sessionStorage.getItem("CheckoutCart");
3535
+ const cartRaw = sessionStorage.getItem("Cart");
3536
+ const parsed = safeParse(checkoutRaw) ?? safeParse(cartRaw);
3537
+ const items = Array.isArray(parsed) ? parsed : parsed ? [parsed] : [];
3538
+ if (items.length === 0) {
3539
+ throw new Error("No items to checkout");
3540
+ }
3541
+ const applicationData = loadApplicationDataFromLocalStorage() ?? createEmptyApplicationData();
3542
+ const checkoutPayload = items.map((item) => ({
3543
+ planDesc: item.planDesc,
3544
+ mode: item.mode,
3545
+ ipInstAmt: Number(item.price),
3546
+ planTerm: item.planTerm,
3547
+ quantity: item.quantity ?? 1
3548
+ }));
3549
+ const checkoutUrl = await onCheckout({
3550
+ items: checkoutPayload,
3551
+ application: applicationData
3552
+ });
3553
+ if (!checkoutUrl) throw new Error("Checkout URL not found");
3554
+ window.location.href = checkoutUrl;
3555
+ } catch (error) {
3556
+ console.error(error);
3557
+ onPaymentError?.(error);
3558
+ alert("Failed to proceed to payment");
3559
+ } finally {
3560
+ setLoading(false);
3561
+ }
3503
3562
  };
3504
3563
  return /* @__PURE__ */ jsx16(Box14, { w: "full", overflowX: "hidden", children: /* @__PURE__ */ jsx16(
3505
3564
  horizontal_stepper_default,
@@ -3517,8 +3576,8 @@ var SharedLifePlanApplication_default = SharedLifePlanApplication;
3517
3576
 
3518
3577
  // src/NewSaleForm/LifePlanApplicationStepWrapper.tsx
3519
3578
  import { jsx as jsx17 } from "react/jsx-runtime";
3520
- var LifePlanApplicationStepWrapper = () => {
3521
- return /* @__PURE__ */ jsx17(SharedLifePlanApplication_default, {});
3579
+ var LifePlanApplicationStepWrapper = (props) => {
3580
+ return /* @__PURE__ */ jsx17(SharedLifePlanApplication_default, { ...props });
3522
3581
  };
3523
3582
  var LifePlanApplicationStepWrapper_default = LifePlanApplicationStepWrapper;
3524
3583
 
@@ -5547,10 +5606,13 @@ export {
5547
5606
  LifePlanApplicationFormWrapper_default as LifePlanApplicationFormWrapper,
5548
5607
  LifePlanApplicationStepWrapper_default as LifePlanApplicationStepWrapper,
5549
5608
  NotifyInstall,
5609
+ OCR_STORAGE_KEY,
5550
5610
  SharedLifePlanApplication_default as SharedLifePlanApplication,
5551
5611
  UserProfile_default as UserProfile,
5552
5612
  createEmptyApplicationData,
5553
5613
  loadApplicationDataFromLocalStorage,
5614
+ markOcrApplied,
5615
+ readOcrResult,
5554
5616
  saveApplicationDataToLocalStorage
5555
5617
  };
5556
5618
  //# sourceMappingURL=index.mjs.map