spree_cm_commissioner 1.17.0.pre.pre5 → 1.17.0.pre.pre7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/assets/images/cm-hangmeas-checkout_image.svg +63 -0
  4. data/app/assets/images/cm-hangmeas-failed.svg +56 -0
  5. data/app/assets/images/cm-hangmeas-loader.svg +50 -0
  6. data/app/assets/images/cm-hangmeas-success.svg +51 -0
  7. data/app/assets/javascripts/spree_cm_commissioner/backend.js +1 -0
  8. data/app/assets/javascripts/spree_cm_commissioner/tenant_payment_icon_fields.js +65 -0
  9. data/app/assets/stylesheets/spree_cm_commissioner/backend/commissioner_admin.css.scss +1 -0
  10. data/app/assets/stylesheets/spree_cm_commissioner/backend/tenant_payment_icon_fields.scss +60 -0
  11. data/app/controllers/spree/admin/tenants_controller.rb +8 -0
  12. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +19 -2
  13. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +4 -0
  14. data/app/models/spree_cm_commissioner/dynamic_field.rb +15 -3
  15. data/app/models/spree_cm_commissioner/dynamic_field_option.rb +5 -1
  16. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +21 -3
  17. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +1 -3
  18. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -3
  19. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +2 -1
  20. data/app/views/spree/admin/tenants/_form.html.erb +109 -42
  21. data/db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb +6 -0
  22. data/db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb +5 -0
  23. data/db/migrate/20250702091935_add_status_to_dynamic_field_option.rb +5 -0
  24. data/lib/spree_cm_commissioner/version.rb +1 -1
  25. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6f4154db94f9e09e6e794abe55a03e92db3a0ccde12796251aeb8976d7d45f7
4
- data.tar.gz: 8289c711a64719b71201051347afadc2b1d97828a231ca49c05068d174dd2488
3
+ metadata.gz: 0a00e3ade6665258924af6b63276add5be49a3b887d193942c41b8ba4a1fa573
4
+ data.tar.gz: c30315d4d2f4313a342f94be21cf567cab1dbc4bac07cd754542d61d5de17990
5
5
  SHA512:
