Various fixes and improvements

This commit is contained in:
Léo 2025-02-06 18:17:16 +01:00
parent 8cc15870d8
commit 9c54bd1025
3 changed files with 132 additions and 34 deletions

View File

@ -31,6 +31,4 @@ h1 {
#app {
max-width: 1600px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

View File

@ -4,15 +4,25 @@ import Chart from 'primevue/chart';
import Fieldset from 'primevue/fieldset';
import MeterGroup from 'primevue/metergroup';
import Carousel from 'primevue/carousel';
import { getProducts,getWarehouses } from '../api.js';
import { getProducts,getWarehouses, modifyProduct } from '../api.js';
import Tag from 'primevue/tag';
import AutoComplete from 'primevue/autocomplete';
import InputNumber from 'primevue/inputnumber';
import IftaLabel from 'primevue/iftalabel';
import Button from 'primevue/button'
const products = ref();
const warehouses = ref();
const selectedRef = ref()
const filteredRef = ref();
const newValue = ref();
const chartProductsData = ref();
const chartWarehousesData = ref();
const chartOptions = {plugins:{legend:{labels:{usePointStyle:true,}}}};
const productColors = {};
const warehouseColors ={};
const colorsSchemes = [
"#40407a", "#706fd3", "#f7f1e3", "#34ace0",
"#33d9b2", "#2c2c54", "#474787", "#aaa69d",
@ -38,6 +48,13 @@ const getColorForProduct = (productName) => {
}
return productColors[productName];
};
const getColorForWarehouse = (warehouseName) => {
if (!warehouseColors[warehouseName]) {
warehouseColors[warehouseName] = colorsSchemes[Object.keys(warehouseColors).length % colorsSchemes.length];
}
return warehouseColors[warehouseName];
};
const setChartProductsData = () => {
@ -61,8 +78,8 @@ const setChartWarehousesData = () =>{
datasets: [
{
label: 'Capacité',
backgroundColor: products.value.map(product => `${getColorForProduct(product.name)}80`),
borderColor : products.value.map(product => getColorForProduct(product.name)),
backgroundColor: warehouses.value.map(warehouse => `${getColorForWarehouse(warehouse.name)}80`),
borderColor : warehouses.value.map(warehouse => getColorForWarehouse(warehouse.name)),
data: warehouses.value.map(warehouse => warehouse.max_capacity),
borderWidth: 1
}
@ -70,15 +87,45 @@ const setChartWarehousesData = () =>{
}
};
const search = (event) => {
filteredRef.value = products.value.filter(product =>
product.reference.toLowerCase().includes(event.query.toLowerCase())
);
}
onMounted(async () => {
warehouses.value = await getWarehouses();
products.value = await getProducts();
chartProductsData.value = setChartProductsData();
chartWarehousesData.value = setChartWarehousesData();
})
const productValueModifier = async () => {
if (!selectedRef.value || !newValue.value) return;
const product = products.value.find(p => p.reference === selectedRef.value.reference);
if (product) {
const newQuantity = product.quantity + newValue.value
try{
await modifyProduct({
quantity: newQuantity,
warehouses: product.warehouses
}, product.id);
warehouses.value = await getWarehouses();
products.value = await getProducts();
chartProductsData.value = setChartProductsData();
chartWarehousesData.value = setChartWarehousesData();
} catch (error){
console.error(error)
}
} else {
console.error("no product found")
}
};
</script>
<template>
<Fieldset legend="Produits stockés" style="max-width: 600px; margin: auto; padding:20px" toggleable>
<Chart type="pie" :data="chartProductsData" :options="chartOptions"></Chart>
</Fieldset>
@ -94,6 +141,20 @@ onMounted(async () => {
</ul>
</Fieldset>
<Fieldset legend="Products" style="max-width: 600px; margin: auto; padding:20px" toggleable>
<form @submit.prevent="productValueModifier">
<IftaLabel>
<AutoComplete inputId="reference" name="reference" optionLabel="reference" variant="filled" :suggestions="filteredRef" v-model="selectedRef" @complete="search"></AutoComplete>
<label for="reference">Reference</label>
</IftaLabel>
<IftaLabel>
<InputNumber inputId="number-value" showButtons v-model="newValue" mode="decimal"></InputNumber>
<label for="number-value">Ajouter/Soustraire</label>
</IftaLabel>
<Button
label="update"
type="submit"
class="p-button-primary"> </Button>
</form>
<Carousel :value="products"
:numVisible="3"
:numScroll="1"
@ -106,6 +167,7 @@ onMounted(async () => {
<Tag severity="info" value="STOCK OK" rounded> </Tag>
</span>
<p>{{ slotProps.data.name }}</p>
<p>{{ slotProps.data.reference }}</p>
<p>{{ slotProps.data.quantity }}</p>
<img :src="slotProps.data.image" alt="" style="border-radius: 8px; width: 150px;">
</template>

View File

@ -29,7 +29,8 @@ const productDescription = ref('');
const productQuantity = ref(0);
const productAlert = ref(false);
const productStockLimit = ref(null);
const base64Image = ref(null);
const b64Img = ref(null);
const b64Modif = ref(null);
const selectedWarehouses = ref([]);
const registerErrors = ref({});
@ -51,7 +52,7 @@ async function create_product() {
quantity: productQuantity.value,
alert_enabled: productAlert.value,
stock_limit: productStockLimit.value,
image: base64Image.value,
image: b64Img.value,
warehouses: selectedWarehouses.value.map((warehouse) => warehouse.id),
});
warehouses.value = await getWarehouses();
@ -88,10 +89,19 @@ function resetForms() {
productQuantity.value = 0;
productAlert.value = false;
productStockLimit.value = null;
base64Image.value = null;
b64Img.value = null;
b64Modif.value = null;
selectedWarehouses.value = [];
};
function resetImg(modifImg = false){
if (modifImg){
b64Modif.value = null;
return
}
b64Img.value = null;
};
async function onRowEditSave(event) {
if (event && event.data) {
let {newData, index} = event;
@ -103,17 +113,30 @@ async function onRowEditSave(event) {
return;
}
modifyErrors.value[newData.id] = {};
let tableDatas = {}
console.log(b64Modif)
try {
await modifyProduct({
if (b64Modif.value){
tableDatas = {
id: newData.id,
name: newData.name,
reference: newData.reference,
description: newData.description,
quantity: newData.quantity,
image: base64Image.value,
image: b64Modif.value,
warehouses: newData.warehouse.map((warehouse) => warehouse.id),
},
newData.id);
}
} else {
tableDatas = {
id: newData.id,
name: newData.name,
reference: newData.reference,
description: newData.description,
quantity: newData.quantity,
warehouses: newData.warehouse.map((warehouse) => warehouse.id),
}
}
await modifyProduct(tableDatas,newData.id);
warehouses.value = await getWarehouses();
products.value = await getProducts();
products.value = enrichProducts();
@ -199,12 +222,16 @@ const truncate = (text, length) => {
}
return text;
};
const handleFileUpload = (event) => {
const handleFileUpload = (event, iscreated) => {
const file = event.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = () => {
base64Image.value = reader.result;
if (iscreated){
b64Img.value = reader.result;
} else {
b64Modif.value = reader.result;
}
toast.add({ severity: 'success', life: 2500, summary: 'Image ajouté avec succès.' });
};
reader.onerror = () => {
@ -328,6 +355,10 @@ try {
<div class="form">
<InputGroup >
<InputGroupAddon>Image :</InputGroupAddon>
<InputGroupAddon v-if="b64Img">
<img :src="b64Img" alt="Image" style="width: 6rem">
<Button icon="pi pi-times" severity="secondary" @click="resetForms()"/>
</InputGroupAddon>
<FileUpload
name="productImage"
accept="image/*"
@ -337,7 +368,7 @@ try {
:multiple="false"
:maxFileSize="1000000"
:chooseLabel="'Choisir une image'"
@uploader="handleFileUpload"
@uploader="handleFileUpload($event,true)"
/>
</InputGroup>
</div>
@ -423,7 +454,7 @@ try {
style="width: 6rem"
/>
</template>
<template #editor>
<template #editor="slotProps">
<FileUpload
name="editProductImage"
accept="image/*"
@ -433,9 +464,16 @@ try {
:multiple="false"
:maxFileSize="1000000"
:chooseLabel='"modifier image"'
@uploader="handleFileUpload"
@uploader="handleFileUpload($event,false)"
>
</FileUpload>
<div v-if="b64Modif">
<img :src="b64Modif" alt="Image" style="width: 6rem">
<Button icon="pi pi-times" severity="secondary" @click="resetImg(true)"/>
</div>
<div v-else>
<img :src="slotProps.data.image" alt="Image" style="width: 6rem;">
</div>
</template>
</Column>