Skip to content

Commit 3ef1216

Browse files
author
Clément VALENTIN
committed
feat(simulator): ajouter la prise en charge de l'offre ZEN_FLEX et améliorer les informations de simulation
1 parent aafa3b8 commit 3ef1216

File tree

2 files changed

+172
-1
lines changed

2 files changed

+172
-1
lines changed

apps/web/src/pages/Contribute.tsx

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export default function Contribute() {
102102
'HC_WEEKEND': 'HC/HP + Weekend',
103103
'HC_NUIT_WEEKEND': 'HC Nuit + Weekend',
104104
'SEASONAL': 'Saisonnier',
105+
'ZEN_FLEX': 'Zen Flex',
105106
}
106107
return labels[type] || type
107108
}
@@ -519,9 +520,15 @@ export default function Contribute() {
519520
} else if (offerType === 'EJP') {
520521
pricingData.ejp_normal = ejpNormal ? parseFloat(ejpNormal) : undefined
521522
pricingData.ejp_peak = ejpPeak ? parseFloat(ejpPeak) : undefined
523+
} else if (offerType === 'ZEN_FLEX') {
524+
// ZEN_FLEX: Eco days use winter prices, Sobriété days use summer prices
525+
pricingData.hc_price_winter = hcPriceWinter ? parseFloat(hcPriceWinter) : undefined
526+
pricingData.hp_price_winter = hpPriceWinter ? parseFloat(hpPriceWinter) : undefined
527+
pricingData.hc_price_summer = hcPriceSummer ? parseFloat(hcPriceSummer) : undefined
528+
pricingData.hp_price_summer = hpPriceSummer ? parseFloat(hpPriceSummer) : undefined
522529
}
523530

524-
// Add seasonal pricing if provided
531+
// Add seasonal pricing if provided (for non-ZEN_FLEX/SEASONAL types)
525532
if (hcPriceWinter) pricingData.hc_price_winter = parseFloat(hcPriceWinter)
526533
if (hpPriceWinter) pricingData.hp_price_winter = parseFloat(hpPriceWinter)
527534
if (hcPriceSummer) pricingData.hc_price_summer = parseFloat(hcPriceSummer)
@@ -1124,6 +1131,7 @@ RÈGLES IMPORTANTES :
11241131
<option value="HC_NUIT_WEEKEND">HC Nuit & Week-end (23h-6h + week-end)</option>
11251132
<option value="HC_WEEKEND">HC Week-end (HC PDL + week-end)</option>
11261133
<option value="SEASONAL">SEASONAL (Tarifs saisonniers hiver/été)</option>
1134+
<option value="ZEN_FLEX">ZEN FLEX (Éco + Sobriété)</option>
11271135
<option value="TEMPO">TEMPO</option>
11281136
<option value="EJP">EJP</option>
11291137
</select>
@@ -1451,6 +1459,89 @@ RÈGLES IMPORTANTES :
14511459
</div>
14521460
)}
14531461