6
- metadata.gz: 8e6795f1cc9679b85d5813d3b1fe1bec813ac8fdf8b82a963278df3a3dd681365e8d28007f935d2fdbd5c38ec8679e05d63430019992655fc4088e75d7328472
7
- data.tar.gz: 50c89c06021e167b0278abfab0569099e7d42caffdbfe158ad672b45d4463d855e742eb90db023752cfc58a4b99d1f1385e73470017204ba57f46e80add08062
6
+ metadata.gz: 30c14950496e7a3df59fd8a5e3233572a30437f750d0d546d4ec87cc405a8d24850912b161ca74eab4530d1d7cf27e3cb333625b0b4915e63102e3b45f1a3e94
7
+ data.tar.gz: 3062f419e60420e2e9a87c57b8720051292ebdbff63b4308bc739e32309b4aef55498b06c1b2134ee3761b9c4fca5cea8d0ecf912d3bf928701292123a23e11b
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (1.17.0.pre.pre5)
37
+ spree_cm_commissioner (1.17.0.pre.pre7)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="payment_proccessing" data-name="payment proccessing" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 334 200">
3
+ <defs>
4
+ <clipPath id="clippath">
5
+ <path d="m332.72,16.62v166.75c0,8.27-6.28,15.08-14.33,15.92-.55.05-1.11.08-1.67.08H16c-.48,0-.96-.02-1.43-.06-8.17-.73-14.57-7.59-14.57-15.94V16.62C0,7.78,7.16.62,16,.62h300.72c8.84,0,16,7.16,16,16Z" style="fill: none;"/>
6
+ </clipPath>
7
+ </defs>
8
+ <g style="clip-path: url(#clippath);">
9
+ <path d="m332.72,16.62v166.75c0,8.27-6.28,15.08-14.33,15.92-.55.05-1.11.08-1.67.08H16c-.48,0-.96-.02-1.43-.06-8.17-.73-14.57-7.59-14.57-15.94V16.62C0,7.78,7.16.62,16,.62h300.72c8.84,0,16,7.16,16,16Z" style="fill: #130d07;"/>
10
+ <path d="m160.11,89.69c1.41-5.81-3.61-9.74-10.21-9.27-6.6.47-26.31,10.68-28.51,12.26-2.2,1.57-29.54,6.6-34.25,3.77-4.71-2.83-12.46-7.49-12.46-7.49,0,0-23.81-23.81-40.47,2.86-16.67,26.66-13.99,61.42-13.99,61.42l-24.1,29.05s-10.95,10,3.81,19.05,22.11,18.14,31.15,21.3c9.04,3.16,14.46-7,14.46-7.68,0-.68,19.43-30.27,19.43-30.27,10.27-.69,20.53-1.41,30.79-2.17,10.81-.8,24.65.44,31.99-9.08,3.2-4.15,1.59-8.37-.02-12.85.06.18,3.68-1,4-1.13,1.81-.72,3.12-1.91,3.94-3.7,1.55-3.36,2.03-8.12.07-11.41-2.91-4.88-3.85-5.31-3.85-5.31.93.42,4.7-2.76,5.32-3.27,2.69-2.21,4.81-5.03,5.27-8.57,1.31-10.16-10.01-17.26-18.56-19.27,5.59,1.31,10.8,2.15,16.21-.39,3.01-1.41,5.69-3.43,8.35-5.44,4.02-3.03,10.38-7.18,11.65-12.41" style="fill: #e89875;"/>
11
+ <path d="m138.73,45.68c-1.83-.91-5.84-1.99-7.86-2.27-3.17-.44-12.78-.68-12.78-.68l-1.24,3.76-31.45-1.3c-4.73-.2-8.98,2.88-10.27,7.44l-27.87,101.59c-1.74,6.14,2.5,12.35,8.85,12.97l49.44,1.78c4.98.49,9.59-2.69,10.89-7.53l27.25-101.35c.17-.64.26-1.28.31-1.92,0-.02.01-.05.02-.07,1.59-7.52-1.35-10.47-5.29-12.43Z" style="fill: #302b31;"/>
12
+ <path d="m51.51,163.26l49.44,1.78c4.98.49,9.59-2.69,10.89-7.53l27.25-101.35c1.7-6.33-2.91-12.61-9.46-12.88l-48.82-2.02c-4.73-.2-8.98,2.88-10.27,7.44l-27.87,101.59c-1.74,6.14,2.5,12.35,8.85,12.97Z" style="fill: #212028;"/>
13
+ <path d="m108.45,126.85c-1.64.07-3.43-.23-5.08-.3-4.13-.18-8.26-.36-12.39-.54l-22.43-.98-.81-.04c-2.87-.41-4.61-1.99-3.7-4.96l.84-3.54c.55-2.49,2.89-4.15,5.42-3.86,13.54.41,27.15.41,40.66,1.23,2,.12,4.17.45,4.34,2.96.15,2.13-1.09,4.94-1.91,6.87-1.02,2.41-2.87,3.07-4.95,3.16Z" style="fill: #f59b1d;"/>
14
+ <path d="m117.78,96.1l-48.7-1.94c-2.03-.08-3.25-1.77-2.74-3.76l8.36-32.34c.52-2,2.58-3.55,4.61-3.47l48.7,1.94c2.03.08,3.25,1.77,2.74,3.76l-8.36,32.34c-.52,2-2.58,3.55-4.61,3.47Z" style="fill: #fffaf8;"/>
15
+ <path d="m85.83,77.72l-8.87-.35c-.88-.04-1.41-.77-1.19-1.63l1.23-4.78c.22-.87,1.12-1.54,2-1.51l8.87.35c.88.04,1.41.77,1.19,1.63l-1.23,4.78c-.22.87-1.12,1.54-2,1.51Z" style="fill: #d6d6d6;"/>
16
+ <path d="m124.55,64.16l-9.8-.39c-.62-.02-1-.54-.84-1.15l.45-1.74c.16-.61.79-1.09,1.41-1.06l9.8.39c.62.02,1,.54.84,1.15l-.45,1.74c-.16.61-.79,1.09-1.41,1.06Z" style="fill: #d6d6d6;"/>
17
+ <path d="m84.05,81.98l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
18
+ <path d="m99.83,91.71l-27.44-1.09c-.25-.01-.41-.22-.34-.47l.42-1.62c.06-.25.32-.44.57-.43l27.44,1.09c.25.01.41.22.34.47l-.42,1.62c-.06.25-.32.44-.57.43Z" style="fill: #d6d6d6;"/>
19
+ <path d="m95.54,82.43l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
20
+ <path d="m107.03,82.89l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
21
+ <path d="m118.52,83.35l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
22
+ <path d="m111.65,93.7c-.49.15-.94.45-1.44.61-2.03.64-4.12-.62-4.15-2.53-.02-1.28.45-2.44,1.6-3.42.84-.72,1.78-1.08,2.78-1.14.88-.05,1.65.12,2.24.65.12.11.29.16.44.24-.17.19.02.23.08.32.37.57.57,1.21.45,1.96-.2,1.22-.73,2.32-1.89,3.17-.05.03-.08.09-.11.14Z" style="fill: #d6d6d6;"/>
23
+ <path d="m111.65,93.7s.07-.11.11-.14c1.16-.85,1.69-1.95,1.89-3.17.12-.75-.08-1.39-.45-1.96-.06-.09-.25-.14-.08-.32.59-.27,1.16-.59,1.79-.67,2.25-.26,3.6.86,3.66,2.68.06,1.96-1.32,3.73-3.42,4.37-1.29.39-2.36.14-3.23-.58-.09-.07-.18-.15-.26-.22Z" style="fill: #5e5e5e;"/>
24
+ <path d="m53.69,110.12s1.51-5.75,5.56,2.51c4.05,8.27,15.38,11.23,20.41,6.86s-.79-23.41-15.54-36.21c-14.75-12.8-30.48,5.41-37.12,19.9-6.65,14.49-6.78,50.07-6.78,50.07l48.9,21.12s8.3-15.25.02-34.98c-4.68-11.15-9.08-16.86-12.8-21.88-3.73-5.02-2.64-7.37-2.64-7.37Z" style="fill: #e89875;"/>
25
+ <g>
26
+ <rect x="222.73" y="98.72" width="8.27" height="27.35" style="fill: #fbc01a;"/>
27
+ <polygon points="231 100.13 222.73 100.13 221.53 95.4 232.39 95.4 231 100.13" style="fill: #fbc01a;"/>
28
+ <line x1="223.67" y1="100.13" x2="231" y2="100.13" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
29
+ <polygon points="222.73 126.08 231 126.08 232.2 130.8 221.33 130.8 222.73 126.08" style="fill: #fbc01a;"/>
30
+ <line x1="231" y1="126.08" x2="222.73" y2="126.08" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
31
+ </g>
32
+ <g>
33
+ <rect x="240.34" y="98.72" width="8.27" height="27.35" style="fill: #f4b200;"/>
34
+ <polygon points="248.61 100.13 240.34 100.13 239.15 95.4 250.01 95.4 248.61 100.13" style="fill: #f4b200;"/>
35
+ <polygon points="240.35 126.08 248.62 126.08 249.81 130.8 238.95 130.8 240.35 126.08" style="fill: #f4b200;"/>
36
+ </g>
37
+ <g>
38
+ <rect x="257.95" y="98.72" width="8.27" height="27.35" style="fill: #fbc01a;"/>
39
+ <polygon points="266.22 100.13 257.95 100.13 256.76 95.4 267.62 95.4 266.22 100.13" style="fill: #fbc01a;"/>
40
+ <line x1="258.9" y1="100.13" x2="266.22" y2="100.13" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
41
+ <polygon points="257.96 126.08 266.23 126.08 267.42 130.8 256.56 130.8 257.96 126.08" style="fill: #fbc01a;"/>
42
+ <line x1="266.22" y1="126.08" x2="257.96" y2="126.08" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
43
+ </g>
44
+ <g>
45
+ <rect x="275.56" y="98.72" width="8.27" height="27.35" style="fill: #fbc01a;"/>
46
+ <polygon points="283.84 100.13 275.56 100.13 274.37 95.4 285.23 95.4 283.84 100.13" style="fill: #fbc01a;"/>
47
+ <line x1="276.51" y1="100.13" x2="283.84" y2="100.13" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
48
+ <polygon points="275.57 126.08 283.84 126.08 285.04 130.8 274.17 130.8 275.57 126.08" style="fill: #fbc01a;"/>
49
+ <line x1="283.84" y1="126.08" x2="275.57" y2="126.08" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
50
+ </g>
51
+ <rect x="218.79" y="91.42" width="69.46" height="3.98" style="fill: #f9b500;"/>
52
+ <rect x="218.79" y="130.8" width="69.46" height="3.98" style="fill: #fbc01a;"/>
53
+ <rect x="209.25" y="134.79" width="88.53" height="4.09" style="fill: #f4b200;"/>
54
+ <path d="m216.67,88.29l34.23-15.08c2.1-.93,4.5-.93,6.6,0l34.23,15.08c1.62.71,1.11,3.13-.66,3.13h-73.75c-1.77,0-2.28-2.42-.66-3.13Z" style="fill: #fbc01a;"/>
55
+ <path d="m230.81,86.16l21.33-9.4c1.31-.58,2.8-.58,4.11,0l21.33,9.4c1.01.44.69,1.95-.41,1.95h-45.96c-1.1,0-1.42-1.51-.41-1.95Z" style="fill: #f4b200;"/>
56
+ <path d="m256.72,83.21c0-1.39-1.13-2.51-2.51-2.51s-2.51,1.13-2.51,2.51,1.13,2.51,2.51,2.51,2.51-1.13,2.51-2.51Z" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
57
+ <line x1="218.8" y1="131.54" x2="288.24" y2="131.54" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
58
+ <path d="m143.42,43.43l2.99-1.92c34.81-22.3,81.11-12.16,103.41,22.65h0" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 4px;"/>
59
+ <polyline points="242.93 64.16 250.34 64.16 250.34 56.12" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 3px;"/>
60
+ <path d="m253.66,141.68l-3.52,4.34c-28.53,29.92-75.91,31.04-105.83,2.5h0" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 4px;"/>
61
+ <polyline points="151 146.9 143.8 148.65 145.77 156.76" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 3px;"/>
62
+ </g>
63
+ </svg>
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ viewBox="0 0 52 52"
5
+ width="100"
6
+ height="100"
7
+ >
8
+ <style>
9
+ .svg-failed {
10
+ stroke: white;
11
+ stroke-width: 5;
12
+ stroke-miterlimit: 10;
13
+ stroke-linecap: round;
14
+ stroke-linejoin: round;
15
+ fill: none;
16
+ animation: svg-failed-scale 0.3s ease-in-out 0.9s both;
17
+ }
18
+
19
+ .svg-failed-circle {
20
+ stroke: none;
21
+ fill: #FF5A5F;
22
+ }
23
+
24
+ .svg-failed-x {
25
+ stroke-dasharray: 48;
26
+ stroke-dashoffset: 48;
27
+ animation: svg-failed-draw 0.5s ease forwards 0.6s;
28
+ }
29
+
30
+ @keyframes svg-failed-draw {
31
+ to {
32
+ stroke-dashoffset: 0;
33
+ }
34
+ }
35
+
36
+ @keyframes svg-failed-scale {
37
+ 0%, 100% {
38
+ transform: scale(1);
39
+ }
40
+ 50% {
41
+ transform: scale(1.1);
42
+ }
43
+ }
44
+ </style>
45
+
46
+ <circle class="svg-failed-circle" cx="26" cy="26" r="25" />
47
+ <!-- X mark: two lines crossing -->
48
+ <path
49
+ class="svg-failed svg-failed-x"
50
+ d="M16 16 L36 36"
51
+ />
52
+ <path
53
+ class="svg-failed svg-failed-x"
54
+ d="M36 16 L16 36"
55
+ />
56
+ </svg>
@@ -0,0 +1,50 @@
1
+ <svg class="pl" width="300" height="300" viewBox="0 0 300 300" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <style>
3
+ .pl__ring { animation: ringA 3s linear infinite; }
4
+ .pl__ring--a { stroke: #F79E1B; }
5
+ .pl__ring--b { animation-name: ringB; stroke: #F79E1B; }
6
+ .pl__ring--c { animation-name: ringC; stroke: #F79E1B; }
7
+ .pl__ring--d { animation-name: ringD; stroke: #F79E1B; }
8
+
9
+ @keyframes ringA {
10
+ from, 4% { stroke-dasharray: 0 660; stroke-width: 20; stroke-dashoffset: -330; }
11
+ 12% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -335; }
12
+ 32% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -595; }
13
+ 40%, 54% { stroke-dasharray: 0 660; stroke-width: 20; stroke-dashoffset: -660; }
14
+ 62% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -665; }
15
+ 82% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -925; }
16
+ 90%, to { stroke-dasharray: 0 660; stroke-width: 20; stroke-dashoffset: -990; }
17
+ }
18
+ @keyframes ringB {
19
+ from, 12% { stroke-dasharray: 0 220; stroke-width: 20; stroke-dashoffset: -110; }
20
+ 20% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -115; }
21
+ 40% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -195; }
22
+ 48%, 62% { stroke-dasharray: 0 220; stroke-width: 20; stroke-dashoffset: -220; }
23
+ 70% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -225; }
24
+ 90% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -305; }
25
+ 98%, to { stroke-dasharray: 0 220; stroke-width: 20; stroke-dashoffset: -330; }
26
+ }
27
+ @keyframes ringC {
28
+ from { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: 0; }
29
+ 8% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -5; }
30
+ 28% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -175; }
31
+ 36%, 58% { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -220; }
32
+ 66% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -225; }
33
+ 86% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -395; }
34
+ 94%, to { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -440; }
35
+ }
36
+ @keyframes ringD {
37
+ from, 8% { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: 0; }
38
+ 16% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -5; }
39
+ 36% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -175; }
40
+ 44%, 50% { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -220; }
41
+ 58% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -225; }
42
+ 78% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -395; }
43
+ 86%, to { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -440; }
44
+ }
45
+ </style>
46
+ <circle class="pl__ring pl__ring--a" cx="150" cy="150" r="105" fill="none" stroke-width="20" stroke-dasharray="0 660" stroke-dashoffset="-330" stroke-linecap="round"/>
47
+ <circle class="pl__ring pl__ring--b" cx="150" cy="150" r="35" fill="none" stroke-width="20" stroke-dasharray="0 220" stroke-dashoffset="-110" stroke-linecap="round"/>
48
+ <circle class="pl__ring pl__ring--c" cx="115" cy="150" r="70" fill="none" stroke-width="20" stroke-dasharray="0 440" stroke-linecap="round"/>
49
+ <circle class="pl__ring pl__ring--d" cx="185" cy="150" r="70" fill="none" stroke-width="20" stroke-dasharray="0 440" stroke-linecap="round"/>
50
+ </svg>
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ viewBox="0 0 52 52"
5
+ width="100"
6
+ height="100"
7
+ >
8
+ <style>
9
+ .svg-checkmark {
10
+ stroke: white;
11
+ stroke-width: 5;
12
+ stroke-miterlimit: 10;
13
+ stroke-linecap: round;
14
+ stroke-linejoin: round;
15
+ fill: none;
16
+ animation: svg-success-scale 0.3s ease-in-out 0.9s both;
17
+ }
18
+
19
+ .svg-checkmark-circle {
20
+ stroke: none;
21
+ fill: #00D290;
22
+ }
23
+
24
+ .svg-checkmark-check {
25
+ stroke-dasharray: 48;
26
+ stroke-dashoffset: 48;
27
+ animation: svg-success-draw 0.5s ease forwards 0.6s;
28
+ }
29
+
30
+ @keyframes svg-success-draw {
31
+ to {
32
+ stroke-dashoffset: 0;
33
+ }
34
+ }
35
+
36
+ @keyframes svg-success-scale {
37
+ 0%, 100% {
38
+ transform: scale(1);
39
+ }
40
+ 50% {
41
+ transform: scale(1.1);
42
+ }
43
+ }
44
+ </style>
45
+
46
+ <circle class="svg-checkmark-circle" cx="26" cy="26" r="25" />
47
+ <path
48
+ class="svg-checkmark svg-checkmark-check"
49
+ d="M14.1 27.2l7.1 7.2 16.7-16.8"
50
+ />
51
+ </svg>
@@ -11,3 +11,4 @@
11
11
  //= require spree_cm_commissioner/selected_field_filter_origin_destination
