npm-pkg-hook 1.3.9 → 1.4.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/package.json CHANGED
@@ -43,5 +43,5 @@
43
43
  "rm": "rm -rf node_modules package-lock.json && npm i",
44
44
  "test": "echo \"Error: no test specified\" && exit 1"
45
45
  },
46
- "version": "1.3.9"
46
+ "version": "1.4.2"
47
47
  }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Generate the store URL based on given parameters
3
+ * @param {Object} city - The city object with name
4
+ * @param {Object} department - The department object with name
5
+ * @param {string} storeName - The name of the store
6
+ * @param {string} idStore - The ID of the store
7
+ * @returns {string} - The generated URL or null if any field is missing
8
+ */
9
+ export const generateStoreURL = ({ city, department, storeName, idStore }) => {
10
+ try {
11
+ // Validate all necessary fields
12
+ if (
13
+ !process.env.MAIN_URL_BASE ||
14
+ !city?.cName ||
15
+ !department?.dName ||
16
+ !storeName ||
17
+ !idStore
18
+ ) {
19
+ return null // Return null or any default case you'd prefer
20
+ }
21
+
22
+ const cityName = city.cName.toLocaleLowerCase()
23
+ const departmentName = department.dName.toLocaleLowerCase()
24
+
25
+ // Replace spaces in storeName with hyphens
26
+ const formattedStoreName = storeName.replace(/\s+/g, '-')
27
+
28
+ return `${process.env.MAIN_URL_BASE}/delivery/${cityName}-${departmentName}/${formattedStoreName}/${idStore}`
29
+ } catch (_) {
30
+ return null
31
+ }
32
+ }
@@ -10,7 +10,15 @@ export * from './useLogout'
10
10
  export * from './useStatusOpenStore'
11
11
  export * from './useScheduleData'
12
12
  export * from './useOrders'
13
+ export * from './usePushNotifications'
14
+ export * from './useLocationManager'
13
15
  export * from './useFingerprintjs'
16
+ export * from './useCountries'
17
+ export * from './generateStoreURL'
18
+ export * from './useCreateStorePendingToRegister'
19
+ export * from './useDepartments'
20
+ export * from './useRoads'
21
+ export * from './useCities'
14
22
  export * from './useEditCategory'
15
23
  export * from './useEmployee'
16
24
  export * from './useCheckbox'
@@ -0,0 +1,34 @@
1
+ import { gql, useQuery } from '@apollo/client'
2
+ import { useEffect, useState } from 'react'
3
+
4
+ export const GET_ALL_STORES_PENDING_TO_REGISTER = gql`
5
+ query GetAllStoresPendingToRegister {
6
+ getAllStoresPendingToRegister {
7
+ StorePendingToRegisterId
8
+ UserId
9
+ UserEmail
10
+ StoreNumber
11
+ createAt
12
+ updateAt
13
+ }
14
+ }
15
+ `
16
+
17
+ export function useAllStoresPendingToRegister () {
18
+ const { loading, error, data } = useQuery(GET_ALL_STORES_PENDING_TO_REGISTER)
19
+
20
+ const [stores, setStores] = useState([])
21
+ const [fetchError, setFetchError] = useState(null)
22
+
23
+ useEffect(() => {
24
+ if (!loading && data) {
25
+ setStores(data.getAllStoresPendingToRegister)
26
+ }
27
+
28
+ if (error) {
29
+ setFetchError(error.message)
30
+ }
31
+ }, [loading, data, error])
32
+
33
+ return { loading, stores, fetchError }
34
+ }
@@ -2,6 +2,6 @@ import { useQuery } from '@apollo/client'
2
2
  import { GET_ALL_CAT_STORE } from './queries'
3
3
 
4
4
  export const useCategoryStore = () => {
5
- const { data } = useQuery(GET_ALL_CAT_STORE)
6
- return [data]
5
+ const { data, loading } = useQuery(GET_ALL_CAT_STORE)
6
+ return [data, { loading }]
7
7
  }
