DoSoapCalc/frontend/components/CalculatorMenu.tsx
DosAi 02c7520c90 Refactor: Modular calculator architecture
Created modular system for calculators, added soap and candles calculators, universal components, updated backend
2025-11-02 15:45:07 +03:00

109 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'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>
);
}