PluginProbe
Extendify / 0.10.2
Extendify v0.10.2
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 / Onboarding / pages / Goals.js

Goals.js in Extendify 0.10.2, at src/Onboarding/pages/Goals.js

185 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useEffect, useRef } from '@wordpress/element'
2 import { __ } from '@wordpress/i18n'
3 import classNames from 'classnames'
4 import { getGoals } from '@onboarding/api/DataApi'
5 import { CheckboxInputCard } from '@onboarding/components/CheckboxInputCard'
6 import { SquareNextButton } from '@onboarding/components/SquareNextButton'
7 import { useFetch } from '@onboarding/hooks/useFetch'
8 import { PageLayout } from '@onboarding/layouts/PageLayout'
9 import { usePagesStore } from '@onboarding/state/Pages'
10 import { useUserSelectionStore } from '@onboarding/state/UserSelections'
11 import { pageState } from '@onboarding/state/factory'
12 import {
13 BarChart,
14 Design,
15 Donate,
16 OpenEnvelope,
17 Pencil,
18 Planner,
19 PriceTag,
20 Shop,
21 Speech,
22 Ticket,
23 } from '@onboarding/svg'
24
25 export const fetcher = () => getGoals()
26 export const fetchData = () => ({ key: 'goals' })
27 export const state = pageState('Goals', () => ({
28 title: __('Goals', 'extendify'),
29 default: undefined,
30 showInSidebar: true,
31 ready: false,
32 isDefault: () => {
33 // If no goals are selected and no text is entered
34 const { feedbackMissingGoal, goals } = useUserSelectionStore.getState()
35 return !feedbackMissingGoal?.length && goals?.length === 0
36 },
37 }))
38 export const Goals = () => {
39 const { data: goals, loading } = useFetch(fetchData, fetcher)
40 const { toggle, has } = useUserSelectionStore()
41 const {
42 feedbackMissingGoal: feedback,
43 setFeedbackMissingGoal,
44 goals: selectedGoals,
45 } = useUserSelectionStore()
46 const nextPage = usePagesStore((state) => state.nextPage)
47 const initialFocus = useRef()
48 const showMissingInput = () =>
49 window.extOnbData?.activeTests?.['remove-dont-see-inputs'] === 'A'
50 const userSelectedGoals = selectedGoals.map((goal) => goal.slug)
51 const iconComponents = {
52 BarChart,
53 Design,
54 Donate,
55 OpenEnvelope,
56 Pencil,
57 Planner,
58 PriceTag,
59 Shop,
60 Speech,
61 Ticket,
62 }
63
64 useEffect(() => {
65 if (loading) return
66 state.setState({ ready: true })
67 }, [loading])
68
69 useEffect(() => {
70 if (!initialFocus.current) return
71 const raf = requestAnimationFrame(() =>
72 initialFocus.current?.querySelector('input')?.focus(),
73 )
74 return () => cancelAnimationFrame(raf)
75 }, [initialFocus])
76
77 return (
78 <PageLayout>
79 <div>
80 <h1 className="text-3xl text-partner-primary-text mb-4 mt-0">
81 {__(
82 'What do you want to accomplish with this new site?',
83 'extendify',
84 )}
85 </h1>
86 <p className="text-base opacity-70 mb-0">
87 {__('You can change these later.', 'extendify')}
88 </p>
89 </div>
90 <div className="w-full">
91 <h2 className="text-lg m-0 mb-4 text-gray-900">
92 {__('Select the goals relevant to your site:', 'extendify')}
93 </h2>
94 {loading ? (
95 <p>{__('Loading...', 'extendify')}</p>
96 ) : (
97 <form
98 onSubmit={(e) => {
99 e.preventDefault()
100 nextPage()
101 }}
102 className="w-full grid lg:grid-cols-2 gap-4 goal-select">
103 {/* Added so forms can be submitted by pressing Enter */}
104 <input type="submit" className="hidden" />
105 {goals?.map((goal, index) => {
106 const selected = userSelectedGoals.includes(
107 goal.slug,
108 )
109 const Icon = iconComponents[goal.icon]
110 return (
111 <div
112 key={goal.id}
113 className={classNames(
114 'relative border rounded-lg',
115 {
116 'border-gray-800': !selected,
117 'border-partner-primary-bg':
118 selected,
119 },
120 )}
121 ref={
122 index === 0 ? initialFocus : undefined
123 }>
124 <div
125 className={classNames(
126 'absolute inset-0 pointer-events-none',
127 {
128 'bg-partner-primary-bg':
129 selected,
130 },
131 )}
132 style={{ opacity: '0.04' }}></div>
133 <div className="flex items-center gap-4">
134 <CheckboxInputCard
135 label={goal.title}
136 slug={`goal-${goal.slug}`}
137 description={goal.description}
138 checked={has('goals', goal)}
139 onChange={() => {
140 toggle('goals', goal)
141 }}
142 Icon={Icon}
143 />
144 </div>
145 </div>
146 )
147 })}
148 </form>
149 )}
150 {!loading && showMissingInput() && (
151 <div className="max-w-onboarding-sm">
152 <h2 className="text-lg mt-12 mb-4 text-gray-900">
153 {__(
154 "Don't see what you're looking for?",
155 'extendify',
156 )}
157 </h2>
158 <div className="search-panel flex items-center justify-center relative gap-4">
159 <input
160 type="text"
161 className="w-full bg-gray-100 h-14 pl-5 input-focus rounded-none ring-offset-0 focus:bg-white"
162 value={feedback}
163 onChange={(e) =>
164 setFeedbackMissingGoal(e.target.value)
165 }
166 placeholder={__(
167 'Add your goals...',
168 'extendify',
169 )}
170 />
171 <div
172 className={classNames({
173 visible: feedback,
174 invisible: !feedback,
175 })}>
176 <SquareNextButton />
177 </div>
178 </div>
179 </div>
180 )}
181 </div>
182 </PageLayout>
183 )
184 }
185