Начальный коммит: рабочая версия с исправленной авторизацией
This commit is contained in:
74
frontend/src/components/ComponentSelector.jsx
Normal file
74
frontend/src/components/ComponentSelector.jsx
Normal file
@@ -0,0 +1,74 @@
|
||||
// src/components/ComponentSelector.jsx
|
||||
import { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
|
||||
export default function ComponentSelector({ type, onSelect, onPriceChange, selectedId }) {
|
||||
const [components, setComponents] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchComponents = async () => {
|
||||
try {
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) {
|
||||
console.warn('Токен отсутствует. Компоненты не загружены.');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await axios.get('http://localhost/api/components', {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
params: { type }, // фильтрация по code (cpu, gpu и т.д.)
|
||||
});
|
||||
|
||||
setComponents(response.data);
|
||||
} catch (err) {
|
||||
console.error(`Ошибка загрузки компонентов типа "${type}":`, err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchComponents();
|
||||
}, [type]);
|
||||
|
||||
const handleChange = (e) => {
|
||||
const id = e.target.value ? parseInt(e.target.value, 10) : null;
|
||||
|
||||
// Передаём ID в родительский компонент
|
||||
onSelect(id);
|
||||
|
||||
// Передаём цену, если компонент выбран
|
||||
if (id !== null && onPriceChange) {
|
||||
const selectedComp = components.find(comp => comp.id === id);
|
||||
if (selectedComp && onPriceChange) {
|
||||
const price = parseFloat(selectedComp.price); // ← преобразуем в число
|
||||
onPriceChange(id, price);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<select disabled style={{ width: '100%', padding: '8px', marginBottom: '10px' }}>
|
||||
<option>Загрузка...</option>
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<select
|
||||
value={selectedId || ''}
|
||||
onChange={handleChange}
|
||||
style={{ width: '100%', padding: '8px', marginBottom: '10px' }}
|
||||
required
|
||||
>
|
||||
<option value="">Выберите {type}</option>
|
||||
{components.map((comp) => (
|
||||
<option key={comp.id} value={comp.id}>
|
||||
{comp.name} — {comp.price} ₽
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
27
frontend/src/components/Layout.jsx
Normal file
27
frontend/src/components/Layout.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
// src/components/Layout.jsx
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<div style={{ display: 'flex', minHeight: '100vh' }}>
|
||||
{/* Боковое меню */}
|
||||
<aside style={{ width: 200, background: '#f4f4f4', padding: '1rem' }}>
|
||||
<h3>Меню</h3>
|
||||
<nav>
|
||||
<ul style={{ listStyle: 'none', padding: 0 }}>
|
||||
<li><Link to="/builds">Сборки</Link></li>
|
||||
<li><Link to="/builds/new">Новая сборка</Link></li>
|
||||
<li><Link to="/ai">ИИ подбор</Link></li>
|
||||
<li><Link to="/login">Вход</Link></li>
|
||||
<li><Link to="/register">Регистрация</Link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
{/* Основной контент */}
|
||||
<main style={{ flex: 1, padding: '1rem' }}>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user