PluginProbe
Extendify / 0.2.0
Extendify v0.2.0
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / components / FooterNotice.js

FooterNotice.js in Extendify 0.2.0, at src/components/FooterNotice.js

104 lines 3.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __ } from '@wordpress/i18n'
2 import { Icon, closeSmall } from '@wordpress/icons'
3 import { Button } from '@wordpress/components'
4 import WelcomeNotice from './notices/WelcomeNotice'
5 import PromotionNotice from './notices/PromotionNotice'
6 import FeedbackNotice from './notices/FeedbackNotice'
7 import { useUserStore } from '../state/User'
8 import { useGlobalStore } from '../state/GlobalState'
9 import { useState, useEffect, useRef } from '@wordpress/element'
10
11 const NoticesByPriority = {
12 welcome: WelcomeNotice,
13 promotion: PromotionNotice,
14 feedback: FeedbackNotice,
15 }
16
17 export default function FooterNotice() {
18 const [hasNotice, setHasNotice] = useState(null)
19 const once = useRef(false)
20 const promotionData = useGlobalStore(
21 (state) => state.metaData?.banners?.footer,
22 )
23
24 const showFeedback = () => {
25 const imports = useUserStore.getState().imports ?? 0
26 const firstLoadedOn =
27 useUserStore.getState()?.firstLoadedOn ?? new Date()
28 const timeDifference =
29 new Date().getTime() - new Date(firstLoadedOn).getTime()
30 const daysSinceActivated = timeDifference / 86_400_000 // 24 hours
31
32 return imports >= 3 && daysSinceActivated > 3
33 }
34
35 // Find the first notice key to use
36 const componentKey =
37 Object.keys(NoticesByPriority).find((key) => {
38 if (key === 'promotion') {
39 return (
40 // When checking promotions, use the key sent from the server
41 // to check whether it's been dismissed
42 promotionData?.key &&
43 !useUserStore.getState().noticesDismissedAt[
44 promotionData.key
45 ]
46 )
47 }
48
49 if (key === 'feedback') {
50 return (
51 showFeedback() &&
52 !useUserStore.getState().noticesDismissedAt[key]
53 )
54 }
55
56 return !useUserStore.getState().noticesDismissedAt[key]
57 }) ?? null
58 const Notice = NoticesByPriority[componentKey]
59
60 const dismiss = () => {
61 setHasNotice(false)
62 // The noticesDismissedAt key will either be the key from NoticesByPriority,
63 // or a key passed in from the server, such as 'holiday-sale2077'
64 const key =
65 componentKey === 'promotion' ? promotionData.key : componentKey
66 useUserStore.setState({
67 noticesDismissedAt: Object.assign(
68 {},
69 {
70 ...useUserStore.getState().noticesDismissedAt,
71 [key]: new Date().toISOString(),
72 },
73 ),
74 })
75 }
76
77 useEffect(() => {
78 // Only show the notice once on main render and only if a notice exists.
79 if (NoticesByPriority[componentKey] && !once.current) {
80 setHasNotice(true)
81 once.current = true
82 }
83 }, [componentKey])
84
85 if (!hasNotice) {
86 return null
87 }
88 return (
89 <div className="bg-extendify-secondary hidden lg:flex space-x-4 py-3 px-5 justify-center items-center relative max-w-screen-4xl mx-auto">
90 {/* Pass all data to all components and let them decide what they use */}
91 <Notice promotionData={promotionData} />
92 <div className="absolute right-1">
93 <Button
94 className="opacity-50 hover:opacity-100 focus:opacity-100 text-extendify-black"
95 icon={<Icon icon={closeSmall} />}
96 label={__('Dismiss this notice', 'extendify')}
97 onClick={dismiss}
98 showTooltip={false}
99 />
100 </div>
101 </div>
102 )
103 }
104