npm-pkg-hook 1.0.0 → 1.0.1
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/.babelrc +14 -0
- package/.eslintrc.json +108 -0
- package/README.md +1 -0
- package/jsconfig.json +28 -0
- package/next.config.js +129 -0
- package/package.json +26 -4
- package/src/cookies/index.ts +3 -0
- package/src/hooks/index.js +15 -0
- package/src/hooks/useAcumulateDate/index.js +16 -0
- package/src/hooks/useAnimationText/index.jsx +30 -0
- package/src/hooks/useCategoryStore/index.js +7 -0
- package/src/hooks/useCategoryStore/queries.js +16 -0
- package/src/hooks/useDrag/index.js +57 -0
- package/src/hooks/useEvent/index.js +33 -0
- package/src/hooks/useFetchJson/index.js +25 -0
- package/src/hooks/useFetchMoreInteractions/index.jsx +35 -0
- package/src/hooks/useFormTools/index.js +71 -0
- package/src/hooks/useFullScreenMode/index.js +66 -0
- package/src/hooks/useGetCategorieStore/index.js +21 -0
- package/src/hooks/useGetCategorieStore/queries.js +78 -0
- package/src/hooks/useHover/index.js +29 -0
- package/src/hooks/useInnerHtml/index.js +38 -0
- package/src/hooks/useIntersection/index.js +31 -0
- package/src/hooks/useKeypress/index.js +28 -0
- package/src/hooks/useLocalSorage/index.js +36 -0
- package/src/hooks/useLocationNavigate/index.js +54 -0
- package/src/hooks/useRestaurant/index.js +19 -0
- package/src/hooks/useRestaurant/queries.js +70 -0
- package/src/hooks/useSetState/index.js +24 -0
- package/src/hooks/useTimeAgo/useTimeAgo.js +39 -0
- package/src/hooks/useUpdateCart/index.js +123 -0
- package/src/hooks/useUser/index.js +3 -0
- package/src/hooks/useWindowSize/index.js +38 -0
- package/src/index.jsx +1 -6
- package/src/utils/index.js +27 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react'
|
|
2
|
+
import styled from 'styled-components'
|
|
3
|
+
|
|
4
|
+
const useFullscreenMode = () => {
|
|
5
|
+
const [isFullscreen, setFullscreen] = useState(false)
|
|
6
|
+
const elementRef = useRef()
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const changeHandler = () => {return setFullscreen(mode => {return !mode})}
|
|
10
|
+
|
|
11
|
+
document.addEventListener('fullscreenchange', changeHandler, false)
|
|
12
|
+
document.addEventListener('mozfullscreenchange', changeHandler, false)
|
|
13
|
+
document.addEventListener('MSFullScreenChange', changeHandler, false)
|
|
14
|
+
document.addEventListener(
|
|
15
|
+
'webkitfullscreenchange',
|
|
16
|
+
changeHandler,
|
|
17
|
+
false
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
document.removeEventListener('fullscreenchange', changeHandler)
|
|
22
|
+
document.removeEventListener('mozfullscreenchange', changeHandler)
|
|
23
|
+
document.removeEventListener('MSFullScreenChange', changeHandler)
|
|
24
|
+
document.removeEventListener(
|
|
25
|
+
'webkitfullscreenchange',
|
|
26
|
+
changeHandler
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
}, [])
|
|
30
|
+
|
|
31
|
+
const goFullscreen = () => {
|
|
32
|
+
if (elementRef.current.requestFullscreen) {
|
|
33
|
+
elementRef.current.requestFullscreen()
|
|
34
|
+
} else if (elementRef.current.mozRequestFullscreen) {
|
|
35
|
+
//Firefox
|
|
36
|
+
elementRef.current.mozRequestFullscreen()
|
|
37
|
+
} else if (elementRef.current.webkitRequestFullscreen) {
|
|
38
|
+
//Chrome, safari, opera
|
|
39
|
+
elementRef.current.webkitRequestFullscreen()
|
|
40
|
+
} else if (elementRef.current.msRequestFullscreen) {
|
|
41
|
+
//IE, edge
|
|
42
|
+
elementRef.current.msRequestFullscreen()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const exitFullScreen = () => {
|
|
47
|
+
if (document.exitFullscreen) {
|
|
48
|
+
document.exitFullscreen()
|
|
49
|
+
} else if (document.mozCancelFullScreen) {
|
|
50
|
+
document.mozCancelFullScreen()
|
|
51
|
+
} else if (document.webkitExitFullscreen) {
|
|
52
|
+
document.webkitExitFullscreen()
|
|
53
|
+
} else if (document.msExitFullscreen) {
|
|
54
|
+
document.msExitFullscreen()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const ToggleIcon = (
|
|
59
|
+
<Button onDoubleClick={() => {return (!isFullscreen ? goFullscreen() : exitFullScreen())}}>{!isFullscreen ? 'FullScreen' : 'Normal'}</Button>
|
|
60
|
+
)
|
|
61
|
+
return [elementRef, ToggleIcon] //Icon, ref
|
|
62
|
+
}
|
|
63
|
+
const Button = styled.button`
|
|
64
|
+
|
|
65
|
+
`
|
|
66
|
+
export default useFullscreenMode
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client'
|
|
2
|
+
import { useEffect, useState } from 'react'
|
|
3
|
+
import { GET_ONE_STORE_IN_CATEGORY } from './queries'
|
|
4
|
+
|
|
5
|
+
export const useGetCategorieStore = ({ catStoreId }) => {
|
|
6
|
+
|
|
7
|
+
const { data: dataCatSto, loading, error } = useQuery(GET_ONE_STORE_IN_CATEGORY, {
|
|
8
|
+
variables: {
|
|
9
|
+
catStore: catStoreId
|
|
10
|
+
},
|
|
11
|
+
onError: () => {
|
|
12
|
+
console.log({ message: '', duration: 5000 })
|
|
13
|
+
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
const [categories, setCategorieStore] = useState([])
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setCategorieStore(dataCatSto?.getOneCatStore || [])
|
|
19
|
+
}, [dataCatSto])
|
|
20
|
+
return [categories, { loading, error }]
|
|
21
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { gql } from "@apollo/client";
|
|
2
|
+
|
|
3
|
+
export const GET_ONE_STORE_IN_CATEGORY = gql`
|
|
4
|
+
query getOneCatStore($catStore: ID){
|
|
5
|
+
getOneCatStore(catStore: $catStore){
|
|
6
|
+
catStore
|
|
7
|
+
idUser
|
|
8
|
+
cName
|
|
9
|
+
cState
|
|
10
|
+
cDatCre
|
|
11
|
+
cPathImage
|
|
12
|
+
cDatMod
|
|
13
|
+
csDescription
|
|
14
|
+
getAllStore {
|
|
15
|
+
idStore
|
|
16
|
+
cId
|
|
17
|
+
id
|
|
18
|
+
dId
|
|
19
|
+
ctId
|
|
20
|
+
catStore
|
|
21
|
+
neighborhoodStore
|
|
22
|
+
Viaprincipal
|
|
23
|
+
storeOwner
|
|
24
|
+
storeName
|
|
25
|
+
emailStore
|
|
26
|
+
storePhone
|
|
27
|
+
socialRaz
|
|
28
|
+
Image
|
|
29
|
+
banner
|
|
30
|
+
documentIdentifier
|
|
31
|
+
uPhoNum
|
|
32
|
+
ULocation
|
|
33
|
+
upLat
|
|
34
|
+
upLon
|
|
35
|
+
uState
|
|
36
|
+
siteWeb
|
|
37
|
+
description
|
|
38
|
+
NitStore
|
|
39
|
+
typeRegiments
|
|
40
|
+
typeContribute
|
|
41
|
+
secVia
|
|
42
|
+
addressStore
|
|
43
|
+
createdAt
|
|
44
|
+
pais {
|
|
45
|
+
cId
|
|
46
|
+
cName
|
|
47
|
+
cCalCod
|
|
48
|
+
cState
|
|
49
|
+
cDatCre
|
|
50
|
+
cDatMod
|
|
51
|
+
}
|
|
52
|
+
city {
|
|
53
|
+
ctId
|
|
54
|
+
dId
|
|
55
|
+
cName
|
|
56
|
+
cState
|
|
57
|
+
cDatCre
|
|
58
|
+
cDatMod
|
|
59
|
+
}
|
|
60
|
+
department {
|
|
61
|
+
dId
|
|
62
|
+
cId
|
|
63
|
+
dName
|
|
64
|
+
dState
|
|
65
|
+
dDatCre
|
|
66
|
+
dDatMod
|
|
67
|
+
}
|
|
68
|
+
getAllRatingStar {
|
|
69
|
+
rSId
|
|
70
|
+
rScore
|
|
71
|
+
idStore
|
|
72
|
+
createAt
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
`
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useRef, useState, useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
export default function useHover() {
|
|
4
|
+
const [value, setValue] = useState(false)
|
|
5
|
+
|
|
6
|
+
const ref = useRef(null)
|
|
7
|
+
|
|
8
|
+
const handleMouseOver = () => {return setValue(true)}
|
|
9
|
+
const handleMouseOut = () => {return setValue(false)}
|
|
10
|
+
|
|
11
|
+
useEffect(
|
|
12
|
+
() => {
|
|
13
|
+
const node = ref.current
|
|
14
|
+
if (node) {
|
|
15
|
+
node.addEventListener('mouseover', handleMouseOver)
|
|
16
|
+
node.addEventListener('mouseout', handleMouseOut)
|
|
17
|
+
|
|
18
|
+
return () => {
|
|
19
|
+
node.removeEventListener('mouseover', handleMouseOver)
|
|
20
|
+
node.removeEventListener('mouseout', handleMouseOut)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return {}
|
|
24
|
+
},
|
|
25
|
+
[] // Recall only if ref changes
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return [ref, value]
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from 'react-dom'
|
|
3
|
+
import './styles.css'
|
|
4
|
+
|
|
5
|
+
const htmlText =
|
|
6
|
+
'<p style=\'display:inline;\'>Lorem ipsum</p> dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.'
|
|
7
|
+
|
|
8
|
+
function App() {
|
|
9
|
+
const [state, setState] = React.useState({
|
|
10
|
+
showOriginalHTML: false,
|
|
11
|
+
originalHTML: htmlText
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const handleShowText = React.useCallback(() => {
|
|
15
|
+
setState(prevState => {return {
|
|
16
|
+
...prevState,
|
|
17
|
+
showOriginalHTML: !prevState.showOriginalHTML
|
|
18
|
+
}})
|
|
19
|
+
}, [setState])
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className='container'>
|
|
23
|
+
<div
|
|
24
|
+
className='text'
|
|
25
|
+
dangerouslySetInnerHTML={{
|
|
26
|
+
__html: `${
|
|
27
|
+
state.originalHTML
|
|
28
|
+
}`
|
|
29
|
+
}}
|
|
30
|
+
/>
|
|
31
|
+
<button className='read-more' onClick={handleShowText}>
|
|
32
|
+
{!state.showOriginalHTML ? 'read more' : 'show less'}
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
render(<App />, document.getElementById('root'))
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
export const useOnScreen = (threshold = 0.6) => {
|
|
4
|
+
const [isVisible, setIsVisible] = useState(false)
|
|
5
|
+
const [ref, setRef] = useState(null)
|
|
6
|
+
|
|
7
|
+
useEffect(
|
|
8
|
+
() => {
|
|
9
|
+
let observer
|
|
10
|
+
if (ref) {
|
|
11
|
+
observer = new IntersectionObserver(
|
|
12
|
+
([entry]) => {
|
|
13
|
+
setIsVisible(entry.isIntersecting)
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
// rootMargin,
|
|
17
|
+
threshold
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
observer.observe(ref)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return () => {
|
|
24
|
+
if (ref && observer) observer.unobserve(ref)
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
[ref]
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
return [setRef, isVisible]
|
|
31
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
export const useKeyPress = (targetKey) => {
|
|
4
|
+
const [keyPressed, setKeyPressed] = useState(false)
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const downHandler = ({ key }) => {
|
|
8
|
+
if (key === targetKey) {
|
|
9
|
+
setKeyPressed(true)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const upHandler = ({ key }) => {
|
|
13
|
+
if (key === targetKey) {
|
|
14
|
+
setKeyPressed(false)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
window.addEventListener('keydown', downHandler)
|
|
19
|
+
window.addEventListener('keyup', upHandler)
|
|
20
|
+
|
|
21
|
+
return () => {
|
|
22
|
+
window.removeEventListener('keydown', downHandler)
|
|
23
|
+
window.removeEventListener('keyup', upHandler)
|
|
24
|
+
}
|
|
25
|
+
}, [targetKey])
|
|
26
|
+
|
|
27
|
+
return keyPressed
|
|
28
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
|
|
3
|
+
export default function useLocalStorage(key, initialValue) {
|
|
4
|
+
// const { setAlertBox } = useContext(Context)
|
|
5
|
+
// State to store our value
|
|
6
|
+
// Pass initial state function to useState so logic is only executed once
|
|
7
|
+
const [storedValue, setStoredValue] = useState(() => {
|
|
8
|
+
try {
|
|
9
|
+
// Get from local storage by key
|
|
10
|
+
const item = window.localStorage.getItem(key)
|
|
11
|
+
// Parse stored json or if none return initialValue
|
|
12
|
+
return item ? JSON.parse(item) : initialValue
|
|
13
|
+
} catch (error) {
|
|
14
|
+
// If error also return initialValue
|
|
15
|
+
return initialValue
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
// Return a wrapped version of useState's setter function that ...
|
|
20
|
+
// ... persists the new value to localStorage.
|
|
21
|
+
const setValue = value => {
|
|
22
|
+
try {
|
|
23
|
+
// Allow value to be a function so we have same API as useState
|
|
24
|
+
const valueToStore =
|
|
25
|
+
value instanceof Function ? value(storedValue) : value
|
|
26
|
+
// Save state
|
|
27
|
+
setStoredValue(valueToStore)
|
|
28
|
+
// Save to local storage
|
|
29
|
+
window.localStorage.setItem(key, JSON.stringify(valueToStore))
|
|
30
|
+
} catch (error) {
|
|
31
|
+
// A more advanced implementation would handle the error case
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return [storedValue, setValue]
|
|
36
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react'
|
|
2
|
+
|
|
3
|
+
const defaultSettings = {
|
|
4
|
+
enableHighAccuracy: false,
|
|
5
|
+
timeout: Infinity,
|
|
6
|
+
maximumAge: 0
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const usePosition = (watch = false, settings = defaultSettings) => {
|
|
10
|
+
const [position, setPosition] = useState({})
|
|
11
|
+
const [error, setError] = useState(null)
|
|
12
|
+
|
|
13
|
+
const onChange = ({ coords, timestamp }) => {
|
|
14
|
+
setPosition({
|
|
15
|
+
latitude: coords.latitude,
|
|
16
|
+
longitude: coords.longitude,
|
|
17
|
+
accuracy: coords.accuracy,
|
|
18
|
+
speed: coords.speed,
|
|
19
|
+
timestamp
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const onError = () => {
|
|
24
|
+
setError(error?.message)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!navigator || !navigator.geolocation) {
|
|
29
|
+
setError('Geolocation is not supported')
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let watcher = null
|
|
34
|
+
if (watch) {
|
|
35
|
+
watcher = navigator.geolocation.watchPosition(
|
|
36
|
+
onChange,
|
|
37
|
+
onError,
|
|
38
|
+
settings
|
|
39
|
+
)
|
|
40
|
+
} else {
|
|
41
|
+
navigator.geolocation.getCurrentPosition(onChange, onError, settings)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return () => { return watcher && navigator.geolocation.clearWatch(watcher) }
|
|
45
|
+
}, [
|
|
46
|
+
settings,
|
|
47
|
+
settings.enableHighAccuracy,
|
|
48
|
+
settings.timeout,
|
|
49
|
+
settings.maximumAge,
|
|
50
|
+
watch
|
|
51
|
+
])
|
|
52
|
+
|
|
53
|
+
return { ...position, error }
|
|
54
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client'
|
|
2
|
+
import { GET_ALL_RESTAURANT } from './queries'
|
|
3
|
+
|
|
4
|
+
export const useRestaurant = () => {
|
|
5
|
+
const {
|
|
6
|
+
data,
|
|
7
|
+
loading,
|
|
8
|
+
error,
|
|
9
|
+
fetchMore
|
|
10
|
+
} = useQuery(GET_ALL_RESTAURANT, {
|
|
11
|
+
fetchPolicy: 'cache-and-network',
|
|
12
|
+
notifyOnNetworkStatusChange: true,
|
|
13
|
+
nextFetchPolicy: 'cache-first',
|
|
14
|
+
refetchWritePolicy: 'merge',
|
|
15
|
+
context: { clientName: 'admin-store'
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
return [data, { loading, error, fetchMore }]
|
|
19
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { gql } from '@apollo/client'
|
|
2
|
+
export const GET_ALL_RESTAURANT = gql`
|
|
3
|
+
query getAllStoreInStore($search: String, $min: Int, $max: Int){
|
|
4
|
+
getAllStoreInStore(search: $search, min: $min, max: $max) {
|
|
5
|
+
idStore
|
|
6
|
+
cId
|
|
7
|
+
id
|
|
8
|
+
dId
|
|
9
|
+
ctId
|
|
10
|
+
catStore
|
|
11
|
+
neighborhoodStore
|
|
12
|
+
Viaprincipal
|
|
13
|
+
storeOwner
|
|
14
|
+
storeName
|
|
15
|
+
cateStore{
|
|
16
|
+
catStore
|
|
17
|
+
cName
|
|
18
|
+
}
|
|
19
|
+
emailStore
|
|
20
|
+
storePhone
|
|
21
|
+
socialRaz
|
|
22
|
+
Image
|
|
23
|
+
banner
|
|
24
|
+
documentIdentifier
|
|
25
|
+
uPhoNum
|
|
26
|
+
ULocation
|
|
27
|
+
upLat
|
|
28
|
+
upLon
|
|
29
|
+
uState
|
|
30
|
+
siteWeb
|
|
31
|
+
description
|
|
32
|
+
NitStore
|
|
33
|
+
typeRegiments
|
|
34
|
+
typeContribute
|
|
35
|
+
secVia
|
|
36
|
+
addressStore
|
|
37
|
+
createdAt
|
|
38
|
+
pais{
|
|
39
|
+
cId
|
|
40
|
+
cName
|
|
41
|
+
cCalCod
|
|
42
|
+
cState
|
|
43
|
+
cDatCre
|
|
44
|
+
cDatMod
|
|
45
|
+
}
|
|
46
|
+
city {
|
|
47
|
+
ctId
|
|
48
|
+
dId
|
|
49
|
+
cName
|
|
50
|
+
cState
|
|
51
|
+
cDatCre
|
|
52
|
+
cDatMod
|
|
53
|
+
}
|
|
54
|
+
department {
|
|
55
|
+
dId
|
|
56
|
+
cId
|
|
57
|
+
dName
|
|
58
|
+
dState
|
|
59
|
+
dDatCre
|
|
60
|
+
dDatMod
|
|
61
|
+
}
|
|
62
|
+
getAllRatingStar {
|
|
63
|
+
rSId
|
|
64
|
+
rScore
|
|
65
|
+
idStore
|
|
66
|
+
createAt
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
`
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
export const useSetState = initialState => {
|
|
4
|
+
const [state, setState] = useState(initialState)
|
|
5
|
+
const increase = () => {return setState(state + 1)}
|
|
6
|
+
const decrease = () => {return setState(state - 1)}
|
|
7
|
+
const reset = () => {return setState(0)}
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (state === -1) return reset()
|
|
10
|
+
return {}
|
|
11
|
+
}, [state])
|
|
12
|
+
// Cambio de estado
|
|
13
|
+
const changeState = () => {
|
|
14
|
+
setState(!state)
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
state,
|
|
18
|
+
increase,
|
|
19
|
+
decrease,
|
|
20
|
+
reset,
|
|
21
|
+
changeState,
|
|
22
|
+
setState
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
const DATE_UNITS = [
|
|
4
|
+
['day', 86400],
|
|
5
|
+
['hour', 3600],
|
|
6
|
+
['minute', 60],
|
|
7
|
+
['second', 1]
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
const getDateDiffs = (timestamp) => {
|
|
11
|
+
const now = Date.now()
|
|
12
|
+
const elapsed = (timestamp - now) / 1000
|
|
13
|
+
|
|
14
|
+
for (const [unit, secondsInUnit] of DATE_UNITS) {
|
|
15
|
+
if (Math.abs(elapsed) > secondsInUnit || unit === 'second') {
|
|
16
|
+
const value = Math.round(elapsed / secondsInUnit)
|
|
17
|
+
return { value, unit }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const useTimeAgo = (timestamp) => {
|
|
23
|
+
const [timeAgo, setTimeAgo] = useState(() => { return getDateDiffs(timestamp) })
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const interval = setInterval(() => {
|
|
27
|
+
const newTimeAgo = getDateDiffs(timestamp)
|
|
28
|
+
setTimeAgo(newTimeAgo)
|
|
29
|
+
}, 5000)
|
|
30
|
+
|
|
31
|
+
return () => { return clearInterval(interval) }
|
|
32
|
+
}, [timestamp])
|
|
33
|
+
|
|
34
|
+
const rtf = new Intl.RelativeTimeFormat('es', { style: 'short' })
|
|
35
|
+
|
|
36
|
+
const { value, unit } = timeAgo
|
|
37
|
+
|
|
38
|
+
return rtf && rtf?.format(value, unit)
|
|
39
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import debounce from 'lodash.debounce'
|
|
2
|
+
import { useState } from 'react'
|
|
3
|
+
import { useEffect } from 'react'
|
|
4
|
+
import { getCurrentDomain } from '../../utils'
|
|
5
|
+
import { trigger } from '../useEvent'
|
|
6
|
+
// EXAMPLE
|
|
7
|
+
// https://codesandbox.io/s/nextjs-cart-system-tfg1e?file=/pages/_app.js
|
|
8
|
+
|
|
9
|
+
// Method to execute the event to add all items of the app.cart cookie
|
|
10
|
+
const updateCart = debounce((items = []) => {
|
|
11
|
+
trigger({ eventType: 'app.cart', data: { loading: true, items } })
|
|
12
|
+
}, 3000)
|
|
13
|
+
|
|
14
|
+
const EMPTY_CART = {
|
|
15
|
+
items: [],
|
|
16
|
+
total: 0
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const useUpdateCart = () => {
|
|
20
|
+
const domain = getCurrentDomain()
|
|
21
|
+
const keyToSaveData = 'app.cart'
|
|
22
|
+
const saveDataState = JSON.parse(Cookies.get(keyToSaveData) || '[]')
|
|
23
|
+
const [cart, setCart] = useState(EMPTY_CART)
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// restore cart from cookie, this could also be tracked in a db
|
|
27
|
+
const cart = Cookies.get(keyToSaveData)
|
|
28
|
+
|
|
29
|
+
// if items in cart, set items and total to state
|
|
30
|
+
if (typeof cart === 'string' && cart !== 'undefined') {
|
|
31
|
+
const cartData = JSON.parse(cart)
|
|
32
|
+
const total = cartData.reduce(
|
|
33
|
+
(total, item) => {return total + item.price * item.quantity},
|
|
34
|
+
0
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
setCart({ items: cartData, total })
|
|
38
|
+
}
|
|
39
|
+
}, [])
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
Cookies.set(keyToSaveData, JSON.stringify(cart.items), { domain, path: '/' })
|
|
43
|
+
}, [cart, domain])
|
|
44
|
+
|
|
45
|
+
const handleAdd = (item) => {
|
|
46
|
+
// check for item already in cart
|
|
47
|
+
// if not in cart, add item else if item is found increment quantity
|
|
48
|
+
const itemExists = cart.items.find((i) => {return i.pId === item.pId})
|
|
49
|
+
|
|
50
|
+
if (!itemExists) {
|
|
51
|
+
setCart((prevCart) => {return {
|
|
52
|
+
items: [...prevCart.items, { ...item, quantity: 1 }],
|
|
53
|
+
total: prevCart.total + item.price
|
|
54
|
+
}})
|
|
55
|
+
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
setCart((prevCart) => {return {
|
|
60
|
+
items: prevCart.items.map((i) => {
|
|
61
|
+
if (i.pId === item.pId) {
|
|
62
|
+
return { ...i, quantity: i.quantity + 1 }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return i
|
|
66
|
+
}),
|
|
67
|
+
total: prevCart.total + item.price
|
|
68
|
+
}})
|
|
69
|
+
updateCart(cart)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const deleteProductCart = (item) => {
|
|
73
|
+
setCart((prevCart) => {
|
|
74
|
+
const items = prevCart.items
|
|
75
|
+
const index = items.findIndex((i) => {return i.pId === item.pId})
|
|
76
|
+
|
|
77
|
+
items.splice(index, 1)
|
|
78
|
+
|
|
79
|
+
const total = items.reduce((t, i) => {return t + i.quantity * i.price}, 0)
|
|
80
|
+
|
|
81
|
+
return { items, total }
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const decreaseItemFromCart = (item) => {
|
|
86
|
+
// check for item already in cart
|
|
87
|
+
// if quantity is more then in cart, subtract item else remove item
|
|
88
|
+
const itemInCart = cart.items.find((i) => {return i.pId === item.pId})
|
|
89
|
+
|
|
90
|
+
if (!itemInCart) {
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (itemInCart.quantity === 1) {
|
|
95
|
+
deleteProductCart(item)
|
|
96
|
+
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setCart((prevCart) => {return {
|
|
101
|
+
items: prevCart.items.map((i) => {
|
|
102
|
+
if (i.pId === item.pId) {
|
|
103
|
+
return { ...i, quantity: item.quantity - 1 }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return i
|
|
107
|
+
}),
|
|
108
|
+
total: prevCart.total - item.price
|
|
109
|
+
}})
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const clearCart = () => {
|
|
113
|
+
setCart(EMPTY_CART)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
saveDataState,
|
|
118
|
+
clearCart,
|
|
119
|
+
deleteProductCart,
|
|
120
|
+
decreaseItemFromCart,
|
|
121
|
+
handleAdd
|
|
122
|
+
}
|
|
123
|
+
}
|