12
12
  //= require spree_cm_commissioner/location_checkbox_manager
13
13
  //= require spree_cm_commissioner/trip_stop_selection
14
+ //= require spree_cm_commissioner/tenant_payment_icon_fields
@@ -0,0 +1,65 @@
1
+ document.addEventListener('DOMContentLoaded', function () {
2
+ // Initialize Select2 for all tenant-payment-icon-select elements
3
+ if (window.$ && $.fn.select2) {
4
+ $('.tenant-payment-icon-select').each(function () {
5
+ $(this).select2({
6
+ width: '100%'
7
+ });
8
+ });
9
+ }
10
+
11
+ // Handle icon selection change
12
+ document.querySelectorAll('.tenant-payment-icon-select').forEach(function (select) {
13
+ select.addEventListener('change', function (e) {
14
+ const field = e.target.name.match(/\[([^\]]*)\]$/)[1]; // Extract field name
15
+ const preview = document.getElementById(`icon-preview-${field}`);
16
+ const removeBtn = document.querySelector(`.remove-icon-btn[data-target="${field}"]`);
17
+ const iconPath = e.target.value;
18
+
19
+ if (!preview || !removeBtn) return;
20
+
21
+ if (!iconPath) {
22
+ preview.innerHTML = '<span class="no-icon-placeholder"></span>';
23
+ removeBtn.classList.add('hidden');
24
+ return;
25
+ }
26
+
27
+ // Fetch SVG for the selected icon
28
+ fetch(`/admin/vector_icons/svg?path=${encodeURIComponent(iconPath)}`)
29
+ .then((response) => {
30
+ if (!response.ok) throw new Error('Failed to fetch SVG');
31
+ return response.text();
32
+ })
33
+ .then((svg) => {
34
+ preview.innerHTML = svg;
35
+ removeBtn.classList.remove('hidden');
36
+ })
37
+ .catch((error) => {
38
+ console.error('Error fetching SVG:', error);
39
+ preview.innerHTML = '<span class="no-icon-placeholder">Error loading icon</span>';
40
+ });
41
+ });
42
+ });
43
+
44
+ document.addEventListener('click', function (e) {
45
+ if (!e.target.classList.contains('remove-icon-btn')) return;
46
+
47
+ const field = e.target.getAttribute('data-target');
48
+ const select = document.querySelector(`.tenant-payment-icon-select[name*="[${field}]"]`);
49
+ const preview = document.getElementById(`icon-preview-${field}`);
50
+ const removeBtn = e.target;
51
+
52
+ if (!select || !preview || !removeBtn) return;
53
+
54
+ // Clear the select input
55
+ select.value = '';
56
+
57
+ if (window.$ && $(select).hasClass('select2-hidden-accessible')) {
58
+ $(select).val('').trigger('change.select2');
59
+ } else {
60
+ select.dispatchEvent(new Event('change', { bubbles: true }));
61
+ }
62
+ preview.innerHTML = '<span class="no-icon-placeholder"></span>';
63
+ removeBtn.classList.add('hidden');
64
+ });
65
+ });
@@ -3,3 +3,4 @@
3
3
  @import "spree_cm_commissioner/backend/service_calendar";
