/
PashigorevAY
/
TestFastAPI
Обзор
Документация
Войти
/
PashigorevAY
/
TestFastAPI
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
frontend/src/components/Catalogs.tsx
128 строк
4 KB
Pashigorev
Initial commit
05 июл 2026, 21:43
05 июл 2026, 21:43
19770a6
Код
Авторство
О чём код?
import { useState, useEffect } from 'react'; import { Catalog } from '../types'; import { api } from '../api'; interface CatalogsProps { onSelectCatalog: (name: string) => void; onBack: () => void; } export function Catalogs({ onSelectCatalog, onBack }: CatalogsProps) { const [catalogs, setCatalogs] = useState<Catalog[]>([]); const [showCreate, setShowCreate] = useState(false); const [folderName, setFolderName] = useState(''); const [description, setDescription] = useState(''); const [error, setError] = useState(''); useEffect(() => { loadCatalogs(); }, []); async function loadCatalogs() { const data = await api.getCatalogs(); setCatalogs(data.catalogs); } async function handleCreateCatalog() { try { setError(''); await api.createCatalog(folderName, description); setFolderName(''); setDescription(''); setShowCreate(false); loadCatalogs(); } catch (err) { setError(err instanceof Error ? err.message : 'Ошибка создания каталога'); } } return ( <div style={{ padding: '20px' }}> <div style={{ marginBottom: '20px', display: 'flex', gap: '10px', alignItems: 'center' }}> <button onClick={onBack} style={{ backgroundColor: '#e0e0e0' }}>← Назад</button> <h2 style={{ flex: 1 }}>Подзадачи</h2> <button onClick={() => setShowCreate(true)} style={{ backgroundColor: '#4CAF50', color: 'white' }} > Добавить каталог </button> </div> <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))', gap: '20px' }}> {catalogs.map((catalog) => ( <div key={catalog.name} onClick={() => onSelectCatalog(catalog.name)} style={{ padding: '20px', border: '1px solid #ddd', borderRadius: '8px', cursor: 'pointer', transition: 'box-shadow 0.2s', }} onMouseEnter={(e) => (e.currentTarget.style.boxShadow = '0 4px 8px rgba(0,0,0,0.1)')} onMouseLeave={(e) => (e.currentTarget.style.boxShadow = 'none')} > <h3>{catalog.name}</h3> <p style={{ color: '#666', marginTop: '8px', fontSize: '14px' }}> {catalog.description} </p> </div> ))} </div> {showCreate && ( <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', }}> <div style={{ background: 'white', padding: '24px', borderRadius: '8px', minWidth: '400px', }}> <h3>Создать каталог</h3> {error && <p style={{ color: 'red' }}>{error}</p>} <div style={{ marginTop: '16px', display: 'flex', flexDirection: 'column', gap: '12px' }}> <div> <label style={{ display: 'block', marginBottom: '4px' }}>Имя папки</label> <input value={folderName} onChange={(e) => setFolderName(e.target.value)} placeholder="только_маленькие_буквы_и_подчеркивания" style={{ width: '100%', padding: '8px' }} /> </div> <div> <label style={{ display: 'block', marginBottom: '4px' }}>Описание</label> <textarea value={description} onChange={(e) => setDescription(e.target.value)} rows={4} style={{ width: '100%', padding: '8px' }} /> </div> </div> <div style={{ marginTop: '20px', display: 'flex', gap: '10px', justifyContent: 'flex-end' }}> <button onClick={() => setShowCreate(false)} style={{ backgroundColor: '#e0e0e0' }}> Отмена </button> <button onClick={handleCreateCatalog} style={{ backgroundColor: '#4CAF50', color: 'white' }}> Создать </button> </div> </div> </div> )} </div> ); }