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 / features / discount / discountSlice.js

discountSlice.js in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.3.48, at backend/views/components/Main/features/discount/discountSlice.js

623 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { createSlice } from '@reduxjs/toolkit';
2 import { v4 as uuidv4 } from 'uuid';
3 import { DEFAULT_COUNTDOWN_DESIGN } from '../../utilities/count-down';
4 import { DEFAULT_TEXT_HIGHLIGHT_DESIGN } from '../../utilities/text-highlight-design';
5 import { DEFAULT_PRODUCT_BADGE_DESIGN } from '../../utilities/product-badge-design';
6
7 const initialState = {
8 name: '',
9 discount_intent: '',
10
11 discount_method: 'automated',
12 discount_coupon: '',
13
14 priority: '1',
15 status: '1',
16
17 show_discount_on_cart_page: false,
18
19 bogo_type: 'all',
20 discount_based_on: 'item_quantity',
21
22 discount_rules: [
23 {
24 id: uuidv4(),
25 min: '',
26 max: '',
27 get_quantity: '',
28 get_ids: [],
29 discount_type: 'percent',
30 discount_value: '',
31 discount_label: '',
32 recursive: 'no',
33 },
34 ],
35
36 discount_max_user: '0',
37 discount_valid_from: '',
38 discount_valid_to: '',
39
40 products: ['all'],
41 conditions: [],
42
43 ui: [0, 0],
44
45 design_blocks: {
46 badge: {
47 enable: false,
48 badge_type: 'editable',
49 selected_design: DEFAULT_PRODUCT_BADGE_DESIGN,
50 position: 'top_left',
51 hasSeparator: false,
52 singleContainer: false,
53
54 // Main container styles
55 container: {
56 position: 'absolute',
57 left: '0px',
58 top: '0px',
59 width: '100px',
60 height: '30px',
61 padding: '5px 10px',
62 background: 'rgb(7, 200, 131)',
63 'clip-path':
64 'polygon(0% 0%, 100% 0%, 85% 49%, 100% 100%, 0% 100%)',
65 },
66 // Title styles
67 title: {
68 text: '[discounted_percentage] OFF',
69 color: '#FFFFFF',
70 'font-family': 'Manrope, sans-serif',
71 'font-size': '14px',
72 'font-weight': 700,
73 },
74 },
75
76 // 🧾 Text highlight (single product page)
77 text_highlight: {
78 enable: false,
79 badge_type: 'editable',
80 selected_design: DEFAULT_TEXT_HIGHLIGHT_DESIGN,
81 position: 'after_add_to_cart',
82
83 // Main container styles
84 container: {
85 width: '150px',
86 height: '40px',
87 display: 'flex',
88 padding: '5px 20px',
89 alignItems: 'center',
90 justifyContent: 'center',
91 'background-color': 'rgb(146, 81, 227)',
92 'border-color': '#fff',
93 'border-width': '0px',
94 radius: {
95 'top-left': '0px',
96 'top-right': '0px',
97 'bottom-right': '0px',
98 'bottom-left': '0px',
99 },
100 'border-style': 'solid',
101 clipPath:
102 'polygon(100% 0%, 90% 50%, 100% 100%, 0% 100%, 10% 50%, 0% 0%)',
103 },
104 // Title styles
105 title: {
106 text: 'Big savings: [discounted_amount]',
107 color: '#FFFFFF',
108 'font-family': 'Manrope, sans-serif',
109 'font-size': '14px',
110 'font-weight': 600,
111 'text-align': 'center',
112 },
113 },
114
115 // ⏳ Countdown timer
116 countdown: {
117 enable: false,
118 selected_design: DEFAULT_COUNTDOWN_DESIGN,
119 position: 'after_add_to_cart',
120
121 // Primary Text (Title)
122 title: {
123 text: 'Exclusive Deals',
124 'font-family': '',
125 'font-size': '14px',
126 'font-weight': 600,
127 'font-style': 'normal',
128 'text-decoration': 'none',
129 color: '#FFFFFF',
130 },
131
132 // Secondary Text (Subtitle)
133 subtitle: {
134 text: 'Available for a limited time only!',
135 'font-family': '',
136 'font-size': '12px',
137 'font-weight': 400,
138 'font-style': 'normal',
139 'text-decoration': 'none',
140 color: '#FFFFFF',
141 },
142
143 // Container (Area) styles
144 container: {
145 background:
146 'linear-gradient(90deg, #F39177 0%, #F61F48 35.5%, #A758EE 69%, #86C5FE 100%)',
147 'border-radius': '6px',
148 padding: '12px 16px 12px 16px',
149 'max-width': '370px',
150 border: 0,
151 'border-color': 'rgba(0, 0, 0, 0)',
152 isChain: false,
153 radius: {
154 'top-left': '6px',
155 'top-right': '6px',
156 'bottom-right': '6px',
157 'bottom-left': '6px',
158 },
159 },
160
161 // Counter Box styles
162 box: {
163 background: '#FFFFFF',
164 'border-radius': '2px',
165 padding: '8px 12px 8px 12px',
166 'min-width': '50px',
167 border: 0,
168 'border-color': 'rgba(0, 0, 0, 0)',
169 isChain: false,
170 radius: {
171 'top-left': '2px',
172 'top-right': '2px',
173 'bottom-right': '2px',
174 'bottom-left': '2px',
175 },
176 },
177
178 // Number styles (countdown digits)
179 number: {
180 'font-family': '',
181 'font-size': '20px',
182 'font-weight': 700,
183 color: '#FF4133',
184 },
185
186 // Label styles (DAYS, HOURS, etc.)
187 label: {
188 'font-family': '',
189 'font-size': '9px',
190 'font-weight': 400,
191 color: '#1A1D1F',
192 },
193
194 // Separator styles
195 separator: {
196 color: '#FFFFFF',
197 'font-size': '20px',
198 'font-weight': 700,
199 },
200
201 // Design metadata
202 hasSeparator: false,
203 singleContainer: false,
204 },
205 cart: {
206 enable: false,
207 design_type: 'notice',
208 selected_design: 'banner1',
209
210 // Banner Customization (includes text, styling, and button)
211 banner: {
212 text: '[discounted_percentage] OFF - Limited Time!',
213 'font-family': '',
214 'font-size': '14px',
215 'font-weight': 600,
216 'font-style': 'normal',
217 'text-decoration': 'none',
218 color: '#ffffff',
219 background: '#07C889',
220 'border-color': '#07C889',
221 icon_color: '#ffffff',
222 border: 0,
223 height: '45px',
224 isChain: false,
225 radius: {
226 'top-left': '8px',
227 'top-right': '8px',
228 'bottom-right': '8px',
229 'bottom-left': '8px',
230 },
231 // Banner Button (Shop Now inside banner)
232 button: {
233 enable: true,
234 text: 'Shop Now',
235 url: '',
236 'font-family': '',
237 'font-size': '12px',
238 'font-weight': 600,
239 'font-style': 'normal',
240 'text-decoration': 'none',
241 color: '#07C889',
242 background: '#ffffff',
243 'border-color': '#ffffff',
244 border: 0,
245 height: '35px',
246 width: '100px',
247 isChain: false,
248 radius: {
249 'top-left': '4px',
250 'top-right': '4px',
251 'bottom-right': '4px',
252 'bottom-left': '4px',
253 },
254 },
255 },
256
257 // Checkout Message Customization
258 checkout_message: {
259 enable: true,
260 text: 'You have saved [Discount Amount] on this order',
261 'font-family': '',
262 'font-size': '14px',
263 'font-weight': 400,
264 'font-style': 'normal',
265 'text-decoration': 'none',
266 color: '#16a34a',
267 },
268
269 // Product Item Savings Badge
270 savings_badge: {
271 enable: true,
272 text: 'SAVE [Amount]',
273 bg_color: '#ef4444',
274 text_color: '#ffffff',
275 'font-size': '12px',
276 },
277 },
278 // 📊 Bulk, Bundle discount table
279 table: {
280 enable: false,
281 position: 'after_add_to_cart',
282 table_style: 'style1',
283
284 heading: {
285 title: 'Title',
286 discount: 'Discount',
287 range: 'Ranges',
288 buy_now: 'Buy Now',
289 },
290
291 // ========================
292 // Heading Text (Used for header font styles)
293 // ========================
294 heading_customization: {
295 'font-family': '',
296 'font-size': '14px',
297 'font-weight': 400,
298 color: '#FFFFFF',
299 background: '#283142',
300 'border-color': '#F3F4F6',
301 height: '45px',
302 'border-right': '1px solid',
303 'border-bottom': '1px solid',
304 },
305
306 // ========================
307 // Cell Customization (Used for body font styles)
308 // ========================
309 cell_customization: {
310 'font-family': '',
311 'font-size': '14px',
312 'font-weight': 400,
313 color: '#374151',
314 background: '#ffffff',
315 'border-color': '#e5e7eb',
316 height: '45px',
317 'border-right': '1px solid',
318 'border-bottom': '1px solid',
319 },
320
321 // ========================
322 // Button Customization (Using the vibrant purple from original component)
323 // ========================
324 button: {
325 enable: true,
326 text: 'Buy Now',
327 'font-family': '',
328 'font-size': '14px',
329 'font-weight': 400,
330 height: '35px',
331 color: '#ffffff',
332 background: '#07C889',
333 border: '1px solid',
334 'border-color': '#ffffff',
335 'padding-top': '4px',
336 'padding-right': '8px',
337 'padding-bottom': '4px',
338 'padding-left': '8px',
339 isChain: false,
340 radius: {
341 'top-left': '6px',
342 'top-right': '6px',
343 'bottom-right': '6px',
344 'bottom-left': '6px',
345 },
346 },
347 },
348 },
349 };
350
351 export const discountSlice = createSlice({
352 name: 'discount',
353 initialState,
354 reducers: {
355 reset: () => initialState,
356 editCampaign: (state, action) => {
357 return { ...initialState, ...action.payload };
358 },
359 updateOption: (state, action) => {
360 state[action.payload.option] = action.payload.value;
361 },
362
363 updateProducts: (state, action) => {
364 if (
365 state.products.find(
366 (_product) => _product.id === action.payload.id
367 )
368 ) {
369 state.products = state.products.filter(
370 (_product) => _product.id !== action.payload.id
371 );
372 } else {
373 state.products.push(action.payload);
374 }
375 },
376
377 removeProduct: (state, action) => {
378 state.products = state.products.filter(
379 (_product) => _product.id !== action.payload.id
380 );
381 },
382
383 // *! Condition's Reducers
384
385 addCondition: (state, action) => {
386 const condition_group_index = state.conditions.findIndex(
387 (filter) => filter.id === action.payload
388 );
389 if (condition_group_index !== -1) {
390 state.conditions[condition_group_index].base_filters.push({
391 id: uuidv4(),
392 compare_with: '',
393 operator: 'and',
394 });
395 }
396 },
397
398 addConditionGroup: (state) => {
399 state.conditions.push({
400 id: uuidv4(),
401 base_operator: 'and',
402 base_filters: [
403 {
404 id: uuidv4(),
405 compare_with: '',
406 operator: 'and',
407 },
408 ],
409 });
410 },
411
412 updateConditionGroup: (state, action) => {
413 const condition_group_index = state.conditions.findIndex(
414 (filter) => filter.id === action.payload.id
415 );
416 if (condition_group_index !== -1) {
417 state.conditions[condition_group_index].base_operator =
418 action.payload.operator;
419 }
420 },
421
422 deleteConditionGroup: (state, action) => {
423 state.conditions = state.conditions.filter(
424 (conditionGroup) => conditionGroup.id !== action.payload
425 );
426 },
427
428 updateConditionValues: (state, action) => {
429 const condition_group_index = state.conditions.findIndex(
430 (filter) => filter.id === action.payload.group_id
431 );
432
433 if (condition_group_index !== -1) {
434 const condition_index = state.conditions[
435 condition_group_index
436 ].base_filters.findIndex(
437 (filter) => filter.id === action.payload.values.id
438 );
439
440 if (condition_index !== -1) {
441 state.conditions[condition_group_index].base_filters[
442 condition_index
443 ] = action.payload.values;
444 }
445 }
446 },
447
448 deleteCondition: (state, action) => {
449 const condition_group_index = state.conditions.findIndex(
450 (filter) => filter.id === action.payload.group_id
451 );
452 if (condition_group_index !== -1) {
453 if (
454 state.conditions[condition_group_index].base_filters
455 .length === 1
456 ) {
457 state.conditions = state.conditions.filter(
458 (conditionGroup) =>
459 conditionGroup.id !== action.payload.group_id
460 );
461 } else {
462 state.conditions[condition_group_index].base_filters =
463 state.conditions[
464 condition_group_index
465 ].base_filters.filter(
466 (condition) =>
467 condition.id !== action.payload.condition_id
468 );
469 }
470 }
471 },
472
473 // *! UI Tab Reducers
474
475 setTab: (state, action) => {
476 state.ui[0] = action.payload;
477 if (state.ui[1] < state.ui[0]) {
478 state.ui[1] = state.ui[0];
479 }
480 },
481
482 // *! Discount Rules Reducers
483
484 changeBOGOType: (state, action) => {
485 if (state.bogo_type !== action.payload) {
486 state.bogo_type = action.payload;
487 state.discount_rules = state.discount_rules.map((rule) => ({
488 ...rule,
489 get_ids: [],
490 }));
491 }
492 },
493
494 changeDiscountIntention: (state, action) => {
495 state.discount_intent = action.payload;
496 state.discount_rules = [
497 {
498 id: uuidv4(),
499 min: '',
500 max: '',
501 get_quantity: '',
502 get_ids: [],
503 discount_type: 'percent',
504 discount_value: '',
505 discount_label: '',
506 recursive: 'no',
507 },
508 ];
509 state.design_blocks = initialState.design_blocks;
510 },
511
512 addNewDiscountRule: (state) => {
513 state.discount_rules.push({
514 id: uuidv4(),
515 min: '',
516 max: '',
517 get_quantity: '',
518 get_ids: [],
519 discount_type: 'percent',
520 discount_value: '',
521 discount_label: '',
522 recursive: 'no',
523 });
524 },
525
526 updateDiscountRule: (state, action) => {
527 const index = state.discount_rules.findIndex(
528 (item) => item.id === action.payload.id
529 );
530 if (index !== -1) {
531 state.discount_rules[index] = action.payload;
532 }
533 },
534 deleteDiscountRule: (state, action) => {
535 state.discount_rules = state.discount_rules.filter(
536 (item) => item.id !== action.payload
537 );
538 },
539
540 // *! Design Block Reducers
541
542 updateBadge: (state, action) => {
543 state.design_blocks.badge[action.payload.name] =
544 action.payload.value;
545 },
546
547 updateTextHighlight: (state, action) => {
548 state.design_blocks.text_highlight[action.payload.name] =
549 action.payload.value;
550 },
551
552 updateCountdown: (state, action) => {
553 state.design_blocks.countdown[action.payload.name] =
554 action.payload.value;
555 },
556
557 applyCountdownDesign: (state, action) => {
558 const countdown = state.design_blocks.countdown;
559 const { designKey, design } = action.payload;
560 countdown.selected_design = designKey;
561 countdown.title = { ...countdown.title, text: design.title.text, color: design.title.color, 'font-size': design.title['font-size'], 'font-weight': design.title['font-weight'] };
562 countdown.subtitle = { ...countdown.subtitle, text: design.subtitle.text, color: design.subtitle.color, 'font-size': design.subtitle['font-size'], 'font-weight': design.subtitle['font-weight'] };
563 countdown.container = { ...countdown.container, background: design.container.background, 'border-radius': design.container['border-radius'], border: design.container.border, 'border-color': design.container['border-color'], radius: { 'top-left': design.container['border-radius'], 'top-right': design.container['border-radius'], 'bottom-right': design.container['border-radius'], 'bottom-left': design.container['border-radius'] } };
564 countdown.box = { ...countdown.box, background: design.box.background, 'border-radius': design.box['border-radius'], 'min-width': design.box['min-width'] || '50px', radius: { 'top-left': design.box['border-radius'], 'top-right': design.box['border-radius'], 'bottom-right': design.box['border-radius'], 'bottom-left': design.box['border-radius'] } };
565 countdown.number = { ...countdown.number, color: design.number.color, 'font-size': design.number['font-size'], 'font-weight': design.number['font-weight'] };
566 countdown.label = { ...countdown.label, color: design.label.color, 'font-size': design.label['font-size'], 'font-weight': design.label['font-weight'] };
567 countdown.separator = { color: design.separator.color, 'font-size': design.separator['font-size'], 'font-weight': design.separator['font-weight'] };
568 countdown.image = { url: design.image.url };
569 countdown.hasSeparator = design.hasSeparator;
570 countdown.singleContainer = design.singleContainer;
571 },
572
573 updateTable: (state, action) => {
574 state.design_blocks.table[action.payload.name] =
575 action.payload.value;
576 },
577
578 updateCartPage: (state, action) => {
579 state.design_blocks.cart[action.payload.name] =
580 action.payload.value;
581 },
582
583 // updateSinglePage: (state, action) => {
584 // state.design_blocks.singlePage[action.payload.name] =
585 // action.payload.value;
586 // },
587 // updateCartPage: (state, action) => {
588 // state.design_blocks.cartPage[action.payload.name] =
589 // action.payload.value;
590 // },
591 },
592 });
593
594 export const {
595 reset,
596 editCampaign,
597 updateOption,
598 updateProducts,
599 removeProduct,
600 addCondition,
601 addConditionGroup,
602 updateConditionGroup,
603 deleteConditionGroup,
604 updateConditionValues,
605 deleteCondition,
606 setTab,
607
608 changeBOGOType,
609 changeDiscountIntention,
610 addNewDiscountRule,
611 updateDiscountRule,
612 deleteDiscountRule,
613
614 updateBadge,
615 updateTextHighlight,
616 updateCountdown,
617 applyCountdownDesign,
618 updateTable,
619 updateCartPage,
620 } = discountSlice.actions;
621
622 export default discountSlice.reducer;
623