Files
thetool/public/mobile/modules/lager/inventur/StocktakeList.js
2026-01-17 12:48:08 +00:00

137 lines
6.5 KiB
JavaScript

import { createModuleApi } from '/mobile/shared/api.js';
const inventurApi = createModuleApi('Lager/Inventur');
export default {
name: 'StocktakeList',
emits: ['select'],
props: {
user: Object
},
setup(props, { emit }) {
const { ref, onMounted } = Vue;
const stocktakes = ref([]);
const isLoading = ref(true);
const error = ref('');
const fetchStocktakes = async () => {
isLoading.value = true;
error.value = '';
try {
const result = await inventurApi.get('getActiveStocktakes');
if (result.success) {
stocktakes.value = result.stocktakes;
} else {
error.value = result.error || 'Fehler beim Laden';
}
} catch (e) {
error.value = 'Netzwerkfehler';
} finally {
isLoading.value = false;
}
};
const selectStocktake = (stocktake) => {
emit('select', stocktake);
};
onMounted(() => {
fetchStocktakes();
});
return {
stocktakes,
isLoading,
error,
fetchStocktakes,
selectStocktake
};
},
template: `
<div class="h-full flex flex-col">
<!-- Refresh bar -->
<div class="flex items-center justify-between px-3 py-2 bg-white dark:bg-slate-800 border-b border-slate-200 dark:border-slate-700">
<span class="text-sm font-medium text-slate-600 dark:text-slate-300">Aktive Inventuren</span>
<button
@click="fetchStocktakes"
class="p-2 rounded-full text-slate-500 hover:bg-slate-100 dark:hover:bg-slate-700 transition"
:disabled="isLoading"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" :class="{ 'animate-spin': isLoading }" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
</button>
</div>
<!-- Content -->
<div class="flex-1 overflow-y-auto p-3">
<!-- Loading -->
<div v-if="isLoading" class="space-y-3">
<div v-for="i in 3" :key="i" class="bg-white dark:bg-slate-800 p-4 rounded-xl shadow-sm animate-pulse">
<div class="h-5 bg-slate-200 dark:bg-slate-700 rounded w-3/4 mb-2"></div>
<div class="h-4 bg-slate-200 dark:bg-slate-700 rounded w-1/2 mb-3"></div>
<div class="h-3 bg-slate-200 dark:bg-slate-700 rounded w-1/3"></div>
</div>
</div>
<!-- Error -->
<div v-else-if="error" class="text-center py-8">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto text-red-400 mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<p class="text-slate-500 dark:text-slate-400 mb-4">{{ error }}</p>
<button @click="fetchStocktakes" class="px-4 py-2 bg-primary text-white rounded-lg font-medium">
Erneut versuchen
</button>
</div>
<!-- Empty -->
<div v-else-if="stocktakes.length === 0" class="text-center py-8">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12 mx-auto text-slate-300 dark:text-slate-600 mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
<p class="text-slate-500 dark:text-slate-400">Keine aktiven Inventuren</p>
</div>
<!-- Stocktake List -->
<div v-else class="bg-white dark:bg-slate-800 rounded-xl overflow-hidden shadow-sm">
<button
v-for="(stocktake, index) in stocktakes"
:key="stocktake.id"
@click="selectStocktake(stocktake)"
:class="[
'w-full text-left px-4 py-3 hover:bg-slate-50 dark:hover:bg-slate-700/50 active:bg-slate-100 dark:active:bg-slate-700 transition',
index !== stocktakes.length - 1 ? 'border-b border-slate-100 dark:border-slate-700' : ''
]"
>
<div class="flex justify-between items-start">
<div class="flex-1 min-w-0">
<h3 class="font-medium text-slate-800 dark:text-white truncate">
{{ stocktake.title || 'Inventur #' + stocktake.stocktakeNumber }}
</h3>
<p class="text-sm text-slate-500 dark:text-slate-400 mt-0.5">
{{ stocktake.locationName }}
</p>
</div>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-slate-400 flex-shrink-0 ml-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
<div class="flex items-center mt-2 text-xs text-slate-400 dark:text-slate-500">
<span class="font-medium text-slate-600 dark:text-slate-400">{{ stocktake.totalScannedItems || 0 }}</span>
<span class="ml-1">Artikel</span>
<span class="mx-2">·</span>
<span>{{ stocktake.startedAt || 'Nicht gestartet' }}</span>
</div>
</button>
</div>
</div>
</div>
`
};