4
4
  @import "spree_cm_commissioner/backend/guest_qr_code";
5
5
  @import "spree_cm_commissioner/backend/vehicle_seat";
6
+ @import "spree_cm_commissioner/backend/tenant_payment_icon_fields";
@@ -0,0 +1,60 @@
1
+ .payment-icon-preview {
2
+ width: 80px;
3
+ height: 80px;
4
+ background: #f8f9fa;
5
+ border: 1px dashed #ccc;
6
+ display: inline-flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ cursor: pointer;
10
+ }
11
+
12
+ .payment-icon-preview svg {
13
+ width: 100%;
14
+ height: 100%;
15
+ object-fit: contain;
16
+ }
17
+
18
+
19
+ .no-icon-placeholder {
20
+ width: 40px;
21
+ height: 40px;
22
+ border: 1px dashed #ddd;
23
+ background: #f8f9fa;
24
+ display: inline-block;
25
+ }
26
+
27
+ .icon-preview-container {
28
+ position: relative;
29
+ display: inline-block;
30
+ }
31
+
32
+ .remove-icon-btn {
33
+ position: absolute;
34
+ top: -8px;
35
+ right: -8px;
36
+ width: 24px;
37
+ height: 24px;
38
+ border-radius: 50%;
39
+ background: #dc3545;
40
+ color: white;
41
+ border: 2px solid white;
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ cursor: pointer;
46
+ font-size: 12px;
47
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
48
+ transition: all 0.2s ease;
49
+ z-index: 10;
50
+ }
51
+
52
+ .remove-icon-btn:hover {
53
+ background: #c82333;
54
+ transform: scale(1.1);
55
+ box-shadow: 0 3px 6px rgba(0,0,0,0.3);
56
+ }
57
+
58
+ .remove-icon-btn.hidden {
59
+ display: none;
60
+ }
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class TenantsController < Spree::Admin::ResourceController
4
+ before_action :load_vector_icons, only: %i[new edit]
5
+
4
6
  # override
