This commit is contained in:
2025-11-06 13:26:38 +04:00
parent e2263f8856
commit 8058b6aef8

View File

@@ -1,61 +1,183 @@
// src/pages/CatalogPage.jsx
import React from 'react';
import React, { useState, useEffect } from 'react';
import EventList from '../components/EventList';
import EventForm from '../components/EventForm';
import useEvents from '../hooks/useEvents';
import useFormState from '../hooks/useFormState';
const API_URL = 'http://localhost:8080/api/events';
const CatalogPage = () => {
const { events, loading, error, addEvent, updateEvent, deleteEvent } = useEvents();
const { formData, currentEvent, isFormOpen, openForm, closeForm, handleFormChange } = useFormState();
const [events, setEvents] = useState([]);
const [currentEvent, setCurrentEvent] = useState(null);
const [isFormOpen, setIsFormOpen] = useState(false);
const [sortOrder, setSortOrder] = useState('asc');
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// Функция для открытия формы для РЕДАКТИРОВАНИЯ
const handleEditClick = (event) => {
openForm(event); // Передаём конкретное событие
};
// Функция для открытия формы для ДОБАВЛЕНИЯ
const handleAddClick = () => {
openForm(null); // Явно передаём null
};
const handleFormSubmit = async (e) => {
e.preventDefault();
try {
if (currentEvent) {
await updateEvent(currentEvent.id, formData);
const getSortedEvents = (eventsList, order) => {
if (!eventsList || !Array.isArray(eventsList)) return [];
return [...eventsList].sort((a, b) => {
const titleA = a.title ? a.title.toLowerCase() : '';
const titleB = b.title ? b.title.toLowerCase() : '';
if (order === 'asc') {
return titleA < titleB ? -1 : titleA > titleB ? 1 : 0;
} else {
await addEvent(formData);
return titleA > titleB ? -1 : titleA < titleB ? 1 : 0;
}
closeForm();
} catch (err) {
console.error('Ошибка сохранения:', err);
});
};
const sortedEvents = getSortedEvents(events, sortOrder);
useEffect(() => {
fetchEvents();
}, []);
const fetchEvents = async () => {
try {
setLoading(true);
const response = await fetch(API_URL);
if (!response.ok) {
throw new Error(`Ошибка HTTP: ${response.status}`);
}
const data = await response.json();
setEvents(data);
setError(null);
} catch (error) {
console.error('Ошибка при загрузке событий:', error);
setError('Не удалось загрузить события. Проверьте, запущен ли сервер на порту 8080.');
} finally {
setLoading(false);
}
};
if (loading) return <p className="text-center">Загрузка событий...</p>;
if (error) return <p className="text-center text-danger">Ошибка: {error}</p>;
const handleAddClick = () => {
setCurrentEvent(null);
setIsFormOpen(true);
};
const handleEditClick = (event) => {
setCurrentEvent(event);
setIsFormOpen(true);
};
const handleFormSubmit = async (eventData) => {
try {
if (currentEvent) {
// Обновление существующего события
const response = await fetch(`${API_URL}/${currentEvent.id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(eventData),
});
if (!response.ok) {
throw new Error(`Ошибка обновления: ${response.status}`);
}
const updatedEvent = await response.json();
setEvents(events.map(e => e.id === currentEvent.id ? updatedEvent : e));
} else {
// Создание нового события
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(eventData),
});
if (!response.ok) {
throw new Error(`Ошибка создания: ${response.status}`);
}
const newEvent = await response.json();
setEvents([...events, newEvent]);
}
setIsFormOpen(false);
} catch (error) {
console.error('Ошибка при сохранении события:', error);
alert('Ошибка при сохранении события: ' + error.message);
}
};
const handleDeleteClick = async (id) => {
if (window.confirm('Вы уверены, что хотите удалить это событие?')) {
try {
const response = await fetch(`${API_URL}/${id}`, {
method: 'DELETE',
});
if (!response.ok) {
throw new Error(`Ошибка удаления: ${response.status}`);
}
setEvents(events.filter(e => e.id !== id));
} catch (error) {
console.error('Ошибка при удалении события:', error);
alert('Ошибка при удалении события: ' + error.message);
}
}
};
const handleFormClose = () => {
setIsFormOpen(false);
};
const handleSortAsc = () => {
setSortOrder('asc');
};
const handleSortDesc = () => {
setSortOrder('desc');
};
if (loading) {
return <div className="container-fluid">Загрузка событий...</div>;
}
if (error) {
return (
<div className="container-fluid">
<div style={{ color: '#ff4444', padding: '20px', textAlign: 'center' }}>
<h3>Ошибка подключения</h3>
<p>{error}</p>
<button className="btn btn-neon" onClick={fetchEvents}>
Попробовать снова
</button>
</div>
</div>
);
}
return (
<div className="container-fluid">
<h1>Каталог стримов и событий</h1>
<p>Выбирай из нашего ассортимента уникальных стримов, концертов и кибермероприятий.</p>
{/* Кнопки сортировки */}
<div className="mb-3">
<button className={`btn btn-sort ${sortOrder === 'asc' ? 'btn-sort-active' : 'btn-sort-inactive'}`}
onClick={handleSortAsc}>
Сортировать А-Я
</button>
<button className={`btn btn-sort ${sortOrder === 'desc' ? 'btn-sort-active' : 'btn-sort-inactive'}`}
onClick={handleSortDesc}>
Сортировать Я-А
</button>
</div>
<EventList
events={events}
onEdit={handleEditClick} // Передаём новую функцию для редактирования
onDelete={deleteEvent}
onAddClick={handleAddClick} // Передаём новую функцию для добавления
events={sortedEvents}
onEdit={handleEditClick}
onDelete={handleDeleteClick}
/>
<div className="text-center mt-4">
<button className="btn btn-neon btn-lg" onClick={handleAddClick}>
<i className="bi bi-plus-circle me-2"></i>Добавить новое событие
</button>
</div>
{isFormOpen && (
<EventForm
formData={formData}
currentEvent={currentEvent}
onChange={handleFormChange}
initialData={currentEvent}
onSubmit={handleFormSubmit}
onClose={closeForm}
onClose={handleFormClose}
/>
)}
</div>