|
11 | 11 | <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet"> |
12 | 12 |
|
13 | 13 | <style> |
14 | | - body{ |
15 | | - font-family: "Outfit", system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; |
16 | | - } |
| 14 | + body { |
| 15 | + font-family: "Outfit", system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; |
| 16 | + } |
| 17 | +
|
| 18 | + [x-cloak] { |
| 19 | + display: none !important; |
| 20 | + } |
17 | 21 | </style> |
18 | 22 |
|
19 | 23 | @stack('styles') |
20 | 24 | </head> |
21 | 25 |
|
22 | | -<body> |
| 26 | +<body class="light"> |
23 | 27 | @include('frontend.partials.header') {{-- optional --}} |
24 | 28 | <main> |
25 | 29 | @yield('content') |
26 | 30 | </main> |
| 31 | + |
| 32 | + |
| 33 | + <div x-init="console.log($store.toast)" x-cloak x-show="$store.toast.visible" x-transition @click="$store.toast.visible = false" |
| 34 | + class="toast fixed top-4 right-4 z-50 cursor-pointer"> |
| 35 | + <div :class="`alert ${$store.toast.type === 'success' ? 'alert-success' : 'alert-error'} text-white`"> |
| 36 | + <span x-text="$store.toast.message"></span> |
| 37 | + </div> |
| 38 | + </div> |
| 39 | + |
27 | 40 | @include('frontend.partials.footer') {{-- optional --}} |
28 | 41 |
|
29 | 42 | <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> |
|
32 | 45 | crossorigin="anonymous" referrerpolicy="no-referrer"></script> |
33 | 46 | <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> |
34 | 47 | @stack('scripts') |
| 48 | + |
| 49 | + |
| 50 | + <script> |
| 51 | + document.addEventListener('alpine:init', () => { |
| 52 | + Alpine.store('cart', { |
| 53 | + items: @json(session()->get('cart')['items'] ?? []), |
| 54 | + attributes: @json(session()->get('cart')['attributes'] ?? []), |
| 55 | + reset(cart) { |
| 56 | + this.items = cart.items ?? []; |
| 57 | + this.attributes = cart.attributes ?? []; |
| 58 | + } |
| 59 | + }); |
| 60 | +
|
| 61 | + |
| 62 | + Alpine.store('toast', { |
| 63 | + visible: false, |
| 64 | + message: '', |
| 65 | + type: 'success', // 'success' or 'error' |
| 66 | +
|
| 67 | + show(success, message) { |
| 68 | + this.type = success ? 'success' : 'error'; |
| 69 | + this.message = message; |
| 70 | + this.visible = true; |
| 71 | +
|
| 72 | + setTimeout(() => { |
| 73 | + this.visible = false; |
| 74 | + }, 3000); |
| 75 | + } |
| 76 | + }); |
| 77 | +
|
| 78 | + Alpine.data('cart', () => ({ |
| 79 | + addToCart(productId) { |
| 80 | + axios.post('/cart/add', { |
| 81 | + product_id: productId, |
| 82 | + quantity: 1 |
| 83 | + }) |
| 84 | + .then(response => { |
| 85 | + Alpine.store('cart').reset(response.data.data); |
| 86 | + // Alpine.store('cart').addItem({ |
| 87 | + // id: productId, |
| 88 | + // title: response.data.title || 'Product ' + productId, |
| 89 | + // quantity: 1 |
| 90 | + // }); |
| 91 | + Alpine.store('toast').show(true, response.data.message || |
| 92 | + 'Added to cart!'); |
| 93 | + }) |
| 94 | + .catch(error => { |
| 95 | + Alpine.store('toast').show(false, error.response?.data?.message || |
| 96 | + 'Add to cart failed.'); |
| 97 | + }); |
| 98 | + } |
| 99 | + })); |
| 100 | +
|
| 101 | + }); |
| 102 | + </script> |
35 | 103 | </body> |
36 | 104 |
|
37 | 105 | </html> |
0 commit comments