5
7
  def collection
6
8
  params[:q] = {} if params[:q].blank?
@@ -31,6 +33,12 @@ module Spree
31
33
  def collection_url(options = {})
32
34
  admin_tenants_url(options)
33
35
  end
36
+
37
+ private
38
+
39
+ def load_vector_icons
40
+ @vector_icons = SpreeCmCommissioner::VectorIcon.all
41
+ end
34
42
  end
35
43
  end
36
44
  end
@@ -38,7 +38,24 @@ module Spree
38
38
  def update
39
39
  spree_authorize! :update, spree_current_order, order_token
40
40
 
41
- if resource.update(guest_params)
41
+ if guest_params[:guest_dynamic_fields_attributes]
42
+ resource.guest_dynamic_fields.destroy_all
43
+
44
+ guest_params[:guest_dynamic_fields_attributes].each do |attr|
45
+ field = resource.guest_dynamic_fields.build(attr.except(:id))
46
+
47
+ if field.dynamic_field.requires_dynamic_field_options?
48
+ option = field.dynamic_field.dynamic_field_options.find_by(id: field.value)
49
+ field.dynamic_field_option = option if option
50
+ end
51
+
52
+ field.save!
53
+ end
54
+ end
55
+
56
+ resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
57
+
58
+ if resource.save
42
59
  render_serialized_payload { serialize_resource(resource) }
43
60
  else
44
61
  render_error_payload(resource, 400)
@@ -76,7 +93,7 @@ module Spree
76
93
  :upload_later,
77
94
  :country_code,
78
95
  :contact,
79
- guest_dynamic_fields_attributes: %i[id dynamic_field_id value _destroy]
96
+ guest_dynamic_fields_attributes: %i[id dynamic_field_id dynamic_field_option_id value _destroy]
80
97
  )
81
98
  end
82
99
  end
@@ -5,6 +5,10 @@ module SpreeCmCommissioner
5
5
  included do
6
6
  preference :assetlinks, :string, default: ''
7
7
  preference :apple_app_site_association, :string, default: ''
8
+ preference :payment_checkout_image, :string, default: ''
9
+ preference :payment_failed_image, :string, default: ''
10
+ preference :payment_success_image, :string, default: ''
11
+ preference :payment_loader, :string, default: ''
8
12
  end
9
13
  end
10
14
  end
@@ -6,15 +6,27 @@ module SpreeCmCommissioner
6
6
  has_many :guest_dynamic_fields, class_name: 'SpreeCmCommissioner::GuestDynamicField', dependent: :destroy
7
7
  has_many :product_dynamic_fields, class_name: 'SpreeCmCommissioner::ProductDynamicField', dependent: :destroy
8
8
 
9
- enum data_type: { string: 0, integer: 1, boolean: 2, checkbox: 3, radio: 4 }
9
+ enum data_type: { text: 0, number: 1, boolean: 2, checkbox: 3, radio: 4, selection: 5, textarea: 6 }
10
10
 
11
11
  accepts_nested_attributes_for :dynamic_field_options, allow_destroy: true, reject_if: :all_blank
12
12
 
13
13
  validates :label, presence: true
14
14
  validates :data_type, presence: true
15
+ validates :configurations, presence: true, allow_blank: false
15
16
 
