feat: Ajout des frais d'inscription lors de la création d'un RF [#18]

This commit is contained in:
N3WT DE COMPET
2025-01-25 16:40:08 +01:00
parent 799e1c6717
commit ece23deb19
12 changed files with 333 additions and 136 deletions

View File

@ -0,0 +1,250 @@
import React, { useState } from 'react';
import { Plus, Trash, Edit3, Check, X, Percent, EuroIcon, Tag } from 'lucide-react';
import Table from '@/components/Table';
import InputTextIcon from '@/components/InputTextIcon';
import Popup from '@/components/Popup';
import CheckBox from '@/components/CheckBox';
const DiscountsSection = ({ discounts, setDiscounts, handleCreate, handleEdit, handleDelete, type, subscriptionMode = false, selectedDiscounts, handleDiscountSelection }) => {
const [editingDiscount, setEditingDiscount] = useState(null);
const [newDiscount, setNewDiscount] = useState(null);
const [formData, setFormData] = useState({});
const [localErrors, setLocalErrors] = useState({});
const [popupVisible, setPopupVisible] = useState(false);
const [popupMessage, setPopupMessage] = useState("");
const handleAddDiscount = () => {
setNewDiscount({ id: Date.now(), name: '', amount: '', description: '', discount_type: 0, type: type });
};
const handleRemoveDiscount = (id) => {
handleDelete(id)
.then(() => {
setDiscounts(prevDiscounts => prevDiscounts.filter(discount => discount.id !== id));
})
.catch(error => {
console.error(error);
});
};
const handleSaveNewDiscount = () => {
if (newDiscount.name && newDiscount.amount) {
handleCreate(newDiscount)
.then((createdDiscount) => {
setDiscounts([createdDiscount, ...discounts]);
setNewDiscount(null);
setLocalErrors({});
})
.catch(error => {
if (error && typeof error === 'object') {
setLocalErrors(error);
} else {
console.error(error);
}
});
} else {
setPopupMessage("Tous les champs doivent être remplis");
setPopupVisible(true);
}
};
const handleUpdateDiscount = (id, updatedDiscount) => {
if (updatedDiscount.name && updatedDiscount.amount) {
handleEdit(id, updatedDiscount)
.then(() => {
setEditingDiscount(null);
setLocalErrors({});
})
.catch(error => {
if (error && typeof error === 'object') {
setLocalErrors(error);
} else {
console.error(error);
}
});
} else {
setPopupMessage("Tous les champs doivent être remplis");
setPopupVisible(true);
}
};
const handleToggleDiscountType = (id) => {
const discount = discounts.find(discount => discount.id === id);
if (!discount) return;
const updatedData = {
...discount,
discount_type: discount.discount_type === 0 ? 1 : 0
};
handleEdit(id, updatedData)
.then(() => {
setDiscounts(prevDiscounts => prevDiscounts.map(discount => discount.id === id ? { ...discount, discount_type: updatedData.discount_type } : discount));
})
.catch(error => {
console.error(error);
});
};
const handleChange = (e) => {
const { name, value } = e.target;
if (editingDiscount) {
setFormData((prevData) => ({
...prevData,
[name]: value,
}));
} else if (newDiscount) {
setNewDiscount((prevData) => ({
...prevData,
[name]: value,
}));
}
};
const renderInputField = (field, value, onChange, placeholder) => (
<div>
<InputTextIcon
name={field}
type={field === 'amount' ? 'number' : 'text'}
value={value}
onChange={onChange}
placeholder={placeholder}
errorMsg={localErrors && localErrors[field] && Array.isArray(localErrors[field]) ? localErrors[field][0] : ''}
/>
</div>
);
const renderDiscountCell = (discount, column) => {
const isEditing = editingDiscount === discount.id;
const isCreating = newDiscount && newDiscount.id === discount.id;
const currentData = isEditing ? formData : newDiscount;
if (isEditing || isCreating) {
switch (column) {
case 'LIBELLE':
return renderInputField('name', currentData.name, handleChange, 'Libellé de la réduction');
case 'REMISE':
return renderInputField('amount', currentData.amount, handleChange,'Montant');
case 'DESCRIPTION':
return renderInputField('description', currentData.description, handleChange, 'Description');
case 'ACTIONS':
return (
<div className="flex justify-center space-x-2">
<button
type="button"
onClick={() => (isEditing ? handleUpdateDiscount(editingDiscount, formData) : handleSaveNewDiscount())}
className="text-green-500 hover:text-green-700"
>
<Check className="w-5 h-5" />
</button>
<button
type="button"
onClick={() => (isEditing ? setEditingDiscount(null) : setNewDiscount(null))}
className="text-red-500 hover:text-red-700"
>
<X className="w-5 h-5" />
</button>
</div>
);
default:
return null;
}
} else {
switch (column) {
case 'LIBELLE':
return discount.name;
case 'REMISE':
return discount.discount_type === 0 ? `${discount.amount}` : `${discount.amount} %`;
case 'DESCRIPTION':
return discount.description;
case 'MISE A JOUR':
return discount.updated_at_formatted;
case 'ACTIONS':
return (
<div className="flex justify-center space-x-2">
<button
type="button"
onClick={() => handleToggleDiscountType(discount.id)}
className="flex justify-center items-center text-emerald-500 hover:text-emerald-700"
>
{discount.discount_type === 0 ? <EuroIcon className="w-5 h-5" /> : <Percent className="w-5 h-5" />}
</button>
<button
type="button"
onClick={() => setEditingDiscount(discount.id) || setFormData(discount)}
className="text-blue-500 hover:text-blue-700"
>
<Edit3 className="w-5 h-5" />
</button>
<button
type="button"
onClick={() => handleRemoveDiscount(discount.id)}
className="text-red-500 hover:text-red-700"
>
<Trash className="w-5 h-5" />
</button>
</div>
);
case '':
return (
<div className="flex justify-center">
<CheckBox
item={discount}
formData={{ selectedDiscounts }}
handleChange={() => handleDiscountSelection(discount.id)}
fieldName="selectedDiscounts"
/>
</div>
);
default:
return null;
}
}
};
const columns = subscriptionMode
? [
{ name: 'LIBELLE', label: 'Libellé' },
{ name: 'DESCRIPTION', label: 'Description' },
{ name: 'REMISE', label: 'Remise' },
{ name: '', label: 'Sélection' }
]
: [
{ name: 'LIBELLE', label: 'Libellé' },
{ name: 'REMISE', label: 'Remise' },
{ name: 'DESCRIPTION', label: 'Description' },
{ name: 'MISE A JOUR', label: 'Date mise à jour' },
{ name: 'ACTIONS', label: 'Actions' }
];
return (
<div className="space-y-4">
{!subscriptionMode && (
<div className="flex justify-between items-center">
<div className="flex items-center mb-4">
<Tag className="w-6 h-6 text-emerald-500 mr-2" />
<h2 className="text-xl font-semibold">Réductions {type === 0 ? 'd\'inscription' : 'de scolarité'}</h2>
</div>
<button type="button" onClick={handleAddDiscount} className="text-emerald-500 hover:text-emerald-700">
<Plus className="w-5 h-5" />
</button>
</div>
)}
<Table
data={newDiscount ? [newDiscount, ...discounts] : discounts}
columns={columns}
renderCell={renderDiscountCell}
defaultTheme='bg-yellow-100'
/>
<Popup
visible={popupVisible}
message={popupMessage}
onConfirm={() => setPopupVisible(false)}
onCancel={() => setPopupVisible(false)}
uniqueConfirmButton={true}
/>
</div>
);
};
export default DiscountsSection;