@agrada_digital/pbm 0.0.56 → 0.0.62

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
@@ -1,27 +1,84 @@
1
+ // src/libs/zustand/usePBM.tsx
2
+ import { createStore } from "zustand";
3
+ import { useStore } from "zustand/react";
4
+ var initialPBMState = {
5
+ securityNumber: "",
6
+ state: "isEmpty",
7
+ availableDiscountSelected: {
8
+ quantity: 0,
9
+ discount: {
10
+ unit: 0,
11
+ total: 0
12
+ },
13
+ totalPrice: 0
14
+ },
15
+ targetProduct: null,
16
+ campaign: "pbm_campaign"
17
+ };
18
+ var createPBMStore = (set) => ({
19
+ ...initialPBMState,
20
+ setSecurityNumber: (securityNumber) => set({ securityNumber }),
21
+ setState: (state) => set({ state }),
22
+ setTargetProduct: (targetProduct) => set({ targetProduct }),
23
+ setAvailableDiscountSelected: (availableDiscount) => set({ availableDiscountSelected: availableDiscount }),
24
+ setUrlAcceptTerms: (urlAcceptTerms) => set({ urlAcceptTerms })
25
+ });
26
+ var pbmStore = createStore(createPBMStore);
27
+ function usePBMStore(selector) {
28
+ if (selector) {
29
+ return useStore(pbmStore, selector);
30
+ }
31
+ return useStore(pbmStore, (state) => state);
32
+ }
33
+
1
34
  // src/components/Header/index.tsx
2
35
  import { jsx, jsxs } from "react/jsx-runtime";
3
36
  function Header({ originalProductPrice }) {
37
+ const { targetProduct } = usePBMStore();
38
+ const Price = targetProduct?.listPrice || originalProductPrice;
39
+ const Discount = Price * ((targetProduct?.discountMax || 0) / 100);
4
40
  return /* @__PURE__ */ jsxs(
5
41
  "header",
6
42
  {
7
- className: "flex items-center justify-between w-full p-0.5 rounded-full bg-[#44c2c0]/30",
43
+ className: "flex items-center justify-between w-full p-0.5 rounded-full bg-[#44c2c0]/30 mt-5",
8
44
  id: "header_pbm",
9
45
  children: [
10
- /* @__PURE__ */ jsx(
46
+ /* @__PURE__ */ jsxs(
11
47
  "span",
12
48
  {
13
- className: "py-1 px-6 rounded-full bg-[#44c2c0] shrink-0 text-white text-sm font-bold",
49
+ className: "py-1 px-6 rounded-full bg-[#44c2c0] shrink-0 text-white text-xl font-bold flex items-center justify-start gap-2 relative",
14
50
  "data-testid": "test_id_header_price",
15
51
  id: "header_price",
16
- children: Number(originalProductPrice)?.toLocaleString("pt-BR", {
17
- currency: "BRL",
18
- currencyDisplay: "symbol",
19
- currencySign: "standard",
20
- style: "currency"
21
- })
52
+ children: [
53
+ /* @__PURE__ */ jsxs("span", { className: "absolute -top-6 left-10 bg-emerald-500 px-4 py-1 rounded-t-2xl text-xs font-medium text-white", children: [
54
+ Discount.toLocaleString("pt-BR", {
55
+ currency: "BRL",
56
+ currencyDisplay: "symbol",
57
+ currencySign: "standard",
58
+ style: "currency"
59
+ }),
60
+ " OFF"
61
+ ] }),
62
+ /* @__PURE__ */ jsxs("svg", { width: "32px", height: "32px", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
63
+ /* @__PURE__ */ jsx("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0" }),
64
+ /* @__PURE__ */ jsx("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round" }),
65
+ /* @__PURE__ */ jsxs("g", { id: "SVGRepo_iconCarrier", children: [
66
+ /* @__PURE__ */ jsx("path", { d: "M10 8.99998C10.5523 8.99998 11 9.44769 11 9.99998C11 10.5523 10.5523 11 10 11C9.44775 11 9.00004 10.5523 9.00004 9.99998C9.00004 9.44769 9.44775 8.99998 10 8.99998Z", fill: "#fff" }),
67
+ /* @__PURE__ */ jsx("path", { d: "M13 14C13 14.5523 13.4478 15 14 15C14.5523 15 15 14.5523 15 14C15 13.4477 14.5523 13 14 13C13.4478 13 13 13.4477 13 14Z", fill: "#fff" }),
68
+ /* @__PURE__ */ jsx("path", { d: "M10.7071 14.7071L14.7071 10.7071C15.0977 10.3166 15.0977 9.6834 14.7071 9.29287C14.3166 8.90235 13.6835 8.90235 13.2929 9.29287L9.29293 13.2929C8.90241 13.6834 8.90241 14.3166 9.29293 14.7071C9.68346 15.0976 10.3166 15.0976 10.7071 14.7071Z", fill: "#fff" }),
69
+ /* @__PURE__ */ jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.3117 4.07145L15.1708 4.34503L14.5575 3.34485C13.3869 1.43575 10.6131 1.43575 9.44254 3.34485L8.82926 4.34503L7.68836 4.07145C5.51069 3.54925 3.54931 5.51063 4.07151 7.6883L4.34509 8.8292L3.34491 9.44248C1.43581 10.6131 1.43581 13.3869 3.34491 14.5575L4.34509 15.1708L4.07151 16.3117C3.54931 18.4893 5.51069 20.4507 7.68836 19.9285L8.82926 19.6549L9.44254 20.6551C10.6131 22.5642 13.3869 22.5642 14.5575 20.6551L15.1708 19.6549L16.3117 19.9285C18.4894 20.4507 20.4508 18.4893 19.9286 16.3117L19.655 15.1708L20.6552 14.5575C22.5643 13.3869 22.5643 10.6131 20.6552 9.44248L19.655 8.8292L19.9286 7.6883C20.4508 5.51063 18.4894 3.54925 16.3117 4.07145ZM11.1475 4.3903C11.5377 3.75393 12.4623 3.75393 12.8525 4.3903L13.8454 6.00951C14.0717 6.37867 14.51 6.56019 14.9311 6.45922L16.7781 6.01631C17.504 5.84225 18.1578 6.49604 17.9837 7.22193L17.5408 9.06894C17.4398 9.49003 17.6213 9.92827 17.9905 10.1546L19.6097 11.1475C20.2461 11.5377 20.2461 12.4623 19.6097 12.8525L17.9905 13.8453C17.6213 14.0717 17.4398 14.5099 17.5408 14.931L17.9837 16.778C18.1578 17.5039 17.504 18.1577 16.7781 17.9836L14.9311 17.5407C14.51 17.4398 14.0717 17.6213 13.8454 17.9904L12.8525 19.6097C12.4623 20.246 11.5377 20.246 11.1475 19.6097L10.1547 17.9904C9.92833 17.6213 9.49009 17.4398 9.069 17.5407L7.22199 17.9836C6.4961 18.1577 5.84231 17.5039 6.01637 16.778L6.45928 14.931C6.56026 14.5099 6.37873 14.0717 6.00957 13.8453L4.39036 12.8525C3.75399 12.4623 3.75399 11.5377 4.39036 11.1475L6.00957 10.1546C6.37873 9.92827 6.56026 9.49003 6.45928 9.06894L6.01637 7.22193C5.84231 6.49604 6.4961 5.84225 7.22199 6.01631L9.069 6.45922C9.49009 6.56019 9.92833 6.37867 10.1547 6.00951L11.1475 4.3903Z", fill: "#fff" })
70
+ ] })
71
+ ] }),
72
+ Number(Price - Discount)?.toLocaleString("pt-BR", {
73
+ currency: "BRL",
74
+ currencyDisplay: "symbol",
75
+ currencySign: "standard",
76
+ style: "currency"
77
+ })
78
+ ]
22
79
  }
23
80
  ),
24
- /* @__PURE__ */ jsx("h1", { id: "header_title", className: "text-center w-full text-[#339c9b] font-bold text-xs px-4 md:text-sm", children: "Benef\xEDcio de Laborat\xF3rio" })
81
+ /* @__PURE__ */ jsx("h1", { id: "header_title", className: "text-center w-full text-[#339c9b] font-bold text-xs px-4 md:text-sm", children: "Desconto de Laborat\xF3rio" })
25
82
  ]
26
83
  }