16
- def selection?
17
- checkbox? || radio?
17
+ def requires_dynamic_field_options?
18
+ checkbox? || radio? || selection?
19
+ end
20
+
21
+ def multiple_select
22
+ return nil unless selection?
23
+
24
+ configurations['multiple_select'] == true
25
+ end
26
+
27
+ def multiple_select=(value)
28
+ self.configurations ||= {}
29
+ self.configurations['multiple_select'] = ActiveModel::Type::Boolean.new.cast(value)
18
30
  end
19
31
  end
20
32
  end
@@ -1,8 +1,12 @@
1
1
  module SpreeCmCommissioner
2
2
  class DynamicFieldOption < SpreeCmCommissioner::Base
3
3
  belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
4
+ has_many :guest_dynamic_fields, class_name: 'SpreeCmCommissioner::GuestDynamicField', dependent: :restrict_with_error
5
+
6
+ enum status: { active: 0, draft: 1, archived: 2 }
4
7
 
5
8
  validates :value, presence: true, uniqueness: { scope: :dynamic_field_id }
9
+ validates :status, presence: true
6
10
  validate :parent_field_must_be_selection_type
7
11
 
8
12
  private
@@ -10,7 +14,7 @@ module SpreeCmCommissioner
10
14
  def parent_field_must_be_selection_type
11
15
  return unless dynamic_field
12
16
 
13
- return if dynamic_field.selection?
17
+ return if dynamic_field.requires_dynamic_field_options?
14
18
 
15
19
  errors.add(:dynamic_field, 'must be a selection type field')
16
20
  end
@@ -2,9 +2,11 @@ module SpreeCmCommissioner
2
2
  class GuestDynamicField < SpreeCmCommissioner::Base
3
3
  belongs_to :guest, class_name: 'SpreeCmCommissioner::Guest', optional: false
4
4
  belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
5
+ belongs_to :dynamic_field_option, class_name: 'SpreeCmCommissioner::DynamicFieldOption', optional: true
5
6
 
6
7
  validates :value, presence: true
7
8
  validate :validate_value_format, if: -> { value.present? && dynamic_field.present? }
9
+ validate :validate_option_reference, if: -> { dynamic_field_option.present? }
8
10
 
9
11
  private
10
12
 
@@ -12,14 +14,30 @@ module SpreeCmCommissioner
12
14
  return if dynamic_field.blank?
13
15
 
14
16
  case dynamic_field.data_type.to_s
15
- when 'integer'
17
+ when 'number'
16
18
  errors.add(:value, 'must be a number') unless value.to_s.match?(/\A\d+\z/)
17
19
  when 'boolean'
18
- errors.add(:value, 'must be true or false') unless %w[true false 1 0].include?(value.to_s.downcase)
19
- when 'checkbox', 'radio'
20
+ errors.add(:value, 'must be true or false') unless %w[true false].include?(value.to_s.downcase)
21
+ when 'checkbox', 'radio', 'selection'
22
+ validate_option_value
23
+ end
24
+ end
25
+
26
+ def validate_option_value
27
+ if dynamic_field_option.present?
28
+ self.value ||= dynamic_field_option.value
29
+ else
20
30
  valid_options = dynamic_field.dynamic_field_options.pluck(:id).map(&:to_s)
21
31
  errors.add(:value, 'is not a valid option') unless valid_options.include?(value)
22
32
  end
23
33
  end
34
+
35
+ def validate_option_reference
36
+ return if dynamic_field.blank? || dynamic_field_option.blank?
37
+
38
+ return if dynamic_field_option.dynamic_field_id == dynamic_field_id
39
+
40
+ errors.add(:dynamic_field_option, 'must belong to the same dynamic field')
41
+ end
24
42
  end
25
43
  end
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldOptionSerializer < BaseSerializer
5
- set_type :dynamic_field_option
6
-
7
- attributes :id, :value, :dynamic_field_id, :created_at, :updated_at
5
+ attributes :id, :value, :dynamic_field_id, :status, :created_at, :updated_at
8
6
  end
9
7
  end
10
8
  end
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldSerializer < BaseSerializer
5
- set_type :dynamic_field
6
-
7
- attributes :id, :label, :data_type, :vendor_id, :created_at, :updated_at
5
+ attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at
8
6
 
9
7
  has_many :dynamic_field_options, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
10
8
  end
@@ -4,9 +4,10 @@ module SpreeCmCommissioner
4
4
  class GuestDynamicFieldSerializer < BaseSerializer
5
5
  set_type :guest_dynamic_field
6
6
 
7
- attributes :id, :value, :guest_id, :dynamic_field_id, :created_at, :updated_at
7
+ attributes :id, :value, :guest_id, :dynamic_field_id, :dynamic_field_option_id, :created_at, :updated_at
8
8
 
9
9
  belongs_to :dynamic_field, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldSerializer
10
+ belongs_to :dynamic_field_option, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
10
11
  end
11
12
  end
12
13
  end
@@ -3,17 +3,21 @@
3
3
  <div class="col-6">
4
4
  <%= f.field_container :name do %>
5
5
  <%= f.label :name, raw(Spree.t(:name) + required_span_tag) %>
6
- <%= f.text_field :name, required: true, class: 'form-control', placeholder: 'eg. bookme plus'%>
7
- <%= f.error_message_on :name %>
6
+ <%= f.text_field :name, required: true, class: 'form-control', placeholder: 'eg. bookme plus' %>
7
+ <% if f.object.errors[:name].any? %>
8
+ <div class="error text-danger"><%= f.object.errors[:name].join(', ') %></div>
9
+ <% end %>
8
10
  <% end %>
9
11
  </div>
10
12
 
11
- <!-- Slug Field (only show if editing) -->
13
+ <!-- Slug Field -->
12
14
  <div class="col-6">
13
15
  <%= f.field_container :slug do %>
14
16
  <%= f.label :slug, raw(Spree.t(:slug)) %>
15
17
  <%= f.text_field :slug, class: 'form-control', placeholder: 'slug' %>
