feat: estimator reads prices from DB via usePricing

This commit is contained in:
2026-05-10 12:55:48 +03:00
parent 775ad2d935
commit 9cfbee74e0
+27 -26
View File
@@ -1,20 +1,21 @@
import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { Calculator } from 'lucide-react';
import { usePricing } from '../hooks/usePricing';
const Estimator = () => {
const [area, setArea] = useState(20); // in sq meters
const [area, setArea] = useState(20);
const [thickness, setThickness] = useState(200);
const { prices, loading: pricesLoading } = usePricing();
// Цены за квадратный метр в зависимости от толщины пленки
const costPerSqM = thickness === 200 ? 2000 : 3000;
const costPerSqM = prices[thickness] ?? (thickness === 200 ? 2000 : 3000);
const estimatedCost = area * costPerSqM;
return (
<section id="estimator" style={{ backgroundColor: 'var(--bg-lighter)' }}>
<div className="container">
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '50px', alignItems: 'center' }}>
<div style={{ flex: '1 1 400px' }}>
<motion.div
initial={{ opacity: 0, x: -50 }}
@@ -28,19 +29,19 @@ const Estimator = () => {
<p style={{ color: 'var(--text-muted)', fontSize: '1.2rem', marginBottom: '40px', lineHeight: '1.6' }}>
Рассчитайте примерную стоимость обеспечения безопасности вашего периметра. Окончательная стоимость определяется после профессионального осмотра объекта.
</p>
<div className="glass-panel" style={{ padding: '40px' }}>
<div style={{ marginBottom: '35px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '15px' }}>
<label style={{ fontWeight: 600, color: 'var(--text-main)', fontSize: '1.1rem' }}>Толщина пленки</label>
</div>
<select
value={thickness}
<select
value={thickness}
onChange={(e) => setThickness(parseInt(e.target.value))}
style={{
width: '100%', padding: '12px',
background: 'var(--bg-lighter)',
border: '2px solid var(--border-light)',
style={{
width: '100%', padding: '12px',
background: 'var(--bg-lighter)',
border: '2px solid var(--border-light)',
borderRadius: '8px',
color: 'var(--text-main)',
fontSize: '1rem',
@@ -48,8 +49,8 @@ const Estimator = () => {
cursor: 'pointer'
}}
>
<option value={200}>200 микрон (от 2000 /м²)</option>
<option value={300}>300 микрон (от 3000 /м²)</option>
<option value={200}>200 микрон (от {prices[200].toLocaleString('ru-RU')} /м²)</option>
<option value={300}>300 микрон (от {prices[300].toLocaleString('ru-RU')} /м²)</option>
</select>
</div>
@@ -58,12 +59,12 @@ const Estimator = () => {
<label style={{ fontWeight: 600, color: 'var(--text-main)', fontSize: '1.1rem' }}>Общая площадь (м²)</label>
<span className="text-accent-blue" style={{ fontWeight: '800', fontSize: '1.2rem' }}>{area}</span>
</div>
<input
type="range"
min="5"
max="500"
<input
type="range"
min="5"
max="500"
step="5"
value={area}
value={area}
onChange={(e) => setArea(parseInt(e.target.value))}
style={{ width: '100%', accentColor: 'var(--accent-blue)', height: '8px', borderRadius: '4px' }}
/>
@@ -79,8 +80,8 @@ const Estimator = () => {
transition={{ duration: 0.6, delay: 0.2, type: "spring" }}
viewport={{ once: true }}
className="glass-panel"
style={{
padding: '50px',
style={{
padding: '50px',
textAlign: 'center',
border: '2px solid rgba(14, 165, 233, 0.2)',
boxShadow: '0 20px 50px rgba(14, 165, 233, 0.1)'
@@ -92,20 +93,20 @@ const Estimator = () => {
>
<Calculator size={56} className="text-accent-blue" style={{ margin: '0 auto 25px' }} />
</motion.div>
<h3 style={{ fontSize: '1.3rem', color: 'var(--text-muted)', marginBottom: '15px' }}>Ориентировочная стоимость</h3>
<div style={{ fontSize: '3.8rem', fontWeight: 800, fontFamily: 'var(--font-heading)', color: 'var(--text-main)', marginBottom: '20px' }}>
{estimatedCost.toLocaleString('ru-RU')}
{pricesLoading ? '...' : estimatedCost.toLocaleString('ru-RU')}
</div>
<p style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '35px', lineHeight: '1.6' }}>
Включает бронематериалы, специализированный монтаж и финальную проверку.
</p>
<motion.a
<motion.a
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
href="#contact"
className="btn-primary"
href="#contact"
className="btn-primary"
style={{ display: 'block', width: '100%', textAlign: 'center' }}
>
Запросить точный расчет