27
84
  );
@@ -39,7 +96,7 @@ function Container({
39
96
  "main",
40
97
  {
41
98
  className: classNames({
42
- "flex flex-col items-center justify-center min-w-[var(--min-container)] max-w-[var(--max-container)] w-full h-auto rounded-2xl p-4 bg-gray-100 gap-4": variant === "main",
99
+ "border-3 border-[#44c2c0] flex flex-col items-center justify-center min-w-[var(--min-container)] max-w-[var(--max-container)] w-full h-auto rounded-2xl p-4 bg-gray-100 gap-4 relative": variant === "main",
43
100
  "w-full h-auto relative": variant === "simple"
44
101
  }),
45
102
  "data-testid": "test_id_container",
@@ -55,38 +112,6 @@ var Container_default = Container;
55
112
  import classNames2 from "classnames";
56
113
  import { useEffect, useState } from "react";
57
114
 
58
- // src/libs/zustand/usePBM.tsx
59
- import { createStore } from "zustand";
60
- import { useStore } from "zustand/react";
61
- var initialPBMState = {
62
- securityNumber: "",
63
- state: "isEmpty",
64
- availableDiscountSelected: {
65
- quantity: 0,
66
- discount: {
67
- unit: 0,
68
- total: 0
69
- },
70
- totalPrice: 0
71
- },
72
- targetProduct: null,
73
- campaign: "pbm_campaign"
74
- };
75
- var createPBMStore = (set) => ({
76
- ...initialPBMState,
77
- setSecurityNumber: (securityNumber) => set({ securityNumber }),
78
- setState: (state) => set({ state }),
79
- setTargetProduct: (targetProduct) => set({ targetProduct }),
80
- setAvailableDiscountSelected: (availableDiscount) => set({ availableDiscountSelected: availableDiscount })
81
- });
82
- var pbmStore = createStore(createPBMStore);
83
- function usePBMStore(selector) {
84
- if (selector) {
85
- return useStore(pbmStore, selector);
86
- }
87
- return useStore(pbmStore, (state) => state);
88
- }
89
-
90
115
  // src/services/get-product-by-ean.ts
91
116
  import Cookies from "js-cookie";
92
117
  var GetProductByEAN = async ({ PRODUCT_EAN }) => {
@@ -103,7 +128,7 @@ var GetProductByEAN = async ({ PRODUCT_EAN }) => {
103
128
  }
104
129
  });
105
130
  const dataResponse = await response.json();
106
- if (!dataResponse.sucesso) {
131
+ if (!dataResponse.success) {
107
132
  throw new Error(dataResponse.message || "Failed to fetch authorization");
108
133
  }
109
134
  return dataResponse;
@@ -112,45 +137,56 @@ var GetProductByEAN = async ({ PRODUCT_EAN }) => {
112
137
  // src/components/Footer/index.tsx
113
138
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
114
139
  function Footer() {
115
- const [industryLogo, setIndustryLogo] = useState(void 0);
116
- const { targetProduct } = usePBMStore();
140
+ const [industryLogo, setIndustryLogo] = useState(null);
141
+ const { targetProduct, setTargetProduct, state } = usePBMStore();
117
142
  useEffect(() => {
118
143
  const fetchProductByEan = async () => {
119
- if (!targetProduct) return;
144
+ if (!targetProduct?.ean) return;
120
145
  try {
121
146
  const response = await GetProductByEAN({ PRODUCT_EAN: targetProduct.ean });
122
- if (response.sucesso && response.dados) {
123
- setIndustryLogo(response.dados.pbm.imageLink);
147
+ if (response.success && response.data) {
148
+ setIndustryLogo(response.data.pbm.imageLink);
149
+ const { pbm, sku, ...targetProductNewData } = response.data;
150
+ setTargetProduct({
151
+ ...targetProduct,
152
+ ...targetProductNewData,
153
+ productId: Number(targetProductNewData.productId),
154
+ informativeMessage: pbm.informativeMessage ?? "",
155
+ discountMax: pbm.discountMax ?? 0
156
+ });
124
157
  }
125
158
  } catch (error) {
126
159
  console.error(error);
127
160
  }
128
161
  };
129
162
  fetchProductByEan();
130
- }, [targetProduct]);
131
- return /* @__PURE__ */ jsx3("footer", { className: "w-full h-auto relative", id: "footer_pbm", children: /* @__PURE__ */ jsxs2("section", { className: classNames2("flex items-center w-full h-auto gap-4", { "justify-center": industryLogo, "justify-start": !industryLogo }), children: [
132
- /* @__PURE__ */ jsxs2("section", { className: "w-4/5 h-auto", children: [
133
- /* @__PURE__ */ jsx3("h3", { className: "text-start font-semibold text-sm", children: "Economize com o benef\xEDcio do laborat\xF3rio." }),
134
- /* @__PURE__ */ jsx3("p", { className: "text-start font-normal text-sm", children: "Este produto tem pre\xE7o exclusivo para clientes cadastrados no programa." })
163
+ }, [targetProduct?.ean]);
164
+ return /* @__PURE__ */ jsxs2("footer", { className: "w-full h-auto relative", id: "footer_pbm", children: [
165
+ /* @__PURE__ */ jsxs2("section", { className: classNames2("flex items-center w-full h-auto gap-4", { "justify-center": industryLogo, "justify-start": !industryLogo }), children: [
166
+ /* @__PURE__ */ jsxs2("section", { className: "w-4/5 h-auto", children: [
167
+ /* @__PURE__ */ jsx3("h3", { className: "text-start font-semibold text-sm", children: "Economize com o benef\xEDcio do laborat\xF3rio." }),
168
+ /* @__PURE__ */ jsx3("p", { className: "text-start font-normal text-sm", children: "Este produto tem pre\xE7o exclusivo para clientes cadastrados no programa." })
169
+ ] }),
170
+ industryLogo && /* @__PURE__ */ jsx3(
171
+ "img",
172
+ {
173
+ src: industryLogo,
174
+ alt: "parceiro",
175
+ className: "w-1/5 min-w-20 h-auto aspect-auto rounded-xl",
176
+ loading: "eager",
177
+ id: "footer_industry_logo_pbm",
178
+ "data-testid": "footer_industry_logo_pbm"
179
+ }
180
+ )
135
181
  ] }),
136
- industryLogo && /* @__PURE__ */ jsx3(
137
- "img",
138
- {
139
- src: industryLogo,
140
- alt: "parceiro",
141
- className: "w-1/5 min-w-20 h-auto aspect-auto",
142
- loading: "eager",
143
- id: "footer_industry_logo_pbm",
144
- "data-testid": "footer_industry_logo_pbm"
145
- }
146
- )
147
- ] }) });
182
+ state !== "isActivated" && targetProduct?.informativeMessage && /* @__PURE__ */ jsx3("p", { className: "text-start font-semibold text-sm", children: targetProduct?.informativeMessage })
183
+ ] });
148
184
  }
149
185
  var Footer_default = Footer;
150
186
 
151
187
  // src/schema/validation-schema.ts
152
188
  import { z } from "zod";
153
- var validationSchema = z.strictObject({
189
+ var validationSchema = z.object({
154
190
  securityNumber: z.string({
155
191
  required_error: "CPF \xE9 obrigat\xF3rio."
156
192
  }).refine((doc) => {
@@ -160,7 +196,7 @@ var validationSchema = z.strictObject({
160
196
  const replacedDoc = doc.replace(/\D/g, "");
161
197
  return !!Number(replacedDoc);
162
198
  }, "CPF deve conter apenas n\xFAmeros."),
163
- coupon: z.string().min(0)
199
+ coupon: z.string({ required_error: "Cupom / ID do Cart\xE3o obrigat\xF3rio." }).optional()
164
200
  });
165
201
 
166
202
  // src/utils/format.ts
@@ -178,9 +214,9 @@ import { useForm } from "react-hook-form";
178
214
  import { ArrowRight } from "lucide-react";
179
215
  import { useState as useState2 } from "react";
180
216
 
181
- // src/services/validate-document.ts
217
+ // src/services/benefits-with-document.ts
182
218
  import Cookies2 from "js-cookie";
183
- var ValidateDocument = async ({ document, products }) => {
219
+ var BenefitsWithDocument = async ({ document: document2, products }) => {
184
220
  const API_URL = import.meta.env.VITE_API_URL;
185
221
  if (!API_URL) {
186
222
  throw new Error("API URL is not defined in environment variables");
@@ -189,13 +225,13 @@ var ValidateDocument = async ({ document, products }) => {
189
225
  if (!AUTH_TOKEN) {
190
226
  throw new Error("Token is not defined in cookies or is expired");
191
227
  }
192
- const response = await fetch(`${API_URL}/transactions/validate`, {
228
+ const response = await fetch(`${API_URL}/products/benefitByDocument`, {
193
229
  method: "POST",
194
230
  headers: {
195
231
  Authorization: `Bearer ${AUTH_TOKEN}`,
196
232
  "Content-Type": "application/json"
197
233
  },
198
- body: JSON.stringify({ document, products })
234
+ body: JSON.stringify({ consumer: { document: document2 }, products })
199
235
  });
200
236
  const dataResponse = await response.json();
201
237
  if (!dataResponse.success) {
@@ -213,7 +249,7 @@ function Button(props) {
213
249
  {
214
250
  ...props,
215
251
  className: classNames3(
216
- "w-3xs cursor-pointer h-10 rounded-full bg-blue-500 hover:bg-blue-400 text-white text-sm font-semibold transition-colors",
252
+ "w-3xs cursor-pointer h-10 rounded-full bg-emerald-500 hover:bg-emerald-400 text-white text-sm font-semibold transition-colors",
217
253
  props.className
218
254
  ),
219
255
  children: props.children
@@ -225,37 +261,60 @@ var Button_default = Button;
225
261
  // src/components/Form/index.tsx
226
262
  import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
227
263
  function Form({ setLoading }) {
228
- const { setSecurityNumber, setState, securityNumber, targetProduct } = usePBMStore();
264
+ const { setSecurityNumber, setState, securityNumber, targetProduct, setUrlAcceptTerms } = usePBMStore();
229
265
  const [showCoupoField, setShowCoupoField] = useState2(false);
230
266
  const {
231
267
  handleSubmit,
232
268
  register,
233
269
  setValue,
270
+ clearErrors,
271
+ unregister,
234
272
  formState: { errors }
235
273
  } = useForm({
236
274
  resolver: zodResolver(validationSchema),
275
+ mode: "onSubmit",
237
276
  defaultValues: {
238
- securityNumber: securityNumber || ""
277
+ securityNumber: securityNumber || "",
278
+ coupon: ""
239
279
  }
240
280
  });
241
281
  const onSubmitDefault = async (values) => {
282
+ if (!showCoupoField) {
283
+ setValue("coupon", void 0, { shouldValidate: false });
284
+ }
242
285
  setLoading(true);
243
286
  try {
244
287
  if (targetProduct === null) {
245
288
  console.error("PBMLOG: Product is not defined!");
246
289
  return;
247
290
  }
248
- const response = await ValidateDocument({
291
+ if (!targetProduct.productId) {
292
+ console.error("PBMLOG: Product ID is not defined!");
293
+ return;
294
+ }
295
+ if (!targetProduct.listPrice) {
296
+ console.error("PBMLOG: List Price is not defined!");
297
+ return;
298
+ }
299
+ const response = await BenefitsWithDocument({
249
300
  document: values.securityNumber.replace(/\D/g, ""),
250
- products: [{ ean: targetProduct.ean, quantity: targetProduct.quantity }]
301
+ products: [{
302
+ productId: targetProduct.productId,
303
+ ean: targetProduct.ean,
304
+ requestedQuantity: 1,
305
+ listPrice: targetProduct.listPrice,
306
+ netPrice: targetProduct.netPrice ?? targetProduct.listPrice
307
+ }]
251
308
  });
252
309
  if (response.success) {
253
310
  const status = {
254
- "active": "isActivated",
255
- "nonexistent": "isInvalid"
311
+ "acceptance": "isInvalid",
312
+ "industry registration": "isRegistered",
313
+ "active": "isActivated"
256
314
  };
257
315
  setSecurityNumber(values.securityNumber);
258
- setState(status[response.data.process_platform.status]);
316
+ setState(status[response.data.product[0].statusCustumer]);
317
+ setUrlAcceptTerms(response.data.product[0].urlAcceptTerm || void 0);
259
318
  }
260
319
  } catch (error) {
261
320
  console.error("PBMLOG: Error validating document -", error);
@@ -271,7 +330,7 @@ function Form({ setLoading }) {
271
330
  onSubmit: handleSubmit(onSubmitDefault),
272
331
  className: classNames4(
273
332
  "w-full h-auto flex items-center justify-center mb-0 transition-all duration-150",
274
- { "mb-4": errors.securityNumber || errors.coupon, "gap-2": showCoupoField }
333
+ { "mb-4": errors.securityNumber || errors.coupon && showCoupoField, "gap-2": showCoupoField }
275
334
  ),
276
335
  id: "form_security_number_pbm",
277
336
  children: [
@@ -287,7 +346,7 @@ function Form({ setLoading }) {
287
346
  {
288
347
  type: "text",
289
348
  className: classNames4(
290
- "w-full h-8 bg-[#44c2c0]/20 rounded-s-full text-sm font-semibold focus:outline focus:outline-[#339c9b] focus:bg-[#44c2c0]/30 text-zinc-600 placeholder:text-zinc-600 px-4 placeholder:text-sm placeholder:font-semibold",
349
+ "w-full h-8 bg-white rounded-s-full text-sm font-semibold focus:outline focus:outline-[#339c9b] focus:bg-white text-zinc-600 placeholder:text-zinc-600 px-4 placeholder:text-sm placeholder:font-semibold",
291
350
  { "outline outline-red-600": errors.securityNumber, "rounded-full": showCoupoField }
292
351
  ),
293
352
  placeholder: "Digite seu CPF aqui...",
@@ -325,12 +384,12 @@ function Form({ setLoading }) {
325
384
  { "outline outline-red-600": errors.coupon, "rounded-full": showCoupoField }
326
385
  ),
327
386
  placeholder: "Cupom / ID do Cart\xE3o",
328
- required: true,
329
- maxLength: 14,
330
387
  ...register("coupon", {
388
+ required: showCoupoField ? "Cupom / ID do Cart\xE3o obrigat\xF3rio." : false,
389
+ shouldUnregister: !showCoupoField,
331
390
  onChange: (e) => {
332
391
  setValue("coupon", e.target.value, {
333
- shouldValidate: true
392
+ shouldValidate: showCoupoField
334
393
  });
335
394
  }
336
395
  }),
@@ -346,7 +405,7 @@ function Form({ setLoading }) {
346
405
  {
347
406
  type: "submit",
348
407
  className: classNames4(
349
- "bg-gray-400 w-1/5 h-8 flex items-center justify-center rounded-e-full cursor-pointer",
408
+ "bg-emerald-500 w-1/5 h-8 flex items-center justify-center rounded-e-full cursor-pointer",
350
409
  { "rounded-full": showCoupoField }
351
410
  ),
352
411
  id: "button_submit_security_number_pbm",
@@ -360,7 +419,14 @@ function Form({ setLoading }) {
360
419
  Button_default,
361
420
  {
362
421
  className: "bg-transparent p-0 pl-2 w-auto h-auto text-zinc-600 underline cursor-pointer hover:text-zinc-900 hover:bg-transparent flex items-center justify-start gap-1",
363
- onClick: () => setShowCoupoField(!showCoupoField),
422
+ onClick: () => {
423
+ const newValue = !showCoupoField;
424
+ setShowCoupoField(newValue);
425
+ if (!newValue) {
426
+ unregister("coupon");
427
+ clearErrors("coupon");
428
+ }
429
+ },
364
430
  id: "check_benefits_button",
365
431
  children: [
366
432
  /* @__PURE__ */ jsx5("span", { children: !showCoupoField ? "Possui cupom?" : "N\xE3o possui cupom?" }),
@@ -398,32 +464,7 @@ function Loading({ textColor }) {
398
464
  var Loading_default = Loading;
399
465
 
400
466
  // src/components/BenefitsTable/index.tsx
401
- import { useState as useState3 } from "react";
402
-
403
- // src/mocks/benefits.ts
404
- var BENEFITS_ITEMS = [
405
- {
406
- id: 1,
407
- ean: "001",
408
- authorizedQuantity: 1,
409
- discountValue: 4800,
410
- discountPercentual: 2400
411
- },
412
- {
413
- id: 2,
414
- ean: "002",
415
- authorizedQuantity: 2,
416
- discountValue: 4800,
417
- discountPercentual: 2400
418
- },
419
- {
420
- id: 3,
421
- ean: "003",
422
- authorizedQuantity: 3,
423
- discountValue: 9400,
424
- discountPercentual: 4700
425
- }
426
- ];
467
+ import { useEffect as useEffect3, useState as useState3 } from "react";
427
468
 
428
469
  // src/components/UI/Title/index.tsx
429
470
  import classNames5 from "classnames";
@@ -449,13 +490,13 @@ var Title_default = Title;
449
490
  import { Badge, BadgeCheck } from "lucide-react";
450
491
  import { useCallback, useEffect as useEffect2 } from "react";
451
492
  import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
452
- function Item({ data, onChange, checked, originalProductPrice }) {
493
+ function Item({ data, onChange, checked }) {
453
494
  const { setAvailableDiscountSelected, securityNumber } = usePBMStore();
454
495
  const ID_INPUT = "unity_quantity_" + data.authorizedQuantity;
455
- const decimalDiscount = data.discountPercentual / 1e4;
456
- const unitDiscountValue = originalProductPrice * decimalDiscount;
496
+ const decimalDiscount = data.discountPercentual / 100;
497
+ const unitDiscountValue = data.grossPrice * decimalDiscount;
457
498
  const discountValue = unitDiscountValue * data.authorizedQuantity;
458
- const totalPriceProductWithDiscountBenefit = originalProductPrice * data.authorizedQuantity - discountValue;
499
+ const totalPriceProductWithDiscountBenefit = data.grossPrice * data.authorizedQuantity - discountValue;
459
500
  const updateStorageData = useCallback(() => {
460
501
  if (checked) {
461
502
  const roundToTwoDecimals = (value) => Math.round(value * 100) / 100;
@@ -527,13 +568,103 @@ function Item({ data, onChange, checked, originalProductPrice }) {
527
568
  }
528
569
  var Item_default = Item;
529
570
 
571
+ // src/services/benefits-without-document.ts
572
+ import Cookies3 from "js-cookie";
573
+ var CheckBenefistWithoutDocument = async ({ products }) => {
574
+ const API_URL = import.meta.env.VITE_API_URL;
575
+ if (!API_URL) {
576
+ throw new Error("API URL is not defined in environment variables");
577
+ }
578
+ const AUTH_TOKEN = Cookies3.get("pbm-token");
579
+ if (!AUTH_TOKEN) {
580
+ throw new Error("Token is not defined in cookies or is expired");
581
+ }
582
+ const response = await fetch(`${API_URL}/products/genericBenefit`, {
583
+ method: "POST",
584
+ headers: {
585
+ Authorization: `Bearer ${AUTH_TOKEN}`,
586
+ "Content-Type": "application/json"
587
+ },
588
+ body: JSON.stringify({ products })
589
+ });
590
+ const dataResponse = await response.json();
591
+ if (!dataResponse.success) {
592
+ throw new Error(dataResponse.message || "Failed to fetch benefits without document");
593
+ }
594
+ return dataResponse;
595
+ };
596
+
530
597
  // src/components/BenefitsTable/index.tsx
531
598
  import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
532
- function BenefitsTable({
533
- originalProductPrice
534
- }) {
535
- const { securityNumber, setState } = usePBMStore();
599
+ function BenefitsTable() {
600
+ const { securityNumber, setState, targetProduct } = usePBMStore();
536
601
  const [selectedDiscout, setSelectedDiscount] = useState3(null);
602
+ const [loading, setLoading] = useState3(true);
603
+ const [benefitsItems, setBenefitsItems] = useState3();
604
+ useEffect3(() => {
605
+ const fetchDicountsWithoutDocument = async () => {
606
+ if (!targetProduct?.productId) {
607
+ console.error("PBMLOG: Product ID is not defined on targetProduct");
608
+ return;
609
+ }
610
+ if (!targetProduct.ean) {
611
+ console.error("PBMLOG: EAN is not defined on targetProduct");
612
+ return;
613
+ }
614
+ if (!targetProduct.listPrice) {
615
+ console.error("PBMLOG: List Price is not defined on targetProduct");
616
+ return;
617
+ }
618
+ if (!targetProduct.price) {
619
+ console.error("PBMLOG: Price is not defined on targetProduct");
620
+ return;
621
+ }
622
+ try {
623
+ const data = {
624
+ productId: Number(targetProduct.productId),
625
+ ean: targetProduct.ean,
626
+ requestedQuantity: 1,
627
+ listPrice: targetProduct.listPrice,
628
+ netPrice: targetProduct.price
629
+ };
630
+ const response = await CheckBenefistWithoutDocument({ products: [data] });
631
+ if (response.success && response.data) {
632
+ setBenefitsItems(response.data);
633
+ } else {
634
+ setBenefitsItems(void 0);
635
+ }
636
+ } catch (error) {
637
+ setBenefitsItems(void 0);
638
+ console.error(error);
639
+ } finally {
640
+ setLoading(false);
641
+ }
642
+ };
643
+ const fetchDiscountWithDocument = async () => {
644
+ console.log("consulta feita com documento");
645
+ };
646
+ securityNumber ? fetchDiscountWithDocument() : fetchDicountsWithoutDocument();
647
+ }, []);
648
+ if (loading) {
649
+ return /* @__PURE__ */ jsxs6("main", { className: "flex items-center justify-center gap-4", id: "loading_pbm", children: [
650
+ /* @__PURE__ */ jsx9(
651
+ "div",
652
+ {
653
+ "data-testid": "test_id_spin",
654
+ className: "w-8 h-8 border-4 border-t-gray-700 border-gray-300 rounded-full animate-spin",
655
+ id: "loading_spin"
656
+ }
657
+ ),
658
+ /* @__PURE__ */ jsx9(
659
+ "p",
660
+ {
661
+ className: "text-sm font-semibold text-start text-zinc-900",
662
+ id: "loading_label",
663
+ children: "Buscando beneficios dispon\xEDveis..."
664
+ }
665
+ )
666
+ ] });
667
+ }
537
668
  return /* @__PURE__ */ jsxs6(
538
669
  "section",
539
670
  {
@@ -541,31 +672,34 @@ function BenefitsTable({
541
672
  id: "benefits_table_pbm",
542
673
  children: [
543
674
  /* @__PURE__ */ jsx9(Title_default, { children: "Descontos dispon\xEDveis:" }),
544
- /* @__PURE__ */ jsx9(
675
+ /* @__PURE__ */ jsxs6(
545
676
  "form",
546
677
  {
547
678
  className: "flex flex-col items-center justify-start w-full gap-3",
548
679
  id: "form_benefits_table_pbm",
549
- children: BENEFITS_ITEMS.map((item, index) => {
550
- const ID_INPUT = "unity_quantity_" + item.authorizedQuantity;
551
- return /* @__PURE__ */ jsx9(
552
- Item_default,
553
- {
554
- data: item,
555
- checked: selectedDiscout === ID_INPUT,
556
- onChange: () => setSelectedDiscount(ID_INPUT),
557
- originalProductPrice
558
- },
559
- index
560
- );
561
- })
680
+ children: [
681
+ !benefitsItems && /* @__PURE__ */ jsx9("p", { className: "text-sm font-semibold text-start text-zinc-900", id: "benefits_empty_pbm", children: "N\xE3o foi poss\xEDvel encontrar benef\xEDcios para esse produto." }),
682
+ benefitsItems && benefitsItems.map((item, index) => {
683
+ const ID_INPUT = "unity_quantity_" + item.authorizedQuantity;
684
+ return /* @__PURE__ */ jsx9(
685
+ Item_default,
686
+ {
687
+ data: item,
688
+ checked: selectedDiscout === ID_INPUT,
689
+ onChange: () => setSelectedDiscount(ID_INPUT)
690
+ },
691
+ index
692
+ );
693
+ }),
694
+ benefitsItems && /* @__PURE__ */ jsx9("p", { className: "w-full text-sm font-semibold text-center text-zinc-600", id: "benefits_empty_pbm", children: benefitsItems[0].informativeMessage })
695
+ ]
562
696
  }
563
697
  ),
564
698
  !securityNumber && /* @__PURE__ */ jsxs6(
565
699
  Button_default,
566
700
  {
567
701
  onClick: () => setState("isEmpty"),
568
- className: "bg-transparent p-0 pl-2 w-auto h-auto text-zinc-600 cursor-pointer hover:text-zinc-900 hover:bg-transparent text-start",
702
+ className: "bg-transparent p-0 w-auto h-auto text-zinc-600 cursor-pointer hover:text-zinc-900 hover:bg-transparent text-start",
569
703
  id: "unauthorized_benefits_button",
570
704
  children: [
571
705
  "Aten\xE7\xE3o: n\xE3o \xE9 poss\xEDvel utilizar os benef\xEDcos sem realizar a consulta do cpf, por favor",
@@ -611,9 +745,39 @@ var Text_default = Text;
611
745
 
612
746
  // src/components/Iframe/index.tsx
613
747
  import classNames7 from "classnames";
614
- import { TriangleAlert } from "lucide-react";
748
+ import { TriangleAlert, ExternalLink } from "lucide-react";
749
+ import { useState as useState4, useEffect as useEffect4 } from "react";
615
750
  import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
616
751
  function Iframe({ url, title, openModal, setOpenModal }) {
752
+ const [_, setIframeError] = useState4(false);
753
+ const [showFallback, setShowFallback] = useState4(false);
754
+ useEffect4(() => {
755
+ if (openModal && url) {
756
+ setIframeError(false);
757
+ setShowFallback(false);
758
+ const timeout = setTimeout(() => {
759
+ const iframe = document.querySelector('iframe[src="' + url + '"]');
760
+ if (iframe) {
761
+ try {
762
+ const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
763
+ if (!iframeDoc) {
764
+ setIframeError(true);
765
+ setShowFallback(true);
766
+ }
767
+ } catch (e) {
768
+ setIframeError(true);
769
+ setShowFallback(true);
770
+ }
771
+ }
772
+ }, 2e3);
773
+ return () => clearTimeout(timeout);
774
+ }
775
+ }, [openModal, url]);
776
+ const handleOpenInNewWindow = () => {
777
+ if (url) {
778
+ window.open(url, "_blank", "noopener,noreferrer");
779
+ }
780
+ };
617
781
  return /* @__PURE__ */ jsxs7(
618
782
  "main",
619
783
  {
@@ -650,7 +814,22 @@ function Iframe({ url, title, openModal, setOpenModal }) {
650
814
  children: "Fechar"
651
815
  }
652
816
  ) }),
653
- /* @__PURE__ */ jsx11(
817
+ showFallback ? /* @__PURE__ */ jsxs7("div", { className: "w-4/5 h-[80%] bg-zinc-800 z-10 flex flex-col items-center justify-center p-8 rounded-lg border-2 border-yellow-500", children: [
818
+ /* @__PURE__ */ jsx11(TriangleAlert, { size: 48, className: "text-yellow-500 mb-4" }),
819
+ /* @__PURE__ */ jsx11("h3", { className: "text-white text-xl font-bold mb-4 text-center", children: "N\xE3o foi poss\xEDvel carregar o conte\xFAdo" }),
820
+ /* @__PURE__ */ jsx11("p", { className: "text-white text-sm mb-6 text-center max-w-md", children: "O servidor bloqueou a exibi\xE7\xE3o deste conte\xFAdo em um iframe devido \xE0s pol\xEDticas de seguran\xE7a. Voc\xEA pode abrir o link em uma nova janela para continuar." }),
821
+ /* @__PURE__ */ jsxs7(
822
+ "button",
823
+ {
824
+ onClick: handleOpenInNewWindow,
825
+ className: "flex items-center gap-2 bg-emerald-500 hover:bg-emerald-600 text-white font-semibold px-6 py-3 rounded-lg transition-colors",
826
+ children: [
827
+ /* @__PURE__ */ jsx11(ExternalLink, { size: 20 }),
828
+ "Abrir em nova janela"
829
+ ]
830
+ }
831
+ )
832
+ ] }) : /* @__PURE__ */ jsx11(
654
833
  "iframe",
655
834
  {
656
835
  src: url,
@@ -658,7 +837,11 @@ function Iframe({ url, title, openModal, setOpenModal }) {
658
837
  width: "80%",
659
838
  height: "80%",
660
839
  allowFullScreen: true,
661
- className: "z-10"
840
+ className: "z-10",
841
+ onError: () => {
842
+ setIframeError(true);
843
+ setShowFallback(true);
844
+ }
662
845
  }
663
846
  ),
664
847
  /* @__PURE__ */ jsxs7("section", { className: "items-center justify-center flex flex-wrap gap-1 bg-zinc-800 z-10 w-4/5 py-2 px-4 rounded-ee-2xl rounded-es-2xl border-t-2 border-gray-100", children: [
@@ -677,10 +860,11 @@ function Iframe({ url, title, openModal, setOpenModal }) {
677
860
  var Iframe_default = Iframe;
678
861
 
679
862
  // src/components/SecurityNumberInvalid/index.tsx
680
- import { useState as useState4 } from "react";
863
+ import { useState as useState5 } from "react";
681
864
  import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
682
865
  function SecurityNumberInvalid({ textColor }) {
683
- const [openModal, setOpenModal] = useState4(false);
866
+ const [openModal, setOpenModal] = useState5(false);
867
+ const { urlAcceptTerms } = usePBMStore();
684
868
  return /* @__PURE__ */ jsxs8(
685
869
  "section",
686
870
  {
@@ -702,7 +886,7 @@ function SecurityNumberInvalid({ textColor }) {
702
886
  /* @__PURE__ */ jsx12(
703
887
  Iframe_default,
704
888
  {
705
- url: "https://termo.azurewebsites.net/",
889
+ url: urlAcceptTerms || "",
706
890
  title: "Aceitar termos PBM",
707
891
  openModal,
708
892
  setOpenModal
@@ -715,7 +899,7 @@ function SecurityNumberInvalid({ textColor }) {
715
899
  var SecurityNumberInvalid_default = SecurityNumberInvalid;
716
900
 
717
901
  // src/PBM.tsx
718
- import { useCallback as useCallback2, useEffect as useEffect3, useState as useState5 } from "react";
902
+ import { useCallback as useCallback2, useEffect as useEffect5, useState as useState6 } from "react";
719
903
 
720
904
  // src/components/UI/Link/index.tsx
721
905
  import classNames8 from "classnames";
@@ -776,7 +960,7 @@ function SecurityNumberRegitered({ textColor }) {
776
960
  var SecurityNumberRegitered_default = SecurityNumberRegitered;
777
961
 
778
962
  // src/services/authorization.ts
779
- import Cookies3 from "js-cookie";
963
+ import Cookies4 from "js-cookie";
780
964
  var GetAuthorization = async ({ clientID }) => {
781
965
  const API_URL = import.meta.env.VITE_API_URL;
782
966
  const STORE_ID = import.meta.env.VITE_STORE_ID;
@@ -793,22 +977,22 @@ var GetAuthorization = async ({ clientID }) => {
793
977
  "Content-Type": "application/json"
794
978
  },
795
979
  body: JSON.stringify({
796
- StoreID: STORE_ID,
797
- StoreName: STORE_NAME,
798
- ClientID: clientID
980
+ storeId: STORE_ID,
981
+ storeName: STORE_NAME,
982
+ clientId: clientID
799
983
  })
800
984
  });
801
985
  const dataResponse = await response.json();
802
986
  if (!dataResponse.success) {
803
987
  throw new Error(dataResponse.message || "Failed to fetch authorization");
804
988
  }
805
- Cookies3.set("pbm-token", dataResponse.data.Token, {
806
- expires: dataResponse.data.ExpiresIn / (60 * 60),
989
+ Cookies4.set("pbm-token", dataResponse.data.token, {
990
+ expires: dataResponse.data.expiresIn / (60 * 60),
807
991
  secure: true,
808
992
  sameSite: "Strict"
809
993
  });
810
- Cookies3.set("pbm-token-refresh", dataResponse.data.RefreshToken, {
811
- expires: dataResponse.data.RefreshExpiresIn / (60 * 60),
994
+ Cookies4.set("pbm-token-refresh", dataResponse.data.refreshToken, {
995
+ expires: dataResponse.data.refreshExpiresIn / (60 * 60),
812
996
  secure: true,
813
997
  sameSite: "Strict"
814
998
  });
@@ -826,11 +1010,11 @@ function PBM({
826
1010
  const formatedOriginalProductPrice = Number(
827
1011
  String(originalProductPrice).replace(",", ".")
828
1012
  );
829
- const [loading, setLoading] = useState5(false);
1013
+ const [loading, setLoading] = useState6(false);
830
1014
  const { setState, state, setTargetProduct } = usePBMStore();
831
- useEffect3(() => {
1015
+ useEffect5(() => {
832
1016
  if (eanProduct) {
833
- setTargetProduct({ ean: eanProduct, quantity: 1 });
1017
+ setTargetProduct({ ean: eanProduct });
834
1018
  }
835
1019
  }, [eanProduct, setTargetProduct]);
836
1020
  const handleAuthorizationRequest = useCallback2(async () => {
@@ -843,7 +1027,7 @@ function PBM({
843
1027
  console.error("Error fetching authorization:", error);
844
1028
  }
845
1029
  }, [clientID]);
846
- useEffect3(() => {
1030
+ useEffect5(() => {
847
1031
  handleAuthorizationRequest();
848
1032
  }, [handleAuthorizationRequest]);
849
1033
  return /* @__PURE__ */ jsxs10(Container_default, { variant: "main", children: [
@@ -867,7 +1051,7 @@ function PBM({
867
1051
  state === "isEmpty" && loading && /* @__PURE__ */ jsx15(Loading_default, {}),
868
1052
  state === "isInvalid" && !loading && /* @__PURE__ */ jsx15(SecurityNumberInvalid_default, {}),
869
1053
  state === "isRegistered" && !loading && /* @__PURE__ */ jsx15(SecurityNumberRegitered_default, {}),
870
- state === "isActivated" && !loading && /* @__PURE__ */ jsx15(BenefitsTable_default, { originalProductPrice: formatedOriginalProductPrice })
1054
+ state === "isActivated" && !loading && /* @__PURE__ */ jsx15(BenefitsTable_default, {})
871
1055
  ] }),
872
1056
  /* @__PURE__ */ jsx15(Footer_default, {})
873
1057
  ] });