|
115 | 115 | <%= order.name %> |
116 | 116 | </td> |
117 | 117 | <td style="padding: 1rem;"> |
118 | | - <% status_color = case order.status |
119 | | - when 'pending' then '#fff3cd' |
120 | | - when 'completed' then '#d4edda' |
121 | | - when 'cancelled' then '#f8d7da' |
122 | | - else '#e2e3e5' |
123 | | - end %> |
124 | | - <span style="background: <%= status_color %>; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem; font-weight: 600; text-transform: capitalize;"><%= order.status %></span> |
| 118 | + <select class="order-status" data-order-id="<%= order.id %>" style="padding: 4px 8px; border-radius: 4px; font-size: 0.85rem; font-weight: 600; border: 1px solid #ddd;"> |
| 119 | + <option value="pending" <%= 'selected' if order.status == 'pending' %>>Pending</option> |
| 120 | + <option value="completed" <%= 'selected' if order.status == 'completed' %>>Completed</option> |
| 121 | + <option value="cancelled" <%= 'selected' if order.status == 'cancelled' %>>Cancelled</option> |
| 122 | + </select> |
125 | 123 | </td> |
126 | 124 | <td style="padding: 1rem; color: #999; font-size: 0.9rem;"> |
127 | 125 | <%= order.created_at.strftime('%b %d, %Y') %> |
|
135 | 133 | </main> |
136 | 134 |
|
137 | 135 | <script> |
138 | | - const addItemForm = document.getElementById('add-item-form'); |
139 | | - const addItemBtn = document.getElementById('add-item-btn'); |
| 136 | + const addItemForm = document.getElementById('add-item-form'); |
| 137 | + const addItemBtn = document.getElementById('add-item-btn'); |
140 | 138 |
|
141 | | - addItemForm?.addEventListener('submit', async (e) => { |
142 | | - e.preventDefault(); |
143 | | - |
144 | | - addItemBtn.disabled = true; |
145 | | - addItemBtn.textContent = 'Adding...'; |
146 | | - |
147 | | - const data = { |
148 | | - shop_item: { |
149 | | - name: document.getElementById('item_name').value, |
150 | | - description: document.getElementById('item_description').value, |
151 | | - cost: parseFloat(document.getElementById('item_cost').value), |
152 | | - status: document.getElementById('item_status').value, |
153 | | - image_url: document.getElementById('item_image_url').value |
154 | | - } |
155 | | - }; |
156 | | - |
157 | | - try { |
158 | | - const response = await fetch('/api/v1/admin/shop_items', { |
159 | | - method: 'POST', |
160 | | - headers: { |
161 | | - 'Content-Type': 'application/json', |
162 | | - 'Accept': 'application/json', |
163 | | - 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.content |
164 | | - }, |
165 | | - credentials: 'same-origin', |
166 | | - body: JSON.stringify(data) |
| 139 | + addItemForm?.addEventListener('submit', async (e) => { |
| 140 | + e.preventDefault(); |
| 141 | + |
| 142 | + addItemBtn.disabled = true; |
| 143 | + addItemBtn.textContent = 'Adding...'; |
| 144 | + |
| 145 | + const data = { |
| 146 | + shop_item: { |
| 147 | + name: document.getElementById('item_name').value, |
| 148 | + description: document.getElementById('item_description').value, |
| 149 | + cost: parseFloat(document.getElementById('item_cost').value), |
| 150 | + status: document.getElementById('item_status').value, |
| 151 | + image_url: document.getElementById('item_image_url').value |
| 152 | + } |
| 153 | + }; |
| 154 | + |
| 155 | + try { |
| 156 | + const response = await fetch('/api/v1/admin/shop_items', { |
| 157 | + method: 'POST', |
| 158 | + headers: { |
| 159 | + 'Content-Type': 'application/json', |
| 160 | + 'Accept': 'application/json', |
| 161 | + 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.content |
| 162 | + }, |
| 163 | + credentials: 'same-origin', |
| 164 | + body: JSON.stringify(data) |
| 165 | + }); |
| 166 | + |
| 167 | + if (response.ok) { |
| 168 | + window.location.reload(); |
| 169 | + } else { |
| 170 | + const result = await response.json(); |
| 171 | + alert(result.errors?.join(', ') || 'Failed to create item.'); |
| 172 | + } |
| 173 | + } catch (error) { |
| 174 | + console.error('Failed to create shop item:', error); |
| 175 | + alert('Failed to create item. Please try again.'); |
| 176 | + } finally { |
| 177 | + addItemBtn.disabled = false; |
| 178 | + addItemBtn.textContent = 'Add Item'; |
| 179 | + } |
167 | 180 | }); |
168 | 181 |
|
169 | | - if (response.ok) { |
170 | | - window.location.reload(); |
171 | | - } else { |
172 | | - const result = await response.json(); |
173 | | - alert(result.errors?.join(', ') || 'Failed to create item.'); |
174 | | - } |
175 | | - } catch (error) { |
176 | | - console.error('Failed to create shop item:', error); |
177 | | - alert('Failed to create item. Please try again.'); |
178 | | - } finally { |
179 | | - addItemBtn.disabled = false; |
180 | | - addItemBtn.textContent = 'Add Item'; |
181 | | - } |
182 | | - }); |
183 | | -</script> |
| 182 | + document.querySelectorAll('.order-status').forEach(select => { |
| 183 | + select.addEventListener('change', async (e) => { |
| 184 | + const orderId = select.dataset.orderId; |
| 185 | + const newStatus = select.value; |
| 186 | + |
| 187 | + try { |
| 188 | + const response = await fetch(`/api/v1/admin/shop_orders/${orderId}`, { |
| 189 | + method: 'PATCH', |
| 190 | + headers: { |
| 191 | + 'Content-Type': 'application/json', |
| 192 | + 'Accept': 'application/json', |
| 193 | + 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')?.content |
| 194 | + }, |
| 195 | + credentials: 'same-origin', |
| 196 | + body: JSON.stringify({ order: { status: newStatus } }) |
| 197 | + }); |
| 198 | + |
| 199 | + if (!response.ok) { |
| 200 | + const result = await response.json(); |
| 201 | + alert(result.errors?.join(', ') || 'Failed to update order.'); |
| 202 | + window.location.reload(); |
| 203 | + } |
| 204 | + } catch (error) { |
| 205 | + console.error('Failed to update order status:', error); |
| 206 | + alert('Failed to update order. Please try again.'); |
| 207 | + window.location.reload(); |
| 208 | + } |
| 209 | + }); |
| 210 | + }); |
| 211 | + </script> |
0 commit comments