Files
n3wt-school/Front-End/src/components/PaymentPlanSelector.js
2025-05-12 14:03:47 +02:00

344 lines
10 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { Calendar, Eye, EyeOff, Clock, Check } from 'lucide-react';
import Table from '@/components/Table';
import DateTab from '@/components/DateTab';
import InputTextIcon from '@/components/InputTextIcon';
import Popup from '@/components/Popup';
import logger from '@/utils/logger';
const paymentPlansOptions = [
{ id: 0, name: '1 fois', frequency: 1 },
{ id: 1, name: '3 fois', frequency: 3 },
{ id: 2, name: '10 fois', frequency: 10 },
{ id: 3, name: '12 fois', frequency: 12 },
];
const PaymentPlanSelector = ({
paymentPlans,
setPaymentPlans,
handleEdit,
type,
}) => {
const [dates, setDates] = useState({});
const [selectedFrequency, setSelectedFrequency] = useState(null);
const [activeFrequencies, setActiveFrequencies] = useState([]);
const [defaultDay, setDefaultDay] = useState('-');
const [isDefaultDayModified, setIsDefaultDayModified] = useState(false);
const [popupVisible, setPopupVisible] = useState(false);
const [popupMessage, setPopupMessage] = useState('');
const [errorMsg, setErrorMsg] = useState('');
const [resetModifiedDates, setResetModifiedDates] = useState(false);
useEffect(() => {
if (paymentPlans && paymentPlans.length > 0) {
const activePlans = paymentPlans.filter((plan) => plan.is_active);
const frequencies = activePlans
.map((plan) => {
const paymentPlanOption = paymentPlansOptions.find(
(p) => p.frequency === plan.frequency
);
return paymentPlanOption ? paymentPlanOption.id : null;
})
.filter((id) => id !== null);
setActiveFrequencies(frequencies);
if (activePlans.length > 0) {
const firstDueDate = new Date(activePlans[0].due_dates[0]);
setDefaultDay(firstDueDate.getDate());
}
const initialDates = {};
paymentPlans.forEach((plan) => {
const paymentPlanOption = paymentPlansOptions.find(
(p) => p.frequency === plan.frequency
);
if (paymentPlanOption) {
initialDates[paymentPlanOption.id] = plan.due_dates;
}
});
setDates(initialDates);
}
}, [paymentPlans]);
useEffect(() => {
updateDefaultDay();
}, [dates, selectedFrequency]);
const updateDefaultDay = () => {
const currentDates = dates[selectedFrequency];
if (currentDates && currentDates.length > 0) {
const days = currentDates.map((date) => new Date(date).getDate());
const allSameDay = days.every((day) => day === days[0]);
if (allSameDay) {
setDefaultDay(days[0]);
} else {
setDefaultDay('-');
setIsDefaultDayModified(false);
}
} else {
setDefaultDay('-');
}
};
const handleActivationChange = (value) => {
const selectedPlan = paymentPlans.find(
(plan) =>
plan.frequency ===
paymentPlansOptions.find((p) => p.id === value)?.frequency
);
if (!selectedPlan) return;
const updatedData = {
...selectedPlan,
is_active: !selectedPlan.is_active,
};
handleEdit(selectedPlan.id, updatedData)
.then(() => {
setPaymentPlans((prevPlans) =>
prevPlans.map((plan) =>
plan.id === selectedPlan.id
? { ...plan, is_active: updatedData.is_active }
: plan
)
);
setActiveFrequencies((prevFrequencies) => {
if (updatedData.is_active) {
setPopupMessage(
`L'option de paiement en ${paymentPlansOptions.find((p) => p.id === value).name} a été activée.`
);
setPopupVisible(true);
return [...prevFrequencies, value];
} else {
setPopupMessage(
`L'option de paiement en ${paymentPlansOptions.find((p) => p.id === value).name} a été désactivée.`
);
setPopupVisible(true);
return prevFrequencies.filter((item) => item !== value);
}
});
})
.catch((error) => {
logger.error(error);
});
};
const handleRowClick = (row) => {
const value = row.id;
if (selectedFrequency === value) {
setSelectedFrequency(null); // Désélectionner l'onglet si la ligne est déjà sélectionnée
} else {
setSelectedFrequency(value);
if (!dates[value]) {
const frequencyValue =
paymentPlansOptions.find((plan) => plan.id === value)?.frequency || 1;
const newDates = Array(frequencyValue)
.fill('')
.map((_, index) => {
const newDate = new Date();
// Validate defaultDay
const day =
typeof defaultDay === 'number' &&
defaultDay >= 1 &&
defaultDay <= 31
? defaultDay
: 1; // Fallback to 1 if defaultDay is invalid
newDate.setDate(day);
if (value === 1) {
newDate.setMonth(newDate.getMonth() + index * 4); // Espacer de 4 mois pour le paiement en 3 fois
} else {
newDate.setMonth(newDate.getMonth() + index);
}
return newDate.toISOString().split('T')[0];
});
setDates((prevDates) => ({ ...prevDates, [value]: newDates }));
}
}
};
const handleDateChange = (planId, index, date) => {
setDates((prevDates) => {
const newDates = { ...prevDates };
newDates[planId][index] = date;
return newDates;
});
};
const handleDefaultDayChange = (e) => {
const value = e.target.value;
if (value === '') {
setDefaultDay('-');
setErrorMsg('');
setIsDefaultDayModified(false);
return;
}
const day = parseInt(value, 10);
setDefaultDay(day);
if (day < 1 || day > 31) {
setErrorMsg('Le jour doit être compris entre 1 et 31.');
setIsDefaultDayModified(false);
return;
}
setErrorMsg('');
setIsDefaultDayModified(true);
setResetModifiedDates(true);
setTimeout(() => setResetModifiedDates(false), 0);
// Mettre à jour les dates d'échéance en fonction du jour sélectionné
const updatedDates = dates[selectedFrequency].map((date) => {
const newDate = new Date(date);
newDate.setDate(day);
return newDate.toISOString().split('T')[0];
});
setDates((prevDates) => ({
...prevDates,
[selectedFrequency]: updatedDates,
}));
};
const handleSubmitDefaultDay = () => {
const selectedPlan = paymentPlans.find(
(plan) =>
plan.frequency ===
paymentPlansOptions.find((p) => p.id === selectedFrequency)?.frequency
);
if (!selectedPlan) return;
const updatedData = {
...selectedPlan,
due_dates: dates[selectedFrequency],
};
handleEdit(selectedPlan.id, updatedData)
.then(() => {
setPopupMessage(
"Mise à jour des dates d'échéances effectuée avec succès"
);
setPopupVisible(true);
setIsDefaultDayModified(false);
})
.catch((error) => {
logger.error(error);
});
};
const columns = [
{ name: 'OPTIONS', label: 'Option' },
{ name: 'ACTIONS', label: 'Action' },
];
const renderCell = (row, column) => {
switch (column) {
case 'OPTIONS':
return (
<span className="text-sm font-medium text-gray-900">{row.name}</span>
);
case 'ACTIONS':
return (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
handleActivationChange(row.id);
}}
className={
activeFrequencies.includes(row.id)
? 'text-emerald-500 hover:text-emerald-700'
: 'text-orange-500 hover:text-orange-700'
}
>
{activeFrequencies.includes(row.id) ? (
<Eye className="w-5 h-5" />
) : (
<EyeOff className="w-5 h-5" />
)}
</button>
);
default:
return null;
}
};
const selectedPaymentPlan = paymentPlans.find(
(plan) =>
plan.frequency ===
paymentPlansOptions.find((p) => p.id === selectedFrequency)?.frequency
);
return (
<div className="space-y-4">
<div className="flex items-center mb-4">
<Calendar className="w-6 h-6 text-emerald-500 mr-2" />
<h2 className="text-xl font-semibold">Paiement en plusieurs fois</h2>
</div>
<div className="grid grid-cols-2 gap-4">
<Table
data={paymentPlansOptions}
columns={columns}
renderCell={renderCell}
isSelectable={true}
onRowClick={handleRowClick}
selectedRows={selectedFrequency !== null ? [selectedFrequency] : []}
/>
{selectedFrequency !== null && selectedPaymentPlan && (
<div>
<div className="flex items-center space-x-3">
<div className="flex-grow">
<InputTextIcon
name="defaultDay"
type="number"
IconItem={Clock}
label="Jour d'échéance"
value={defaultDay}
onChange={handleDefaultDayChange}
placeholder="Jour d'échéance"
errorMsg={errorMsg}
/>
</div>
{isDefaultDayModified && defaultDay && (
<button
type="button"
onClick={handleSubmitDefaultDay}
className="text-emerald-500 hover:text-emerald-700 ml-2 cursor-pointer"
style={{ marginTop: errorMsg ? '3.5rem' : '1.75rem' }}
>
<Check className="w-5 h-5" />
</button>
)}
</div>
<DateTab
dates={dates}
activeTab={selectedFrequency}
handleDateChange={handleDateChange}
handleEdit={handleEdit}
type={type}
paymentPlanId={selectedPaymentPlan.id}
resetModifiedDates={resetModifiedDates}
/>
</div>
)}
</div>
<Popup
visible={popupVisible}
message={popupMessage}
onConfirm={() => setPopupVisible(false)}
onCancel={() => setPopupVisible(false)}
uniqueConfirmButton={true}
/>
</div>
);
};
export default PaymentPlanSelector;