PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.3.48
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.3.48
1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 1.3.51 1.3.50 1.3.49 1.3.48 All 180 releases
disco / backend / views / components / Main / utilities / countdown-style.js

countdown-style.js in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.3.48, at backend/views/components/Main/utilities/countdown-style.js

189 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Utility functions for countdown timer styling
3 */
4
5 // Keys to skip when converting to style object
6 const SKIP_KEYS = ['text', 'isChain', 'radius', 'border', 'border-color'];
7
8 /**
9 * Convert kebab-case CSS properties to camelCase React style object
10 */
11 export const toStyleObject = (styleObj, skipKeys = SKIP_KEYS) => {
12 if (!styleObj) return {};
13 const result = {};
14 Object.entries(styleObj).forEach(([key, value]) => {
15 if (skipKeys.includes(key)) return;
16 const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
17 result[camelKey] = value;
18 });
19 return result;
20 };
21
22 /**
23 * Build border radius string from radius object
24 */
25 const getBorderRadius = (radius) => {
26 if (!radius) return undefined;
27 return `${radius['top-left']} ${radius['top-right']} ${radius['bottom-right']} ${radius['bottom-left']}`;
28 };
29
30 /**
31 * Apply border styles to style object
32 */
33 const applyBorderStyles = (style, borderWidth, borderColor) => {
34 style.borderWidth = `${borderWidth}px`;
35 style.borderStyle = 'solid';
36 style.borderColor = borderColor;
37 };
38
39 /**
40 * Get container style with border and radius
41 */
42 export const getContainerStyle = (container) => {
43 if (!container) return {};
44 const style = toStyleObject(container);
45
46 if (container.radius) {
47 style.borderRadius = getBorderRadius(container.radius);
48 }
49
50 applyBorderStyles(
51 style,
52 container.border ?? 0,
53 container['border-color'] ?? 'rgba(0, 0, 0, 0)'
54 );
55
56 return style;
57 };
58
59 /**
60 * Get box style with border and radius
61 */
62 export const getBoxStyle = (box) => {
63 if (!box) return {};
64 const style = toStyleObject(box);
65
66 if (box.radius) {
67 style.borderRadius = getBorderRadius(box.radius);
68 }
69
70 applyBorderStyles(
71 style,
72 box.border ?? 0,
73 box['border-color'] ?? 'rgba(0, 0, 0, 0)'
74 );
75
76 return style;
77 };
78
79 /**
80 * Replace discount variables with sample values for preview
81 */
82 export const replaceVariables = (text) => {
83 if (!text) return '';
84 return text
85 .replace(/\[discounted_percentage\]/g, '20%')
86 .replace(/\[discount_amount\]/g, '$50')
87 .replace(/\[remaining_quantity\]/g, '2')
88 .replace(/\[remaining_amount\]/g, '$25');
89 };
90
91 /**
92 * Calculate time left from target date
93 */
94 export const calculateTimeLeft = (targetDate) => {
95 const difference = new Date(targetDate) - new Date();
96 if (difference > 0) {
97 return {
98 days: String(Math.floor(difference / (1000 * 60 * 60 * 24))).padStart(2, '0'),
99 hours: String(Math.floor((difference / (1000 * 60 * 60)) % 24)).padStart(2, '0'),
100 minutes: String(Math.floor((difference / (1000 * 60)) % 60)).padStart(2, '0'),
101 seconds: String(Math.floor((difference / 1000) % 60)).padStart(2, '0'),
102 };
103 }
104 return { days: '02', hours: '08', minutes: '15', seconds: '05' };
105 };
106
107 /**
108 * Get time units array from time left object
109 */
110 export const getTimeUnits = (timeLeft) => [
111 { value: timeLeft.days, label: 'DAYS' },
112 { value: timeLeft.hours, label: 'HOURS' },
113 { value: timeLeft.minutes, label: 'MINUTES' },
114 { value: timeLeft.seconds, label: 'SECONDS' },
115 ];
116
117 /**
118 * Build default countdown state from design
119 */
120 export const buildDefaultCountdownState = (design) => ({
121 selected_design: design.id,
122 title: {
123 text: design.title.text,
124 'font-family': design.title['font-family'] || '',
125 'font-size': design.title['font-size'],
126 'font-weight': design.title['font-weight'],
127 'font-style': design.title['font-style'] || 'normal',
128 'text-decoration': 'none',
129 color: design.title.color,
130 },
131 subtitle: {
132 text: design.subtitle.text,
133 'font-family': design.subtitle['font-family'] || '',
134 'font-size': design.subtitle['font-size'],
135 'font-weight': design.subtitle['font-weight'],
136 'font-style': design.subtitle['font-style'] || 'normal',
137 'text-decoration': 'none',
138 color: design.subtitle.color,
139 },
140 container: {
141 background: design.container.background,
142 'border-radius': design.container['border-radius'],
143 padding: design.container.padding,
144 border: design.container.border || 0,
145 'border-color': design.container['border-color'] || 'rgba(0, 0, 0, 0)',
146 isChain: false,
147 radius: {
148 'top-left': '6px',
149 'top-right': '6px',
150 'bottom-right': '6px',
151 'bottom-left': '6px',
152 },
153 },
154 box: {
155 background: design.box.background,
156 'border-radius': design.box['border-radius'],
157 padding: design.box.padding,
158 'min-width': design.box['min-width'] || '50px',
159 border: 0,
160 'border-color': 'rgba(0, 0, 0, 0)',
161 isChain: false,
162 radius: {
163 'top-left': '2px',
164 'top-right': '2px',
165 'bottom-right': '2px',
166 'bottom-left': '2px',
167 },
168 },
169 number: {
170 'font-family': design.number['font-family'] || '',
171 'font-size': design.number['font-size'],
172 'font-weight': design.number['font-weight'],
173 color: design.number.color,
174 },
175 label: {
176 'font-family': design.label['font-family'] || '',
177 'font-size': design.label['font-size'],
178 'font-weight': design.label['font-weight'],
179 color: design.label.color,
180 },
181 separator: {
182 color: design.separator.color,
183 'font-size': design.separator['font-size'],
184 'font-weight': design.separator['font-weight'],
185 },
186 hasSeparator: design.hasSeparator,
187 singleContainer: design.singleContainer,
188 });
189