@@ -0,0 +1,13 @@
1
+ import { useLazyQuery } from '@apollo/client'
2
+ import { GET_ALL_CITIES } from './queries'
3
+
4
+ /**
5
+ * Custom hook to fetch cities lazily based on the provided department ID.
6
+ *
7
+ * @returns {Array} - Returns an array containing a function to execute the query, and an object containing data and any associated query state/error.
8
+ */
9
+ export function useCities () {
10
+ const [getCities, { data, loading, error }] = useLazyQuery(GET_ALL_CITIES)
11
+
12
+ return [getCities, { data: data ? data?.cities : [], loading, error }]
13
+ }
@@ -0,0 +1,12 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const GET_ALL_CITIES = gql`
4
+ query getAllCities($dId: ID!) {
5
+ cities(dId: $dId) {
6
+ ctId
7
+ dId
8
+ cName
9
+ cState
10
+ }
11
+ }
12
+ `
@@ -1,4 +1,8 @@
1
- import { useQuery, useMutation, useLazyQuery } from '@apollo/client'
1
+ import {
2
+ useQuery,
3
+ useMutation,
4
+ useLazyQuery
5
+ } from '@apollo/client'
2
6
  import {
3
7
  CREATE_CLIENTS,
4
8
  DELETE_ONE_CLIENTS,
@@ -28,11 +32,11 @@ export const useDeleteClients = ({ sendNotification = () => { } } = {}) => {
28
32
  export const useCreateClient = ({ sendNotification = () => { } } = {}) => {
29
33
  const [createClients, { loading, error }] = useMutation(CREATE_CLIENTS, {
30
34
  onError: (data) => {
31
- // sendNotification({
32
- // title: '',
33
- // description: 'Error',
34
- // backgroundColor: 'error'
35
- // })
35
+ sendNotification({
36
+ title: '',
37
+ description: 'Error',
38
+ backgroundColor: 'error'
39
+ })
36
40
  }
37
41
  })
38
42
 
@@ -0,0 +1,19 @@
1
+ import { useQuery } from '@apollo/client'
2
+ import { GET_ALL_COUNTRIES } from './queries'
3
+ /**
4
+
5
+ * Hook personalizado para obtener todos los países.
6
+ *
7
+ * @returns {Object} - Retorna un objeto con la data de los países y cualquier otro estado/error relacionado con la consulta.
8
+ */
9
+ export function useCountries () {
10
+ const { data, loading, error } = useQuery(GET_ALL_COUNTRIES)
11
+
12
+ // Aquí puedes manejar la lógica adicional que necesites, como mapear la data, manejar errores, etc.
13
+
14
+ return {
15
+ data: data ? data.countries : [],
16
+ loading,
17
+ error
18
+ }
19
+ }
@@ -0,0 +1,12 @@
1
+ import { gql } from '@apollo/client'
2
+
3
+ export const GET_ALL_COUNTRIES = gql`
4
+ query countries {
5
+ countries {
6
+ cId
7
+ cName
8
+ cCalCod
9
+ cState
10
+ }
11
+ }
12
+ `
@@ -0,0 +1,23 @@
1
+ const MAX_PRICE = 2147483647
2
+
3
+ /**
4
+ * Verifica si alguno de los valores en el array excede el precio máximo.
5
+ *
6
+ * @param {Array<number>} values - Lista de valores a verificar.
7
+ * @param {Function} sendNotification - Función para enviar notificaciones.
8
+ * @returns {boolean} - Retorna `true` si todos los valores están en rango, `false` si alguno excede el máximo.
9
+ */
10
+ export const verifyPriceInRange = ({ values = [], sendNotification }) => {
11
+ const isAnyValueOutOfRange = values.some(value => value > MAX_PRICE)
12
+
13
+ if (isAnyValueOutOfRange) {
14
+ sendNotification({
15
+ backgroundColor: 'warning',
16
+ title: 'Alerta',
17
+ description: 'El valor es muy elevado'
18
+ })
19
+ return false
20
+ }
21
+
22
+ return true
23
+ }
@@ -12,6 +12,7 @@ import { useStore } from '../useStore'
12
12
  import { useTagsProducts } from './../useProductsFood/usetagsProducts'
13
13
  import { useEditImageProduct } from './helpers/useEditImageProduct'
14
14
  import { getCatProductsWithProduct } from './helpers/manageCacheDataCatProduct'
15
+ export * from './helpers'
15
16
 
16
17
  export const useCreateProduct = ({
17
18
  setAlertBox = () => { },
@@ -92,7 +93,6 @@ export const useCreateProduct = ({
92
93
  setSearchFilter({ ...filter })
93
94
  }
94
95
  const handleCheckFreeShipping = e => {
95
- // setCheck(e.target.checked)
96
96
  handleCheck(e)
97
97
  setValues({
98
98
  ...values,
@@ -100,7 +100,7 @@ export const useCreateProduct = ({
100
100
  })
101
101
  }
102
102
 
103
- const [updateProductFoods] = useMutation(UPDATE_PRODUCT_FOOD, {
103
+ const [updateProductFoods, { loading }] = useMutation(UPDATE_PRODUCT_FOOD, {
104
104
  })
105
105
  const [setImageProducts] = useMutation(UPDATE_IMAGE_PRODUCT_FOOD, {
106
106
  context: { clientName: 'admin-server' }
@@ -140,6 +140,7 @@ export const useCreateProduct = ({
140
140
  ValueDelivery,
141
141
  carProId
142
142
  } = values
143
+ const formatPrice = ProPrice ? parseFloat(ProPrice?.replace(/\./g, '')) : 0
143
144
  if (!carProId && !names) return setErrors({ ...errors, carProId: true })
144
145
 
145
146
  if (!ProPrice?.length > 0) {
@@ -147,7 +148,6 @@ export const useCreateProduct = ({
147
148
  }
148
149
  const ProImage = `https:${process.env.URL_ADMIN_SERVER}static/platos/${image?.name}`
149
150
  const pCode = RandomCode(9)
150
- const formatPrice = ProPrice ? parseFloat(ProPrice.replace(/\./g, '')) : 0
151
151
  try {
152
152
  updateProductFoods({
153
153
  variables: {
@@ -207,7 +207,7 @@ export const useCreateProduct = ({
207
207
  nameTag: tags.tag,
208
208
  pId
209
209
  }
210
- handleRegisterTags(objTag)
210
+ if (tags?.tag) handleRegisterTags(objTag)
211
211
  setValues({})
212
212
  }).catch(err => {
213
213
  return sendNotification({
@@ -265,6 +265,7 @@ export const useCreateProduct = ({
265
265
  pId,
266
266
  dataTags: data,
267
267
  tags,
268
+ loading,
268
269
  active,
269
270
  idStore: dataStore?.getStore?.idStore || '',
270
271
  arrTags,
@@ -277,6 +278,7 @@ export const useCreateProduct = ({
277
278
  onClickSearch,
278
279
  changeHandler,
279
280
  setErrors,
281
+ setCheck,
280
282
  handleRegister,
281
283
  setActive,
282
284
  onFileInputChange,
@@ -0,0 +1,13 @@
1
+ import { useMutation } from '@apollo/client'
2
+ import { CREATE_STORE_PENDING_TO_REGISTER } from './queries'
3
+
4
+ export function useCreateStorePendingToRegister () {
5
+ const [createStorePendingToRegister, { data, loading, error }] = useMutation(CREATE_STORE_PENDING_TO_REGISTER)
6
+
7
+ return {
8
+ createStorePendingToRegister,
9
+ data,
10
+ loading,
11
+ error
12
+ }
13
+ }
@@ -0,0 +1,10 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const CREATE_STORE_PENDING_TO_REGISTER = gql`
4
+ mutation createStorePendingToRegister($input: StorePendingToRegisterInput) {
5
+ createStorePendingToRegister(input: $input) {
6
+ success
7
+ message
8
+ }
9
+ }
10
+ `
@@ -0,0 +1,13 @@
1
+ import { useLazyQuery } from '@apollo/client'
2
+ import { GET_ALL_DEPARTMENTS } from './queries'
3
+
4
+ /**
5
+ * Custom hook to fetch departments lazily based on the provided company ID.
6
+ *
7
+ * @returns {Array} - Returns an array containing a function to execute the query, and an object containing data and any associated query state/error.
8
+ */
9
+ export function useDepartments () {
10
+ const [getDepartments, { data, loading, error }] = useLazyQuery(GET_ALL_DEPARTMENTS)
11
+
12
+ return [getDepartments, { data: data ? data?.departments : [], loading, error }]
13
+ }
@@ -0,0 +1,12 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ export const GET_ALL_DEPARTMENTS = gql`
4
+ query getAllDepartments($cId: ID!) {
5
+ departments(cId: $cId) {
6
+ dId
7
+ cId
8
+ dName
9
+ dState
10
+ }
11
+ }
12
+ `
@@ -25,6 +25,9 @@ export const useDessert = ({
25
25
  const [title, setTitle] = useState('') // State for title input value
26
26
  // Initialize the data state with the transformedData or MockData
27
27
  const [data, setData] = useState(MockData)
28
+ const handleCleanData = () => {
29
+ setData(MockData)
30
+ }
28
31
  const dataListIds = data?.listIds?.filter(x => x !== '01list')
29
32
 
30
33
  /**
@@ -56,11 +59,11 @@ export const useDessert = ({
56
59
  if (initialData) {
57
60
  // Only update the data state if it's different from initialData
58
61
  if (JSON.stringify(data) !== JSON.stringify(transformDataToDessert(initialData))) {
59
- const transformedInitialData = transformDataToDessert(initialData);
60
- setData(transformedInitialData);
62
+ const transformedInitialData = transformDataToDessert(initialData)
63
+ setData(transformedInitialData)
61
64
  }
62
65
  }
63
- }, [initialData]); // Include data as a dependency
66
+ }, [initialData]) // Include data as a dependency
64
67
 
65
68
  // Filter the 'listIds' from 'data' and store the filtered result in 'dataListIds'
66
69
  // Here, it seems to exclude a specific list ID ('01list') from the listIds.
@@ -207,51 +210,51 @@ export const useDessert = ({
207
210
  title = null
208
211
  }) => {
209
212
  try {
210
- setSelectedItem(() => {
211
- return { listID, id }
212
- })
213
- const currentList = data.lists[listID];
214
- const findItem = currentList?.cards?.find(item => item.id === id)
215
- const checkDifferentText = findItem?.title !== title
216
- if (title && checkDifferentText) {
217
- editExtFoodSubsOptional({
218
- variables: {
219
- isCustomSubOpExPid: false,
220
- opSubExPid: id,
221
- OptionalSubProName: title
222
- }
223
- }).then(({ data: response }) => {
224
- const { editExtFoodSubsOptional } = response || {}
225
- const { success } = editExtFoodSubsOptional || { success: false }
226
- if (success) {
227
- sendNotification({
228
- description: 'El sub item actualizado con exito',
229
- title: 'Actualizado',
230
- backgroundColor: 'success'
231
- })
232
- const currentList = data.lists[listID];
233
- const updatedCards = currentList?.cards?.map((card) => {
234
- if (card.id === id) {
235
- return {
236
- ...card,
237
- title: title
238
- };
213
+ setSelectedItem(() => {
214
+ return { listID, id }
215
+ })
216
+ const currentList = data.lists[listID]
217
+ const findItem = currentList?.cards?.find(item => item.id === id)
218
+ const checkDifferentText = findItem?.title !== title
219
+ if (title && checkDifferentText) {
220
+ editExtFoodSubsOptional({
221
+ variables: {
222
+ isCustomSubOpExPid: false,
223
+ opSubExPid: id,
224
+ OptionalSubProName: title
225
+ }
226
+ }).then(({ data: response }) => {
227
+ const { editExtFoodSubsOptional } = response || {}
228
+ const { success } = editExtFoodSubsOptional || { success: false }
229
+ if (success) {
230
+ sendNotification({
231
+ description: 'El sub item actualizado con exito',
232
+ title: 'Actualizado',
233
+ backgroundColor: 'success'
234
+ })
235
+ const currentList = data.lists[listID]
236
+ const updatedCards = currentList?.cards?.map((card) => {
237
+ if (card.id === id) {
238
+ return {
239
+ ...card,
240
+ title
239
241
  }
240
- return card;
241
- });
242
- setData({
243
- listIds: [...data.listIds],
244
- lists: {
245
- ...data.lists,
246
- [listID]: {
247
- ...currentList,
248
- cards: updatedCards
249
- }
242
+ }
243
+ return card
244
+ })
245
+ setData({
246
+ listIds: [...data.listIds],
247
+ lists: {
248
+ ...data.lists,
249
+ [listID]: {
250
+ ...currentList,
251
+ cards: updatedCards
250
252
  }
251
- });
252
- }
253
- })
254
- }
253
+ }
254
+ })
255
+ }
256
+ })
257
+ }
255
258
  } catch (error) {
256
259
  console.error(error)
257
260
  }
@@ -267,15 +270,15 @@ export const useDessert = ({
267
270
  ...prevData.lists[listId],
268
271
  ...updatedFields
269
272
  }
270
- };
273
+ }
271
274
 
272
275
  return {
273
276
  ...prevData,
274
277
  lists: updatedLists
275
- };
276
- });
277
- };
278
- /**
278
+ }
279
+ })
280
+ }
281
+ /**
279
282
  * Edit a extra.
280
283
  * @async
281
284
  * @param {Object} options - Opciones para la edición del extra.
@@ -294,7 +297,7 @@ export const useDessert = ({
294
297
  }) => {
295
298
  try {
296
299
  if (id) {
297
- const response = await handleUpdateExtProduct({
300
+ const response = await handleUpdateExtProduct({
298
301
  opExPid: id,
299
302
  code: id,
300
303
  OptionalProName: title,
@@ -302,11 +305,13 @@ export const useDessert = ({
302
305
  numbersOptionalOnly: numberLimit
303
306
  })
304
307
  const { data } = response || {}
305
- if (!data?.updateExtProductFoodsOptional) return sendNotification({
306
- description: 'Ocurrió un error, intenta de nuevo',
307
- title: 'Error',
308
- backgroundColor: 'warning'
309
- })
308
+ if (!data?.updateExtProductFoodsOptional) {
309
+ return sendNotification({
310
+ description: 'Ocurrió un error, intenta de nuevo',
311
+ title: 'Error',
312
+ backgroundColor: 'warning'
313
+ })
314
+ }
310
315
  const { success, message } = data?.updateExtProductFoodsOptional || {}
311
316
  if (success) {
312
317
  setSelectedExtra({})
@@ -317,18 +322,20 @@ export const useDessert = ({
317
322
  backgroundColor: 'success'
318
323
  })
319
324
  return updateListById(id, {
320
- title: title,
321
- numberLimit: numberLimit,
325
+ title,
326
+ numberLimit,
322
327
  required: required ? 1 : 0
323
- });
328
+ })
324
329
  }
325
330
  }
326
331
 
327
- if (!id) return sendNotification({
328
- description: 'Ocurrió un error, intenta de nuevo',
329
- title: 'Error',
330
- backgroundColor: 'warning'
331
- })
332
+ if (!id) {
333
+ return sendNotification({
334
+ description: 'Ocurrió un error, intenta de nuevo',
335
+ title: 'Error',
336
+ backgroundColor: 'warning'
337
+ })
338
+ }
332
339
  } catch (error) {
333
340
  setSelectedExtra({})
334
341
  setOpenModalEditExtra(false)
@@ -384,7 +391,7 @@ export const useDessert = ({
384
391
  // Check if the title is not empty
385
392
  if (title.trim() === '') {
386
393
  sendNotification({
387
- description: 'El titulo no debe estar vacio',
394
+ description: 'El titulo no debe estar vacío',
388
395
  title: 'Error',
389
396
  backgroundColor: 'warning'
390
397
  })
@@ -471,11 +478,12 @@ export const useDessert = ({
471
478
  setCheck,
472
479
  selectedItem,
473
480
  setData,
481
+ handleCleanData,
474
482
  setTitle,
475
483
  title,
476
484
  selectedExtra,
477
485
  openModalEditExtra,
478
486
  setSelectedExtra,
479
- setOpenModalEditExtra,
487
+ setOpenModalEditExtra
480
488
  }
481
489
  }
@@ -0,0 +1,61 @@
1
+ import { useState } from 'react'
2
+
3
+ /**
4
+ * Hook para gestionar la lógica de ubicaciones, valores y errores.
5
+ *
6
+ * @param {Function} getDepartments - Función para obtener los departamentos basado en el ID de país.
7
+ * @param {Function} getCities - Función para obtener las ciudades basado en el ID de departamento.
8
+ *
9
+ * @returns {Object} - Retorna los estados y funciones de manejo asociados.
10
+ */
11
+ export function useLocationManager (getDepartments, getCities) {
12
+ const [values, setValues] = useState({})
13
+ const [errors, setErrors] = useState({})
14
+ const [showLocation, setShowLocation] = useState(true)
15
+
16
+ const handleUpdateValues = (name, value) => {
17
+ setValues(prevValues => ({ ...prevValues, [name]: value }))
18
+ }
19
+
20
+ const handleUpdateErrors = (name, error) => {
21
+ setErrors(prevErrors => ({ ...prevErrors, [name]: error }))
22
+ }
23
+
24
+ const handleCountrySearch = (value) => {
25
+ getDepartments({ variables: { cId: value } })
26
+ }
27
+
28
+ const handleDepartmentSearch = (value) => {
29
+ getCities({ variables: { dId: value } })
30
+ }
31
+
32
+ const handleChangeLocation = (e, error) => {
33
+ const { name, value } = e.target
34
+ handleUpdateValues(name, value)
35
+ handleUpdateErrors(name, error)
36
+ }
37
+
38
+ const handleChangeSearch = (e) => {
39
+ const { name, value } = e.target
40
+ switch (name) {
41
+ case 'countryId':
42
+ handleCountrySearch(value)
43
+ break
44
+ case 'dId':
45
+ handleDepartmentSearch(value)
46
+ break
47
+ default:
48
+ break
49
+ }
50
+ handleChangeLocation(e)
51
+ }
52
+
53
+ return {
54
+ values,
55
+ errors,
56
+ showLocation,
57
+ setShowLocation,
58
+ handleChangeSearch,
59
+ setValues
60
+ }
61
+ }
@@ -5,7 +5,6 @@ import {
5
5
  } from '@apollo/client'
6
6
  import { useState } from 'react'
7
7
  import {
8
- GET_ALL_CATEGORIES_WITH_PRODUCT,
9
8
  GET_ALL_EXTRA_PRODUCT,
10
9
  GET_ALL_PRODUCT_STORE,
11
10
  GET_EXTRAS_PRODUCT_FOOD_OPTIONAL,
@@ -84,7 +83,8 @@ export const useDeleteProductsFood = ({ sendNotification = () => { } } = {}) =>
84
83
  pId,
85
84
  pState
86
85
  }
87
- }, update (cache) {
86
+ },
87
+ update (cache) {
88
88
  cache.modify({
89
89
  fields: {
90
90
  productFoodsAll (dataOld = []) {
@@ -94,7 +94,7 @@ export const useDeleteProductsFood = ({ sendNotification = () => { } } = {}) =>
94
94
  })
95
95
  if (product) {
96
96
  const newProductList = dataOld?.filter((product) => {
97
- return product?.pId !== pId
97
+ return product?.pId !== pId
98
98
  })
99
99
  return newProductList
100
100
  }
@@ -108,21 +108,23 @@ export const useDeleteProductsFood = ({ sendNotification = () => { } } = {}) =>
108
108
  cache.modify({
109
109
  fields: {
110
110
  getCatProductsWithProduct (dataOld = []) {
111
- if (Array.isArray(dataOld?.catProductsWithProduct) && dataOld?.catProductsWithProduct?.length) {
112
- const newListCatProducts = dataOld?.catProductsWithProduct?.map((categories) => {
113
- return {
114
- ...categories,
115
- productFoodsAll: categories?.productFoodsAll?.length ? categories?.productFoodsAll?.filter((product) => {
116
- return product?.pId !== pId
117
- }) : []
118
- }
119
- })
111
+ if (Array.isArray(dataOld?.catProductsWithProduct) && dataOld?.catProductsWithProduct?.length) {
112
+ const newListCatProducts = dataOld?.catProductsWithProduct?.map((categories) => {
120
113
  return {
121
- catProductsWithProduct: newListCatProducts,
122
- totalCount: newListCatProducts?.length,
114
+ ...categories,
115
+ productFoodsAll: categories?.productFoodsAll?.length
116
+ ? categories?.productFoodsAll?.filter((product) => {
117
+ return product?.pId !== pId
118
+ })
119
+ : []
123
120
  }
121
+ })
122
+ return {
123
+ catProductsWithProduct: newListCatProducts,
124
+ totalCount: newListCatProducts?.length
124
125
  }
125
- return dataOld
126
+ }
127
+ return dataOld
126
128
  }
127
129
  }
128
130
  })
@@ -0,0 +1,114 @@
1
+ /* eslint-disable consistent-return */
2
+ const pushServerPublicKey = 'BIN2Jc5Vmkmy-S3AUrcMlpKxJpLeVRAfu9WBqUbJ70SJOCWGCGXKY-Xzyh7HDr6KbRDGYHjqZ06OcS3BjD7uAm8'
3
+
4
+ /**
5
+ * checks if Push notification and service workers are supported by your browser
6
+ */
7
+ function isPushNotificationSupported () {
8
+ if (typeof window !== 'undefined' && window.Notification && window.ServiceWorker) {
9
+ return 'serviceWorker' in navigator && 'PushManager' in window
10
+ }
11
+ }
12
+
13
+ /**
14
+ * asks user consent to receive push notifications and returns the response of the user, one of granted, default, denied
15
+ */
16
+ async function askUserPermission () {
17
+ return await Notification.requestPermission()
18
+ }
19
+ /**
20
+ * shows a notification
21
+ */
22
+ function sendNotification () {
23
+ const img = '/images/jason-leung-HM6TMmevbZQ-unsplash.jpg'
24
+ const text = 'Take a look at this brand new t-shirt!'
25
+ const title = 'New Product Available'
26
+ const options = {
27
+ body: text,
28
+ icon: '/images/jason-leung-HM6TMmevbZQ-unsplash.jpg',
29
+ vibrate: [200, 100, 200],
30
+ tag: 'new-product',
31
+ image: img,
32
+ badge: 'https://spyna.it/icons/android-icon-192x192.png',
33
+ actions: [{ action: 'Detail', title: 'View', icon: 'https://via.placeholder.com/128/ff0000' }]
34
+ }
35
+ navigator.serviceWorker.ready.then(function (serviceWorker) {
36
+ serviceWorker.showNotification(title, options)
37
+ })
38
+ }
39
+
40
+ /**
41
+ *
42
+ */
43
+ function registerServiceWorker () {
44
+ return navigator.serviceWorker.register('/sw.js')
45
+ }
46
+
47
+ /**
48
+ *
49
+ * using the registered service worker creates a push notification subscription and returns it
50
+ *
51
+ */
52
+ async function createNotificationSubscription () {
53
+ // wait for service worker installation to be ready
54
+ const serviceWorker = await navigator.serviceWorker.ready
55
+ // subscribe and return the subscription
56
+ return await serviceWorker.pushManager.subscribe({
57
+ userVisibleOnly: true,
58
+ applicationServerKey: pushServerPublicKey
59
+ })
60
+ }
61
+
62
+ /**
63
+ * returns the subscription if present or nothing
64
+ */
65
+ function getUserSubscription () {
66
+ // wait for service worker installation to be ready, and then
67
+ return navigator.serviceWorker.ready
68
+ .then(function (serviceWorker) {
69
+ return serviceWorker.pushManager.getSubscription()
70
+ })
71
+ .then(function (pushSubscription) {
72
+ return pushSubscription
73
+ })
74
+ }
75
+
76
+ const host = process.env.NODE_ENV === 'production' ? 'http://localhost:4000' : 'http://localhost:4000'
77
+
78
+ function post (path, body) {
79
+ return fetch(`${host}${path}`, {
80
+ body: JSON.stringify(body),
81
+ method: 'POST',
82
+ mode: 'cors'
83
+ })
84
+ .then(function (response) {
85
+ return response.json()
86
+ })
87
+ .then(function (data) {
88
+ return data
89
+ })
90
+ }
91
+
92
+ function get (path) {
93
+ return fetch(`${host}${path}`, {
94
+ method: 'GET',
95
+ mode: 'cors'
96
+ })
97
+ .then(function (response) {
98
+ return response.json()
99
+ })
100
+ .then(function (data) {
101
+ return data
102
+ })
103
+ }
104
+
105
+ export {
106
+ isPushNotificationSupported,
107
+ askUserPermission,
108
+ post,
109
+ get,
110
+ registerServiceWorker,
111
+ sendNotification,
112
+ createNotificationSubscription,
113
+ getUserSubscription
114
+ }
@@ -0,0 +1,149 @@
1
+ /* eslint-disable no-console */
2
+ import { useState, useEffect } from 'react'
3
+ import {
4
+ isPushNotificationSupported,
5
+ post,
6
+ get,
7
+ askUserPermission,
8
+ registerServiceWorker,
9
+ createNotificationSubscription,
10
+ getUserSubscription
11
+ } from './helpers'
12
+ // import all the function created to manage the push notifications
13
+
14
+ const pushNotificationSupported = isPushNotificationSupported()
15
+ // first thing to do: check if the push notifications are supported by the browser
16
+
17
+ export const usePushNotifications = () => {
18
+ const [userConsent, setSuserConsent] = useState()
19
+ useEffect(() => {
20
+ if (typeof Notification !== 'undefined') {
21
+ setSuserConsent(Notification.permission)
22
+ }
23
+ }, [])
24
+
25
+ // to manage the user consent: Notification.permission is a JavaScript native function that return the current state of the permission
26
+ // We initialize the userConsent with that value
27
+ const [userSubscription, setUserSubscription] = useState(null)
28
+ // to manage the use push notification subscription
29
+ const [pushServerSubscriptionId, setPushServerSubscriptionId] = useState()
30
+ // to manage the push server subscription
31
+ const [error, setError] = useState(null)
32
+ // to manage errors
33
+ const [loading, setLoading] = useState(true)
34
+ // to manage async actions
35
+
36
+ useEffect(() => {
37
+ if (pushNotificationSupported) {
38
+ setLoading(true)
39
+ setError(false)
40
+ registerServiceWorker().then(() => {
41
+ setLoading(false)
42
+ })
43
+ }
44
+ }, [])
45
+ // if the push notifications are supported, registers the service worker
46
+ // this effect runs only the first render
47
+
48
+ useEffect(() => {
49
+ setLoading(true)
50
+ setError(false)
51
+ const getExixtingSubscription = async () => {
52
+ const existingSubscription = await getUserSubscription()
53
+ setUserSubscription(existingSubscription)
54
+ setLoading(false)
55
+ }
56
+ getExixtingSubscription()
57
+ }, [])
58
+ // Retrieve if there is any push notification subscription for the registered service worker
59
+ // this use effect runs only in the first render
60
+
61
+ /**
62
+ * define a click handler that asks the user permission,
63
+ * it uses the setSuserConsent state, to set the consent of the user
64
+ * If the user denies the consent, an error is created with the setError hook
65
+ */
66
+ const onClickAskUserPermission = () => {
67
+ setLoading(true)
68
+ setError(false)
69
+ askUserPermission().then(consent => {
70
+ setSuserConsent(consent)
71
+ if (consent !== 'granted') {
72
+ setError({
73
+ name: 'consentimiento denegado',
74
+ message: 'Negaste el consentimiento para recibir notificaciones',
75
+ code: 0
76
+ })
77
+ }
78
+ setLoading(false)
79
+ })
80
+ }
81
+ //
82
+
83
+ /**
84
+ * define a click handler that creates a push notification subscription.
85
+ * Once the subscription is created, it uses the setUserSubscription hook
86
+ */
87
+ const onClickSusbribeToPushNotification = () => {
88
+ setLoading(true)
89
+ setError(false)
90
+ createNotificationSubscription()
91
+ .then(function (subscrition) {
92
+ setUserSubscription(subscrition)
93
+ setLoading(false)
94
+ })
95
+ .catch(err => {
96
+ console.error("Couldn't create the notification subscription", err, 'name:', err.name, 'message:', err.message, 'code:', err.code)
97
+ setError(err)
98
+ setLoading(false)
99
+ })
100
+ }
101
+
102
+ /**
103
+ * define a click handler that sends the push susbcribtion to the push server.
104
+ * Once the subscription ics created on the server, it saves the id using the hook setPushServerSubscriptionId
105
+ */
106
+ const onClickSendSubscriptionToPushServer = () => {
107
+ setLoading(true)
108
+ setError(false)
109
+ post('/subscription2', userSubscription)
110
+ .then(function (response) {
111
+ setPushServerSubscriptionId(response.id)
112
+ setLoading(false)
113
+ })
114
+ .catch(err => {
115
+ setLoading(false)
116
+ setError(err)
117
+ })
118
+ }
119
+
120
+ /**
121
+ * define a click handler that request the push server to send a notification, passing the id of the saved subscription
122
+ */
123
+ const onClickSendNotification = async () => {
124
+ setLoading(true)
125
+ setError(false)
126
+ console.log(pushServerSubscriptionId)
127
+ await get(`/subscription/${pushServerSubscriptionId}`).catch(err => {
128
+ setLoading(false)
129
+ setError(err)
130
+ })
131
+ setLoading(false)
132
+ }
133
+
134
+ /**
135
+ * returns all the stuff needed by a Component
136
+ */
137
+ return {
138
+ onClickAskUserPermission,
139
+ onClickSusbribeToPushNotification,
140
+ onClickSendSubscriptionToPushServer,
141
+ pushServerSubscriptionId,
142
+ onClickSendNotification,
143
+ userConsent,
144
+ pushNotificationSupported,
145
+ userSubscription,
146
+ error,
147
+ loading
148
+ }
149
+ }
@@ -0,0 +1,19 @@
1
+ import { useQuery } from '@apollo/client'
2
+ import { GET_ALL_ROAD } from './queries'
3
+
4
+ /**
5
+ * Custom hook to fetch all roads.
6
+ *
7
+ * @returns {Object} - Returns an object containing road data and any associated query state/error.
8
+ */
9
+ export function useRoads () {
10
+ const { data, loading, error } = useQuery(GET_ALL_ROAD)
11
+
12
+ // Here, you can handle any additional logic you might need, like mapping data, handling errors, etc.
13
+
14
+ return {
15
+ data: data || [],
16
+ loading,
17
+ error
18
+ }
19
+ }
@@ -0,0 +1,13 @@
1
+ import { gql } from '@apollo/client'
2
+
3
+ export const GET_ALL_ROAD = gql`
4
+ query getTypeRoad{
5
+ road{
6
+ rId
7
+ rName
8
+ rState
9
+ rDatCre
10
+ rDatMod
11
+ }
12
+ }
13
+ `
@@ -13,11 +13,15 @@ export const useSaveAvailableProduct = () => {
13
13
  setSelectedDays([...selectedDays, day])
14
14
  }
15
15
  }
16
+ const handleCleanSelectedDays = () => {
17
+ setSelectedDays([])
18
+ }
16
19
  const [registerAvailableProduct, { loading }] = useMutation(CREATE_AVAILABLE_PRODUCTS_DAYS, {
17
20
  onError: () => { return console.log({ message: 'Lo sentimos ocurrió un error, vuelve a intentarlo' }) }
18
21
  })
19
22
  return {
20
23
  handleDaySelection,
24
+ handleCleanSelectedDays,
21
25
  selectedDays,
22
26
  days,
23
27
  Loading: loading,