added warehouses, and moved home to products
This commit is contained in:
parent
a67aa0b54e
commit
9c154eff3e
14
src/App.vue
14
src/App.vue
@ -16,8 +16,18 @@
|
|||||||
if(isAuth.value){
|
if(isAuth.value){
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: 'Accueil',
|
label: 'Tableau de Bord',
|
||||||
command:() => router.push({name:'home'}),
|
command:() => router.push({name:'dashboard'}),
|
||||||
|
icon: 'pi pi-home',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Gerer les produits',
|
||||||
|
command:() => router.push({name:'products'}),
|
||||||
|
icon: 'pi pi-home',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Gerer les entrepôts',
|
||||||
|
command:() => router.push({name:'warehouses'}),
|
||||||
icon: 'pi pi-home',
|
icon: 'pi pi-home',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
34
src/api.js
34
src/api.js
@ -67,6 +67,40 @@ export const modifyProduct = async (productData, id) => {
|
|||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteProduct = async (id) => {
|
||||||
|
const response = await api.delete(`/products/${id}/`, {
|
||||||
|
headers: {Authorization: `Bearer ${sessionStorage.getItem('access_token')}`},
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getWarehouses = async () => {
|
||||||
|
const response = await api.get('/warehouses/', {
|
||||||
|
headers: {Authorization: `Bearer ${sessionStorage.getItem('access_token')}`},
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createWarehouse = async (warehouseData) => {
|
||||||
|
const response = await api.post('/warehouses/', warehouseData, {
|
||||||
|
headers: {Authorization: `Bearer ${sessionStorage.getItem('access_token')}`},
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const modifyWarehouse = async (warehouseData, id) => {
|
||||||
|
const response = await api.patch(`/warehouses/${id}/`, warehouseData, {
|
||||||
|
headers: {Authorization: `Bearer ${sessionStorage.getItem('access_token')}`},
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteWarehouse = async (id) => {
|
||||||
|
const response = await api.delete(`/warehouses/${id}/`, {
|
||||||
|
headers: {Authorization: `Bearer ${sessionStorage.getItem('access_token')}`},
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
const refreshAccessToken = async () => {
|
const refreshAccessToken = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await api.post('/token/refresh', {'refresh': Cookies.get('refresh')}, {
|
const response = await api.post('/token/refresh', {'refresh': Cookies.get('refresh')}, {
|
||||||
|
@ -1,12 +1,30 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router';
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
import HomeView from '../views/Home.vue';
|
import ProductsView from '../views/Products.vue';
|
||||||
import SwaggerView from '../views/Swagger.vue';
|
import SwaggerView from '../views/Swagger.vue';
|
||||||
import LoginView from '../views/Login.vue';
|
import LoginView from '../views/Login.vue';
|
||||||
|
import DashboardView from '../views/Dashboard.vue';
|
||||||
|
import WarehousesView from '../views/Warehouses.vue';
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
name: 'dashboard',
|
||||||
component: HomeView,
|
component: DashboardView,
|
||||||
|
meta: {
|
||||||
|
requireAuth: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/products',
|
||||||
|
name: 'products',
|
||||||
|
component: ProductsView,
|
||||||
|
meta: {
|
||||||
|
requireAuth: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/warehouses',
|
||||||
|
name: 'warehouses',
|
||||||
|
component: WarehousesView,
|
||||||
meta: {
|
meta: {
|
||||||
requireAuth: true,
|
requireAuth: true,
|
||||||
},
|
},
|
||||||
|
6
src/views/Dashboard.vue
Normal file
6
src/views/Dashboard.vue
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<script setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<p>Dashboard</p>
|
||||||
|
</template>
|
@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { createProduct,getProducts,modifyProduct } from '../api.js';
|
import { createProduct,getProducts,modifyProduct,deleteProduct } from '../api.js';
|
||||||
import { useToast } from 'primevue/usetoast';
|
import { useToast } from 'primevue/usetoast';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import InputText from 'primevue/inputtext';
|
import InputText from 'primevue/inputtext';
|
||||||
@ -77,7 +77,6 @@ async function onRowEditSave(event) {
|
|||||||
let {newData, index} = event;
|
let {newData, index} = event;
|
||||||
products.value[index] = newData;
|
products.value[index] = newData;
|
||||||
|
|
||||||
console.log(newData);
|
|
||||||
if (!newData.id) {
|
if (!newData.id) {
|
||||||
console.error("No id found in edited row.");
|
console.error("No id found in edited row.");
|
||||||
toast.add({ severity: 'error', life: 2500, summary: 'Error', detail: 'Aucune donnée n\'a été modifiée.' });
|
toast.add({ severity: 'error', life: 2500, summary: 'Error', detail: 'Aucune donnée n\'a été modifiée.' });
|
||||||
@ -108,6 +107,24 @@ async function onRowEditSave(event) {
|
|||||||
toast.add({ severity: 'error', life: 2500, summary: 'Error', detail: 'Aucune donnée n\'a été modifiée.' });
|
toast.add({ severity: 'error', life: 2500, summary: 'Error', detail: 'Aucune donnée n\'a été modifiée.' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeProduct(id) {
|
||||||
|
try {
|
||||||
|
await deleteProduct(id);
|
||||||
|
products.value = await getProducts();
|
||||||
|
toast.add({ severity: 'success', life: 2500, summary: 'Succès', detail: 'Produit supprimé.' });
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
const data = error.response.data;
|
||||||
|
if (data.detail) {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: data.detail });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: 'Une erreur est survenue.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const stockSeverity = (data) => {
|
const stockSeverity = (data) => {
|
||||||
if (!data) return 'info';
|
if (!data) return 'info';
|
||||||
|
|
||||||
@ -337,12 +354,20 @@ try {
|
|||||||
<InputNumber v-model="slotProps.data.quantity" fluid />
|
<InputNumber v-model="slotProps.data.quantity" fluid />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
|
<Column editor="true">
|
||||||
|
<template #editor="slotProps">
|
||||||
|
<Button
|
||||||
|
icon="pi pi-times"
|
||||||
|
class="p-button-rounded p-button-danger"
|
||||||
|
@click="removeProduct(slotProps.data.id)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
<Column
|
<Column
|
||||||
:rowEditor="true"
|
:rowEditor="true"
|
||||||
style="width: 10%; min-width: 8rem"
|
style="width: 10%; min-width: 8rem"
|
||||||
bodyStyle="text-align:center"
|
bodyStyle="text-align:center"
|
||||||
></Column>
|
/>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
179
src/views/Warehouses.vue
Normal file
179
src/views/Warehouses.vue
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { createWarehouse, getWarehouses, modifyWarehouse, deleteWarehouse } from '../api.js';
|
||||||
|
import { useToast } from 'primevue/usetoast';
|
||||||
|
import InputText from 'primevue/inputtext';
|
||||||
|
import Button from 'primevue/button';
|
||||||
|
import PMessage from 'primevue/message';
|
||||||
|
import InputNumber from 'primevue/inputnumber';
|
||||||
|
import InputGroup from 'primevue/inputgroup';
|
||||||
|
import InputGroupAddon from 'primevue/inputgroupaddon';
|
||||||
|
import DataTable from 'primevue/datatable';
|
||||||
|
import Column from 'primevue/column';
|
||||||
|
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const warehouses = ref([]);
|
||||||
|
const warehouseName = ref('');
|
||||||
|
const warehouseLocation = ref('');
|
||||||
|
const warehouseMaxCapacity = ref(0);
|
||||||
|
|
||||||
|
const registerErrors = ref({ name: '', location: '', max_capacity: '', products: '' });
|
||||||
|
const editingRows = ref([]);
|
||||||
|
|
||||||
|
async function create_warehouse() {
|
||||||
|
registerErrors.value = { name: '', location: '', max_capacity: '', products: '' };
|
||||||
|
try {
|
||||||
|
await createWarehouse({
|
||||||
|
name: warehouseName.value,
|
||||||
|
location: warehouseLocation.value,
|
||||||
|
max_capacity: warehouseMaxCapacity.value,
|
||||||
|
});
|
||||||
|
warehouses.value = await getWarehouses();
|
||||||
|
toast.add({ severity: 'success', life: 2500, summary: 'Succès', detail: 'Entrepôt créé' });
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
const data = error.response.data;
|
||||||
|
if (data.detail) {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: data.detail });
|
||||||
|
}
|
||||||
|
if (data.name) {
|
||||||
|
registerErrors.value.name = data.name[0];
|
||||||
|
}
|
||||||
|
if (data.location) {
|
||||||
|
registerErrors.value.location = data.location[0];
|
||||||
|
}
|
||||||
|
if (data.max_capacity) {
|
||||||
|
registerErrors.value.max_capacity = data.max_capacity[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: 'Une erreur est survenue.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onRowEditSave(event) {
|
||||||
|
if (event && event.data) {
|
||||||
|
let { newData, index } = event;
|
||||||
|
warehouses.value[index] = newData;
|
||||||
|
if (!newData.id) {
|
||||||
|
console.error("No id found in edited row.");
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Error', detail: 'Aucune donnée n\'a été modifiée.' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await modifyWarehouse({
|
||||||
|
id: newData.id,
|
||||||
|
name: newData.name,
|
||||||
|
location: newData.location,
|
||||||
|
max_capacity: newData.max_capacity,
|
||||||
|
},newData.id);
|
||||||
|
warehouses.value = await getWarehouses();
|
||||||
|
toast.add({ severity: 'success', life: 2500, summary: 'Succès', detail: 'Entrepôt modifié' });
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
const data = error.response.data;
|
||||||
|
if (data.detail) {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: data.detail });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: 'Une erreur est survenue.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeWarehouse(id) {
|
||||||
|
try {
|
||||||
|
await deleteWarehouse(id);
|
||||||
|
warehouses.value = await getWarehouses();
|
||||||
|
toast.add({ severity: 'success', life: 2500, summary: 'Succès', detail: 'Entrepôt supprimé' });
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
const data = error.response.data;
|
||||||
|
if (data.detail) {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: data.detail });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: 'Une erreur est survenue.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
warehouses.value = await getWarehouses();
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
const data = error.response.data;
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: data.detail });
|
||||||
|
} else {
|
||||||
|
toast.add({ severity: 'error', life: 2500, summary: 'Erreur', detail: 'Une erreur est survenue.' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h2>Gérer les entrepôts</h2>
|
||||||
|
<div class="register form-container">
|
||||||
|
<h2>Créer un entrepôt</h2>
|
||||||
|
<form @submit.prevent="create_warehouse">
|
||||||
|
<div class="form">
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroupAddon>Nom :</InputGroupAddon>
|
||||||
|
<InputText type="text" id="register-warehouse" v-model="warehouseName" required />
|
||||||
|
</InputGroup>
|
||||||
|
<p-message v-if="registerErrors.name" severity="error">{{ registerErrors.name }}</p-message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroupAddon>Location :</InputGroupAddon>
|
||||||
|
<InputText type="text" id="register-location" v-model="warehouseLocation" required />
|
||||||
|
</InputGroup>
|
||||||
|
<p-message v-if="registerErrors.location" severity="error">{{ registerErrors.location }}</p-message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroupAddon>Capacité maximale :</InputGroupAddon>
|
||||||
|
<InputNumber id="register-max-capacity" v-model="warehouseMaxCapacity" required />
|
||||||
|
</InputGroup>
|
||||||
|
<p-message v-if="registerErrors.max_capacity" severity="error">{{ registerErrors.max_capacity }}</p-message>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button label="Créer" type="submit" class="p-button-primary" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DataTable v-model:editingRows="editingRows" editMode="row" dataKey="id" @row-edit-save="onRowEditSave" :value="warehouses" tableStyle="min-width: 50rem" removableSort>
|
||||||
|
|
||||||
|
<Column field="name" header="Nom" editor="true" sortable>
|
||||||
|
<template #editor="slotProps">
|
||||||
|
<InputText v-model="slotProps.data.name" fluid />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
|
||||||
|
<Column field="location" header="Location" editor="true">
|
||||||
|
<template #editor="slotProps">
|
||||||
|
<InputText v-model="slotProps.data.location" fluid />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
|
||||||
|
<Column field="max_capacity" header="Capacité maximale" editor="true" sortable>
|
||||||
|
<template #editor="slotProps">
|
||||||
|
<InputNumber v-model="slotProps.data.max_capacity" fluid />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
|
||||||
|
<Column editor="true">
|
||||||
|
<template #editor="slotProps">
|
||||||
|
<Button icon="pi pi-times" class="p-button-rounded p-button-danger" @click="removeWarehouse(slotProps.data.id)" />
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
<Column :rowEditor="true" />
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
Loading…
x
Reference in New Issue
Block a user