1462+
{/* ZEN_FLEX */}
1463+
{offerType === 'ZEN_FLEX' && (
1464+
<div className="space-y-4">
1465+
<div className="p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
1466+
<p className="text-sm text-blue-800 dark:text-blue-200">
1467+
💡 <strong>Zen Flex</strong> : Jours Éco (345j/an) avec tarifs réduits + Jours Sobriété (20j/an) avec tarifs majorés. HC de 22h à 6h.
1468+
</p>
1469+
</div>
1470+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
1471+
<div className="space-y-4">
1472+
<h4 className="font-semibold text-green-700 dark:text-green-300 flex items-center gap-2">
1473+
<span className="w-3 h-3 rounded-full bg-green-500"></span> Jours Éco (345j/an)
1474+
</h4>
1475+
<div>
1476+
<label className="block text-sm font-medium mb-2">
1477+
HC Éco (€/kWh TTC) <span className="text-red-500">*</span>
1478+
</label>
1479+
<input
1480+
type="number"
1481+
step="0.00001"
1482+
value={hcPriceWinter}
1483+
onChange={(e) => setHcPriceWinter(e.target.value)}
1484+
className="input"
1485+
required
1486+
placeholder="0.1546"
1487+
/>
1488+
<p className="text-xs text-gray-500 mt-1">22h-6h les jours Éco</p>
1489+
</div>
1490+
<div>
1491+
<label className="block text-sm font-medium mb-2">
1492+
HP Éco (€/kWh TTC) <span className="text-red-500">*</span>
1493+
</label>
1494+
<input
1495+
type="number"
1496+
step="0.00001"
1497+
value={hpPriceWinter}
1498+
onChange={(e) => setHpPriceWinter(e.target.value)}
1499+
className="input"
1500+
required
1501+
placeholder="0.2068"
1502+
/>
1503+
<p className="text-xs text-gray-500 mt-1">6h-22h les jours Éco</p>
1504+
</div>
1505+
</div>
1506+
<div className="space-y-4">
1507+
<h4 className="font-semibold text-red-700 dark:text-red-300 flex items-center gap-2">
1508+
<span className="w-3 h-3 rounded-full bg-red-500"></span> Jours Sobriété (20j/an)
1509+
</h4>
1510+
<div>
1511+
<label className="block text-sm font-medium mb-2">
1512+
HC Sobriété (€/kWh TTC) <span className="text-red-500">*</span>
1513+
</label>
1514+
<input
1515+
type="number"
1516+
step="0.00001"
1517+
value={hcPriceSummer}
1518+
onChange={(e) => setHcPriceSummer(e.target.value)}
1519+
className="input"
1520+
required
1521+
placeholder="0.1546"
1522+
/>
1523+
<p className="text-xs text-gray-500 mt-1">22h-6h les jours Sobriété</p>
1524+
</div>
1525+
<div>
1526+
<label className="block text-sm font-medium mb-2">
1527+
HP Sobriété (€/kWh TTC) <span className="text-red-500">*</span>
1528+
</label>
1529+
<input
1530+
type="number"
1531+
step="0.00001"
1532+
value={hpPriceSummer}
1533+
onChange={(e) => setHpPriceSummer(e.target.value)}
1534+
className="input"
1535+
required
1536+
placeholder="0.6712"
1537+
/>
1538+
<p className="text-xs text-gray-500 mt-1">6h-22h les jours Sobriété (prix majoré)</p>
1539+
</div>
1540+
</div>
1541+
</div>
1542+
</div>
1543+
)}
1544+
14541545
{offerType === 'TEMPO' && (
14551546
<div className="mt-4 space-y-4">
14561547
<div className="bg-blue-50 dark:bg-blue-900/20 p-4 rounded-lg">

apps/web/src/pages/Simulator.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,29 @@ export default function Simulator() {
17481748
{simulationResult && Array.isArray(simulationResult) && simulationResult.length > 0 && (
17491749
<>
17501750

1751+
{/* Information banner */}
1752+
<div className="mx-6 mb-4 p-4 rounded-xl bg-gradient-to-r from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 border border-blue-200 dark:border-blue-800">
1753+
<div className="flex items-start gap-3">
1754+
<div className="flex-shrink-0 w-10 h-10 rounded-full bg-blue-100 dark:bg-blue-800 flex items-center justify-center">
1755+
<span className="text-xl">💡</span>
1756+
</div>
1757+
<div className="flex-1 text-sm text-blue-800 dark:text-blue-200">
1758+
<p className="font-semibold mb-1">À propos de cette simulation</p>
1759+
<p className="text-blue-700 dark:text-blue-300 leading-relaxed">
1760+
Cette simulation est basée sur <strong>votre consommation réelle de l'année écoulée</strong> (J-1 à J-365).
1761+
Certaines offres comme <strong>Tempo</strong> ou <strong>Zen Flex</strong> appliquent des tarifs majorés sur quelques jours spécifiques
1762+
(22 jours rouges pour Tempo, 20 jours de sobriété pour Zen Flex).
1763+
</p>
1764+
<p className="text-blue-600 dark:text-blue-400 mt-2 font-medium">
1765+
🎯 En réduisant simplement votre consommation ces quelques jours dans l'année, vous pouvez significativement diminuer votre facture avec ces offres.
1766+
</p>
1767+
<p className="text-blue-600 dark:text-blue-400 mt-2">
1768+
💬 Votre fournisseur n'est pas listé ? <a href="/contribute" className="font-semibold underline hover:text-blue-800 dark:hover:text-blue-200">Contribuez au simulateur</a> en demandant son ajout !
1769+
</p>
1770+
</div>
1771+
</div>
1772+
</div>
1773+
17511774
{/* Filters */}
17521775
<div className="px-6 pb-4 border-b border-gray-200 dark:border-gray-700">
17531776
<div className="flex flex-wrap gap-3 p-3 bg-gray-50 dark:bg-gray-900/30 rounded-lg border border-gray-200 dark:border-gray-700">
@@ -2214,6 +2237,15 @@ export default function Simulator() {
22142237
</div>
22152238
</div>
22162239
</div>
2240+
{/* Info about Tempo optimization */}
2241+
<div className="p-3 rounded-lg bg-blue-50 dark:bg-blue-900/20 border-l-4 border-blue-400">
2242+
<div className="flex items-start gap-2 text-xs text-blue-700 dark:text-blue-300">
2243+
<span className="flex-shrink-0 text-base">💡</span>
2244+
<div>
2245+
<strong>Simulation basée sur votre consommation actuelle.</strong> En réduisant votre consommation les 22 jours rouges (HP à {formatPrice(result.offer.tempo_red_hp, 4)} €/kWh), vous pouvez significativement diminuer votre facture avec cette offre.
2246+
</div>
2247+
</div>
2248+
</div>
22172249
<div className="flex justify-between pt-3 border-t border-gray-200 dark:border-gray-600">
22182250
<span className="text-sm font-bold text-gray-700 dark:text-gray-300">Total énergie</span>
22192251
<span className="text-lg font-bold text-violet-600 dark:text-violet-400">{result.energyCost.toFixed(2)}</span>
@@ -2397,6 +2429,54 @@ export default function Simulator() {
23972429
</div>
23982430
)}
23992431

2432+
{/* TEMPO prices */}
2433+
{result.offerType === 'TEMPO' && result.offer.tempo_blue_hc && (
2434+
<div className="space-y-2">
2435+
{/* Jours Bleus */}
2436+
<div className="text-xs font-semibold text-blue-600 dark:text-blue-400 uppercase tracking-wide flex items-center gap-1">
2437+
<span className="w-2 h-2 rounded-full bg-blue-500"></span> Jours Bleus (300j)
2438+
</div>
2439+
<div className="grid grid-cols-2 gap-2">
2440+
<div className="p-2 rounded-lg bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 text-center">
2441+
<div className="text-xs text-blue-600 dark:text-blue-400">HC</div>
2442+
<div className="text-sm font-bold text-blue-800 dark:text-blue-200">{formatPrice(result.offer.tempo_blue_hc, 5)}</div>
2443+
</div>
2444+
<div className="p-2 rounded-lg bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 text-center">
2445+
<div className="text-xs text-blue-600 dark:text-blue-400">HP</div>
2446+
<div className="text-sm font-bold text-blue-800 dark:text-blue-200">{formatPrice(result.offer.tempo_blue_hp, 5)}</div>
2447+
</div>
2448+
</div>
2449+
{/* Jours Blancs */}
2450+
<div className="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide flex items-center gap-1">
2451+
<span className="w-2 h-2 rounded-full bg-gray-400"></span> Jours Blancs (43j)
2452+
</div>
2453+
<div className="grid grid-cols-2 gap-2">
2454+
<div className="p-2 rounded-lg bg-gray-100 dark:bg-gray-700/50 border border-gray-300 dark:border-gray-600 text-center">
2455+
<div className="text-xs text-gray-500 dark:text-gray-400">HC</div>
2456+
<div className="text-sm font-bold text-gray-700 dark:text-gray-200">{formatPrice(result.offer.tempo_white_hc, 5)}</div>
2457+
</div>
2458+
<div className="p-2 rounded-lg bg-gray-100 dark:bg-gray-700/50 border border-gray-300 dark:border-gray-600 text-center">
2459+
<div className="text-xs text-gray-500 dark:text-gray-400">HP</div>
2460+
<div className="text-sm font-bold text-gray-700 dark:text-gray-200">{formatPrice(result.offer.tempo_white_hp, 5)}</div>
2461+
</div>
2462+
</div>
2463+
{/* Jours Rouges */}
2464+
<div className="text-xs font-semibold text-red-600 dark:text-red-400 uppercase tracking-wide flex items-center gap-1">
2465+
<span className="w-2 h-2 rounded-full bg-red-500"></span> Jours Rouges (22j)
2466+
</div>
2467+
<div className="grid grid-cols-2 gap-2">
2468+
<div className="p-2 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-center">
2469+
<div className="text-xs text-red-600 dark:text-red-400">HC</div>
2470+
<div className="text-sm font-bold text-red-800 dark:text-red-200">{formatPrice(result.offer.tempo_red_hc, 5)}</div>
2471+
</div>
2472+
<div className="p-2 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-center">
2473+
<div className="text-xs text-red-600 dark:text-red-400">HP</div>
2474+
<div className="text-sm font-bold text-red-800 dark:text-red-200">{formatPrice(result.offer.tempo_red_hp, 5)}</div>
2475+
</div>
2476+
</div>
2477+
</div>
2478+
)}
2479+
24002480
{/* Link to offer */}
24012481
{result.offer.offer_url && (
24022482
<a

0 commit comments

Comments
 (0)