Enhance SaleSection component to manage selling state with improved user feedback. Disable buttons during selling, show status messages for sellAll actions, and update translations for new statuses.

This commit is contained in:
Torsten Schulz (local)
2025-12-20 15:35:20 +01:00
parent fcbb903839
commit a8a136a9ce
4 changed files with 908 additions and 16 deletions

View File

@@ -20,8 +20,10 @@
<td>{{ item.quality }}</td>
<td>{{ item.totalQuantity }}</td>
<td>
<input type="number" v-model.number="item.sellQuantity" :min="1" :max="item.totalQuantity" />
<button @click="sellItem(index)">{{ $t('falukant.branch.sale.sellButton') }}</button>
<input type="number" v-model.number="item.sellQuantity" :min="1" :max="item.totalQuantity" :disabled="sellingItemIndex === index" />
<button @click="sellItem(index)" :disabled="sellingItemIndex === index || sellingAll">
{{ sellingItemIndex === index ? $t('falukant.branch.sale.selling') : $t('falukant.branch.sale.sellButton') }}
</button>
</td>
<td>
<div v-if="item.betterPrices && item.betterPrices.length > 0" class="price-cities">
@@ -36,7 +38,12 @@
</tr>
</tbody>
</table>
<button @click="sellAll">{{ $t('falukant.branch.sale.sellAllButton') }}</button>
<button @click="sellAll" :disabled="sellingAll || sellingItemIndex !== null">
{{ sellingAll ? $t('falukant.branch.sale.selling') : $t('falukant.branch.sale.sellAllButton') }}
</button>
<div v-if="sellAllStatus" class="sell-all-status" :class="sellAllStatus.type">
{{ sellAllStatus.message }}
</div>
</div>
<div v-else>
<p>{{ $t('falukant.branch.sale.noInventory') }}</p>
@@ -183,6 +190,9 @@
data() {
return {
inventory: [],
sellingItemIndex: null,
sellingAll: false,
sellAllStatus: null,
transportForm: {
sourceKey: null,
vehicleTypeId: null,
@@ -320,23 +330,55 @@
maximumFractionDigits: 2,
}).format(price);
},
sellItem(index) {
async sellItem(index) {
if (this.sellingItemIndex !== null || this.sellingAll) return;
const item = this.inventory[index];
const quantityToSell = item.sellQuantity || item.totalQuantity;
apiClient.post(`/api/falukant/sell`, {
branchId: this.branchId,
productId: item.product.id,
quantity: quantityToSell,
quality: item.quality,
}).catch(() => {
this.sellingItemIndex = index;
try {
await apiClient.post(`/api/falukant/sell`, {
branchId: this.branchId,
productId: item.product.id,
quantity: quantityToSell,
quality: item.quality,
});
// Inventory neu laden nach erfolgreichem Verkauf
await this.loadInventory();
} catch (error) {
alert(this.$t('falukant.branch.sale.sellError'));
});
} finally {
this.sellingItemIndex = null;
}
},
sellAll() {
apiClient.post(`/api/falukant/sell/all`, { branchId: this.branchId })
.catch(() => {
alert(this.$t('falukant.branch.sale.sellAllError'));
});
async sellAll() {
if (this.sellingAll || this.sellingItemIndex !== null) return;
this.sellingAll = true;
this.sellAllStatus = null;
try {
const response = await apiClient.post(`/api/falukant/sell/all`, { branchId: this.branchId });
const revenue = response.data?.revenue || 0;
this.sellAllStatus = {
type: 'success',
message: this.$t('falukant.branch.sale.sellAllSuccess', { revenue: this.formatMoney(revenue) })
};
// Inventory neu laden nach erfolgreichem Verkauf
await this.loadInventory();
} catch (error) {
this.sellAllStatus = {
type: 'error',
message: this.$t('falukant.branch.sale.sellAllError')
};
} finally {
this.sellingAll = false;
// Status nach 5 Sekunden löschen
setTimeout(() => {
this.sellAllStatus = null;
}, 5000);
}
},
inventoryOptions() {
return this.inventory.map((item, index) => ({
@@ -590,5 +632,20 @@
color: #999;
font-style: italic;
}
.sell-all-status {
margin-top: 10px;
padding: 8px;
border-radius: 4px;
}
.sell-all-status.success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.sell-all-status.error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
</style>

View File

@@ -260,6 +260,10 @@
"sell": "Verkauf",
"sellButton": "Verkaufen",
"sellAllButton": "Alles verkaufen",
"selling": "Verkauf läuft...",
"sellError": "Fehler beim Verkauf des Produkts.",
"sellAllError": "Fehler beim Verkauf aller Produkte.",
"sellAllSuccess": "Alle Produkte wurden erfolgreich verkauft. Einnahmen: {revenue}"
"transportTitle": "Transport anlegen",
"transportSource": "Artikel",
"transportSourcePlaceholder": "Artikel wählen",