16
- <%= f.error_message_on :slug %>
18
+ <% if f.object.errors[:slug].any? %>
19
+ <div class="error text-danger"><%= f.object.errors[:slug].join(', ') %></div>
20
+ <% end %>
17
21
  <% end %>
18
22
  </div>
19
23
 
@@ -22,16 +26,20 @@
22
26
  <%= f.field_container :description do %>
23
27
  <%= f.label :description, raw(Spree.t(:description)) %>
24
28
  <%= f.text_area :description, class: 'form-control', placeholder: 'description' %>
25
- <%= f.error_message_on :description %>
29
+ <% if f.object.errors[:description].any? %>
30
+ <div class="error text-danger"><%= f.object.errors[:description].join(', ') %></div>
31
+ <% end %>
26
32
  <% end %>
27
33
  </div>
28
34
 
29
- <!-- Host Field -->
35
+ <!-- Host Field -->
30
36
  <div class="col-12">
31
37
  <%= f.field_container :host do %>
32
38
  <%= f.label :host, raw(Spree.t(:host) + required_span_tag) %>
33
39
  <%= f.text_field :host, required: true, class: 'form-control', placeholder: 'host' %>
34
- <%= f.error_message_on :host %>
40
+ <% if f.object.errors[:host].any? %>
41
+ <div class="error text-danger"><%= f.object.errors[:host].join(', ') %></div>
42
+ <% end %>
35
43
  <% end %>
36
44
  </div>
37
45
 
@@ -39,21 +47,26 @@
39
47
  <div class="col-12">
40
48
  <%= f.field_container :preferred_assetlinks do %>
41
49
  <%= f.label :preferred_assetlinks, raw(Spree.t(:assetlinks)) %>
42
- <%= f.text_area :preferred_assetlinks, class: 'form-control',
43
- placeholder: 'example:
44
- [
45
- {
46
- "relation": ["delegate_permission/common.handle_all_urls"],
47
- "target": {
48
- "namespace": "android_app",
49
- "package_name": "com.yourapp.app",
50
- "sha256_cert_fingerprints": [
51
- "SHA256_CERTIFICATE_FINGERPRINT_HERE"
52
- ]
53
- }
54
- }
55
- ]', rows: 5 %>
56
- <%= f.error_message_on :preferred_assetlinks %>
50
+ <%= f.text_area :preferred_assetlinks, class: 'form-control', rows: 5,
51
+ placeholder: <<~JSON.strip
52
+ example:
53
+ [
54
+ {
55
+ "relation": ["delegate_permission/common.handle_all_urls"],
56
+ "target": {
57
+ "namespace": "android_app",
58
+ "package_name": "com.yourapp.app",
59
+ "sha256_cert_fingerprints": [
60
+ "SHA256_CERTIFICATE_FINGERPRINT_HERE"
61
+ ]
62
+ }
63
+ }
64
+ ]
65
+ JSON
66
+ %>
67
+ <% if f.object.errors[:preferred_assetlinks].any? %>
68
+ <div class="error text-danger"><%= f.object.errors[:preferred_assetlinks].join(', ') %></div>
69
+ <% end %>
57
70
  <% end %>
58
71
  </div>
59
72
 
@@ -61,25 +74,30 @@
61
74
  <div class="col-12">
62
75
  <%= f.field_container :preferred_apple_app_site_association do %>
63
76
  <%= f.label :preferred_apple_app_site_association, raw(Spree.t(:apple_app_site_association)) %>
