PluginProbe
WebberZone Top 10 — Popular Posts / 4.3.2
WebberZone Top 10 — Popular Posts v4.3.2
4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 1.6.1 All 117 releases
top-10 / includes / frontend / blocks / src / post-count / controls.js

controls.js in WebberZone Top 10 — Popular Posts 4.3.2, at includes/frontend/blocks/src/post-count/controls.js

379 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * WordPress dependencies
3 */
4 import {
5 BlockControls,
6 AlignmentControl,
7 InspectorControls,
8 } from '@wordpress/block-editor';
9 import {
10 PanelBody,
11 SelectControl,
12 Button,
13 Modal,
14 TextControl,
15 ToggleControl,
16 Popover,
17 DatePicker,
18 TextareaControl,
19 __experimentalText as Text,
20 } from '@wordpress/components';
21 import { __ } from '@wordpress/i18n';
22 import { useState } from '@wordpress/element';
23
24 import { svgOptions } from './components/svg';
25 import PaddingControl from './components/padding-control';
26 import UnitControl from './components/unit-control';
27
28 const Controls = ({ attributes, setAttributes }) => {
29 const {
30 textAlign,
31 counter,
32 fromDate,
33 toDate,
34 textBefore,
35 textAfter,
36 advancedMode,
37 textAdvanced,
38 numberFormat,
39 svgCode,
40 svgIconLocation,
41 svgIconSize,
42 svgIconSizeUnit,
43 } = attributes;
44 const [isFromDatePickerVisible, setIsFromDatePickerVisible] =
45 useState(false);
46 const [isToDatePickerVisible, setIsToDatePickerVisible] = useState(false);
47 const [isSvgModalOpen, setIsSvgModalOpen] = useState(false);
48
49 const formatDate = (date) => {
50 if (!date) {
51 return '';
52 }
53 const d = new Date(date);
54 return d.toISOString().split('T')[0];
55 };
56
57 const handleDateChange = (date, isFromDate) => {
58 const formattedDate = formatDate(date);
59 setAttributes({
60 [isFromDate ? 'fromDate' : 'toDate']: formattedDate,
61 });
62 setIsFromDatePickerVisible(false);
63 setIsToDatePickerVisible(false);
64 };
65
66 const clearDate = (isFromDate) => {
67 setAttributes({ [isFromDate ? 'fromDate' : 'toDate']: '' });
68 };
69
70 const handleSvgSelection = (selectedSvg) => {
71 setAttributes({ svgCode: selectedSvg });
72 setIsSvgModalOpen(false);
73 };
74 const clearSvg = () => {
75 setAttributes({ svgCode: '' });
76 };
77
78 return (
79 <>
80 <BlockControls group="block">
81 <AlignmentControl
82 value={textAlign}
83 onChange={(nextAlign) => {
84 setAttributes({ textAlign: nextAlign });
85 }}
86 />
87 </BlockControls>
88 <InspectorControls>
89 <PanelBody
90 title={__('Counter Settings', 'top-10')}
91 initialOpen={true}
92 >
93 <SelectControl
94 label={__('Counter Type', 'top-10')}
95 value={counter}
96 options={[
97 { label: __('Total', 'top-10'), value: 'total' },
98 { label: __('Daily', 'top-10'), value: 'daily' },
99 ]}
100 onChange={(value) => setAttributes({ counter: value })}
101 />
102 {counter === 'daily' && (
103 <>
104 <div className="tptn-date-picker-container">
105 <Text>{__('From', 'top-10')}</Text>
106 <Button
107 onClick={() =>
108 setIsFromDatePickerVisible(
109 (state) => !state
110 )
111 }
112 variant="secondary"
113 >
114 {fromDate ||
115 __('Select From Date', 'top-10')}
116 </Button>
117 {fromDate && (
118 <Button
119 onClick={() => clearDate(true)}
120 variant="link"
121 isDestructive
122 >
123 {__('Clear', 'top-10')}
124 </Button>
125 )}
126 {isFromDatePickerVisible && (
127 <Popover
128 onClose={() =>
129 setIsFromDatePickerVisible(false)
130 }
131 >
132 <DatePicker
133 currentDate={fromDate}
134 onChange={(date) =>
135 handleDateChange(date, true)
136 }
137 />
138 </Popover>
139 )}
140 </div>
141
142 <div className="tptn-date-picker-container">
143 <Text>{__('To', 'top-10')}</Text>
144 <Button
145 onClick={() =>
146 setIsToDatePickerVisible(
147 (state) => !state
148 )
149 }
150 variant="secondary"
151 >
152 {toDate || __('Select To Date', 'top-10')}
153 </Button>
154 {toDate && (
155 <Button
156 onClick={() => clearDate(false)}
157 variant="link"
158 isDestructive
159 >
160 {__('Clear', 'top-10')}
161 </Button>
162 )}
163 {isToDatePickerVisible && (
164 <Popover
165 onClose={() =>
166 setIsToDatePickerVisible(false)
167 }
168 >
169 <DatePicker
170 currentDate={toDate}
171 onChange={(date) =>
172 handleDateChange(date, false)
173 }
174 />
175 </Popover>
176 )}
177 </div>
178 </>
179 )}
180 <ToggleControl
181 label={__('Number Formatting', 'top-10')}
182 checked={numberFormat}
183 onChange={(value) =>
184 setAttributes({ numberFormat: value })
185 }
186 />
187 </PanelBody>
188
189 <PanelBody
190 title={__('Text Customization', 'top-10')}
191 initialOpen={true}
192 >
193 <ToggleControl
194 label={__('Advanced Mode', 'top-10')}
195 checked={advancedMode}
196 onChange={(value) =>
197 setAttributes({ advancedMode: value })
198 }
199 />
200
201 {!advancedMode && (
202 <>
203 <TextControl
204 label={__('Text Before Count', 'top-10')}
205 value={textBefore}
206 onChange={(value) =>
207 setAttributes({ textBefore: value })
208 }
209 />
210 <TextControl
211 label={__('Text After Count', 'top-10')}
212 value={textAfter}
213 onChange={(value) =>
214 setAttributes({ textAfter: value })
215 }
216 />
217 </>
218 )}
219
220 {advancedMode && (
221 <TextareaControl
222 label={__('Advanced Text', 'top-10')}
223 value={textAdvanced}
224 onChange={(value) =>
225 setAttributes({ textAdvanced: value })
226 }
227 help={__(
228 'Use %totalcount% or %dailycount% as placeholders for the count value.',
229 'top-10'
230 )}
231 />
232 )}
233 </PanelBody>
234
235 <PanelBody title={__('Icon', 'top-10')} initialOpen={true}>
236 <div
237 style={{
238 display: 'flex',
239 alignItems: 'center',
240 }}
241 >
242 <TextControl
243 label={__('Icon SVG HTML', 'top-10')}
244 value={svgCode}
245 onChange={(value) =>
246 setAttributes({ svgCode: value })
247 }
248 />
249 </div>
250 <div
251 style={{
252 display: 'flex',
253 justifyContent: 'space-between',
254 marginBottom: '10px',
255 }}
256 >
257 <Button
258 onClick={() => setIsSvgModalOpen(true)}
259 variant="secondary"
260 >
261 {__('Select SVG', 'top-10')}
262 </Button>
263 <Button
264 onClick={clearSvg}
265 variant="secondary"
266 isDestructive
267 >
268 {__('Clear', 'top-10')}
269 </Button>
270 {svgCode && (
271 <div
272 style={{
273 marginRight: '10px',
274 width: '30px',
275 height: '30px',
276 }}
277 dangerouslySetInnerHTML={{ __html: svgCode }}
278 />
279 )}
280 </div>
281 <SvgSelectionModal
282 isOpen={isSvgModalOpen}
283 onClose={() => setIsSvgModalOpen(false)}
284 onSelect={handleSvgSelection}
285 />
286
287 {svgCode && (
288 <>
289 <SelectControl
290 label={__('Icon Location', 'top-10')}
291 value={svgIconLocation}
292 options={[
293 {
294 value: 'before',
295 label: __('Before Text', 'top-10'),
296 },
297 {
298 value: 'after',
299 label: __('After Text', 'top-10'),
300 },
301 ]}
302 onChange={(newValue) =>
303 setAttributes({ svgIconLocation: newValue })
304 }
305 help={
306 svgIconLocation === 'after'
307 ? __(
308 'Icon will be placed after the text.',
309 'top-10'
310 )
311 : __(
312 'Icon will be placed before the text.',
313 'top-10'
314 )
315 }
316 />
317 <UnitControl
318 label={__('Icon Size', 'top-10')}
319 value={svgIconSize}
320 unit={svgIconSizeUnit}
321 onValueChange={(value) =>
322 setAttributes({ svgIconSize: value })
323 }
324 onUnitChange={(unit) =>
325 setAttributes({ svgIconSizeUnit: unit })
326 }
327 />
328 <PaddingControl
329 attributes={attributes}
330 setAttributes={setAttributes}
331 />
332 </>
333 )}
334 </PanelBody>
335 </InspectorControls>
336 </>
337 );
338 };
339
340 export default Controls;
341
342 const SvgSelectionModal = ({ isOpen, onClose, onSelect }) => {
343 return isOpen ? (
344 <Modal title={__('Select an SVG', 'top-10')} onRequestClose={onClose}>
345 <div
346 style={{
347 display: 'grid',
348 gridTemplateColumns: 'repeat(auto-fill, minmax(25px, 1fr))',
349 gap: '2px',
350 padding: '1px',
351 }}
352 >
353 {svgOptions.map((svg, index) => (
354 <Button
355 key={index}
356 onClick={() => onSelect(svg.code)}
357 style={{
358 padding: '1px',
359 border: '0px solid #ddd',
360 display: 'flex',
361 justifyContent: 'center',
362 alignItems: 'center',
363 height: '25px',
364 }}
365 title={svg.name}
366 >
367 <svg
368 viewBox="0 0 100 100"
369 xmlns="http://www.w3.org/2000/svg"
370 style={{ width: '100%', height: '100%' }}
371 dangerouslySetInnerHTML={{ __html: svg.code }}
372 />
373 </Button>
374 ))}
375 </div>
376 </Modal>
377 ) : null;
378 };
379