Created modular system for calculators, added soap and candles calculators, universal components, updated backend
109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useEffect } from 'react';
|
||
import Image from 'next/image';
|
||
import { getAllCalculators } from '@/lib/calculator-registry';
|
||
import CalculatorEngine from './CalculatorEngine';
|
||
|
||
type CalculatorMenuProps = {
|
||
chatId?: string | null;
|
||
};
|
||
|
||
export default function CalculatorMenu({ chatId: externalChatId }: CalculatorMenuProps) {
|
||
const [selectedCalculator, setSelectedCalculator] = useState<string | null>(null);
|
||
const [chatId, setChatId] = useState<string | null>(null);
|
||
const calculators = getAllCalculators();
|
||
|
||
// Получаем chat_id из URL или пропсов
|
||
useEffect(() => {
|
||
if (externalChatId) {
|
||
setChatId(externalChatId);
|
||
} else {
|
||
const params = new URLSearchParams(window.location.search);
|
||
const id = params.get('chat_id');
|
||
if (id) {
|
||
setChatId(id);
|
||
}
|
||
}
|
||
}, [externalChatId]);
|
||
|
||
// Если выбран калькулятор, показываем его
|
||
if (selectedCalculator) {
|
||
return (
|
||
<CalculatorEngine
|
||
calculatorId={selectedCalculator}
|
||
chatId={chatId}
|
||
onBack={() => setSelectedCalculator(null)}
|
||
/>
|
||
);
|
||
}
|
||
|
||
// Иначе показываем меню выбора
|
||
return (
|
||
<div className="max-w-2xl mx-auto p-6 bg-gray-800 text-gray-200 rounded-lg shadow-lg">
|
||
{/* Логотип */}
|
||
<div className="flex justify-center mb-8">
|
||
<Image
|
||
src="/logo.svg"
|
||
alt="Logo"
|
||
width={150}
|
||
height={50}
|
||
className="mx-auto w-64 md:w-96 lg:w-112 h-auto"
|
||
/>
|
||
</div>
|
||
|
||
{chatId === null && (
|
||
<div className="bg-yellow-800 p-4 text-yellow-200 font-semibold rounded mb-6">
|
||
❗ Не найден chat_id. Откройте калькулятор через Telegram-бота.
|
||
</div>
|
||
)}
|
||
|
||
{/* Заголовок */}
|
||
<h1 className="text-2xl font-bold text-center mb-8">
|
||
Выберите калькулятор
|
||
</h1>
|
||
|
||
{/* Список калькуляторов */}
|
||
{calculators.length === 0 ? (
|
||
<div className="text-center text-gray-400 py-8">
|
||
Нет доступных калькуляторов
|
||
</div>
|
||
) : (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
{calculators.map((calc) => (
|
||
<button
|
||
key={calc.id}
|
||
onClick={() => setSelectedCalculator(calc.id)}
|
||
className="
|
||
p-6
|
||
bg-gray-700
|
||
hover:bg-gray-600
|
||
rounded-lg
|
||
border-2 border-gray-600
|
||
hover:border-sky-500
|
||
transition-all
|
||
text-left
|
||
focus:outline-none focus:ring-2 focus:ring-sky-500
|
||
"
|
||
>
|
||
<div className="flex items-center gap-3 mb-2">
|
||
{calc.icon && <span className="text-3xl">{calc.icon}</span>}
|
||
<h2 className="text-xl font-semibold">{calc.name}</h2>
|
||
</div>
|
||
{calc.description && (
|
||
<p className="text-gray-400 text-sm">{calc.description}</p>
|
||
)}
|
||
</button>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{/* Подсказка */}
|
||
<div className="mt-8 text-center text-gray-400 text-sm">
|
||
Выберите калькулятор для начала расчёта
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|