64
- <%= f.text_area :preferred_apple_app_site_association, class: 'form-control',
65
- placeholder: 'example:
66
- {
67
- "webcredentials": {
68
- "apps": [
69
- "TEAM_ID.com.yourapp.app"
70
- ]
71
- },
72
- "applinks": {
73
- "apps": [],
74
- "details": [
75
- {
76
- "appID": "TEAM_ID.com.yourapp.app",
77
- "paths": ["*"]
77
+ <%= f.text_area :preferred_apple_app_site_association, class: 'form-control', rows: 5,
78
+ placeholder: <<~JSON.strip
79
+ example:
80
+ {
81
+ "webcredentials": {
82
+ "apps": [
83
+ "TEAM_ID.com.yourapp.app"
84
+ ]
85
+ },
86
+ "applinks": {
87
+ "apps": [],
88
+ "details": [
89
+ {
90
+ "appID": "TEAM_ID.com.yourapp.app",
91
+ "paths": ["*"]
92
+ }
93
+ ]
78
94
  }
79
- ]
80
- }
81
- }', rows: 5 %>
82
- <%= f.error_message_on :preferred_apple_app_site_association %>
95
+ }
96
+ JSON
97
+ %>
98
+ <% if f.object.errors[:preferred_apple_app_site_association].any? %>
99
+ <div class="error text-danger"><%= f.object.errors[:preferred_apple_app_site_association].join(', ') %></div>
100
+ <% end %>
83
101
  <% end %>
84
102
  </div>
85
103
 
@@ -87,8 +105,57 @@
87
105
  <div class="col-6">
88
106
  <%= f.field_container :state do %>
89
107
  <%= f.label :state, raw(Spree.t(:state)) %>
90
- <%= f.select :state, options_for_select([['Enabled', 'enabled'], ['Disabled', 'disabled']], @object.state), { required: true }, class: 'select2 form-control' %>
91
- <%= f.error_message_on :state %>
108
+ <%= f.select :state,
109
+ options_for_select([['Enabled', 'enabled'], ['Disabled', 'disabled']], f.object&.state),
110
+ { required: true },
111
+ class: 'select2 form-control' %>
112
+ <% if f.object.errors[:state].any? %>
113
+ <div class="error text-danger"><%= f.object.errors[:state].join(', ') %></div>
114
+ <% end %>
92
115
  <% end %>
93
116
  </div>
94
117
  </div>
118
+
119
+ <div data-hook="admin_tenant_form_fields" class="row">
120
+ <div class="col-12">
121
+ <div class="row gy-4">
122
+ <% payment_icon_fields = [
123
+ { field: :preferred_payment_checkout_image, label: Spree.t(:payment_checkout_image), target: 'checkout' },
124
+ { field: :preferred_payment_failed_image, label: Spree.t(:payment_failed_image), target: 'failed' },
125
+ { field: :preferred_payment_success_image, label: Spree.t(:payment_success_image), target: 'success' },
126
+ { field: :preferred_payment_loader, label: Spree.t(:payment_loader), target: 'loader' }
127
+ ] %>
128
+
129
+ <% payment_icon_fields.each do |icon| %>
130
+ <div class="col-md-3">
131
+ <%= f.field_container icon[:field] do %>
132
+ <div class="d-flex flex-column align-items-center text-center">
133
+ <label class="form-label fw-bold mb-2" for="tenant_<%= icon[:field] %>">
134
+ <%= icon[:label] %>
135
+ </label>
136
+
137
+ <div class="icon-preview-container mb-2" id="icon-preview-container-<%= icon[:field] %>">
138
+ <span class="payment-icon-preview" id="icon-preview-<%= icon[:field] %>">
139
+ <% if f.object.send(icon[:field]).present? %>
140
+ <%= render_vector_icon(f.object.send(icon[:field])) %>
141
+ <% else %>
142
+ <span class="no-icon-placeholder"></span>
143
+ <% end %>
144
+ </span>
145
+ <span class="remove-icon-btn <%= 'hidden' unless f.object.send(icon[:field]).present? %>" data-target="<%= icon[:field] %>">&times;</span>
146
+ </div>
147
+ </div>
148
+
149
+ <%= f.collection_select icon[:field],
150
+ @vector_icons, :path, :path,
151
+ { include_blank: 'None' },
152
+ { class: 'select2 form-control tenant-payment-icon-select mt-2', data: { target: icon[:target] } } %>
153
+ <% if f.object.errors[icon[:field]].any? %>
154
+ <div class="text-danger small mt-1"><%= f.object.errors[icon[:field]].join(', ') %></div>
155
+ <% end %>
156
+ <% end %>
157
+ </div>
158
+ <% end %>
159
+ </div>
160
+ </div>
161
+ </div>
@@ -0,0 +1,6 @@
1
+ class AddConfigurationsToCmDynamicField < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :cm_dynamic_fields, :configurations, :jsonb, default: {}, null: false, if_not_exists: true
4
+ add_index :cm_dynamic_fields, :configurations, if_not_exists: true
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddDynamicFieldOptionToGuestDynamicField < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_reference :cm_guest_dynamic_fields, :dynamic_field_option, index: true, foreign_key: { to_table: :cm_dynamic_field_options }, if_not_exists: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddStatusToDynamicFieldOption < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :cm_dynamic_field_options, :status, :integer, default: 0, if_not_exists: true
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '1.17.0-pre5'.freeze
2
+ VERSION = '1.17.0-pre7'.freeze
3
3
 
4
4
  module_function
5
5
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_cm_commissioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.0.pre.pre5
4
+ version: 1.17.0.pre.pre7
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-03 00:00:00.000000000 Z
11
+ date: 2025-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -600,6 +600,10 @@ files:
600
600
  - app/assets/images/cm-fitness-room-icon.svg
601
601
  - app/assets/images/cm-front-desk-icon.svg
602
602
  - app/assets/images/cm-hair-dryer-icon.svg
603
+ - app/assets/images/cm-hangmeas-checkout_image.svg
604
+ - app/assets/images/cm-hangmeas-failed.svg
605
+ - app/assets/images/cm-hangmeas-loader.svg
606
+ - app/assets/images/cm-hangmeas-success.svg
603
607
  - app/assets/images/cm-hiking-icon.svg
604
608
  - app/assets/images/cm-iron-icon.svg
605
609
  - app/assets/images/cm-lcd-tv-icon.svg
@@ -705,6 +709,7 @@ files:
705
709
  - app/assets/javascripts/spree_cm_commissioner/selected_field_filter_origin_destination.js
706
710
  - app/assets/javascripts/spree_cm_commissioner/telegram.js
707
711
  - app/assets/javascripts/spree_cm_commissioner/telegram/order_confirmation.js
712
+ - app/assets/javascripts/spree_cm_commissioner/tenant_payment_icon_fields.js
708
713
  - app/assets/javascripts/spree_cm_commissioner/trip_stop_selection.js
709
714
  - app/assets/javascripts/spree_cm_commissioner/update_popup_confirmation.js
710
715
  - app/assets/javascripts/spree_cm_commissioner/vehicle_seat.js
@@ -714,6 +719,7 @@ files:
714
719
  - app/assets/stylesheets/spree_cm_commissioner/backend/guest_qr_code.scss
715
720
  - app/assets/stylesheets/spree_cm_commissioner/backend/invoice.scss
716
721
  - app/assets/stylesheets/spree_cm_commissioner/backend/service_calendar.scss
722
+ - app/assets/stylesheets/spree_cm_commissioner/backend/tenant_payment_icon_fields.scss
717
723
  - app/assets/stylesheets/spree_cm_commissioner/backend/vehicle_seat.scss
718
724
  - app/assets/stylesheets/spree_cm_commissioner/telegram.css
719
725
  - app/assets/stylesheets/spree_cm_commissioner/telegram/telegram_bot.css.scss
@@ -2511,6 +2517,9 @@ files:
2511
2517
  - db/migrate/20250611023548_add_country_code_to_guests.rb
2512
2518
  - db/migrate/20250612035937_add_intel_phone_number_to_guests.rb
2513
2519
  - db/migrate/20250616084219_add_description_to_cm_vendor_place.rb
2520
+ - db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb
2521
+ - db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb
2522
+ - db/migrate/20250702091935_add_status_to_dynamic_field_option.rb
2514
2523
  - docker-compose.yml
2515
2524
  - docs/option_types/attr_types.md
2516
2525
  - docs/private_key.pem