Skip to content

Commit 0861bc2

Browse files
committed
Improve UI
1 parent db3d61f commit 0861bc2

File tree

4 files changed

+230
-19
lines changed

4 files changed

+230
-19
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/* Современные стили для подробностей события */
2+
.event-details-card {
3+
background: #fff;
4+
border-radius: 24px;
5+
box-shadow: 0 4px 24px rgba(135,210,167,0.18);
6+
padding: 36px 32px 32px 32px;
7+
max-width: 700px;
8+
margin: 32px auto;
9+
position: relative;
10+
animation: fadeInUp 0.5s cubic-bezier(.23,1.01,.32,1) both;
11+
}
12+
@keyframes fadeInUp {
13+
from { opacity: 0; transform: translateY(40px); }
14+
to { opacity: 1; transform: none; }
15+
}
16+
.event-details-back {
17+
position: absolute;
18+
top: 18px;
19+
left: 18px;
20+
background: #87D2A7;
21+
color: #0F114B;
22+
border: none;
23+
border-radius: 8px;
24+
padding: 8px 18px;
25+
font-weight: 600;
26+
font-size: 15px;
27+
cursor: pointer;
28+
box-shadow: 0 2px 8px rgba(135,210,167,0.10);
29+
transition: background 0.2s;
30+
z-index: 2;
31+
}
32+
.event-details-back:hover {
33+
background: #6ccf9a;
34+
}
35+
.event-details-main {
36+
display: flex;
37+
gap: 32px;
38+
align-items: flex-start;
39+
flex-wrap: wrap;
40+
}
41+
.event-details-img-wrap {
42+
flex: 0 0 220px;
43+
display: flex;
44+
align-items: center;
45+
justify-content: center;
46+
min-width: 180px;
47+
}
48+
.event-details-img {
49+
width: 220px;
50+
height: 220px;
51+
object-fit: cover;
52+
border-radius: 18px;
53+
background: #f3f3f3;
54+
box-shadow: 0 2px 8px rgba(135,210,167,0.10);
55+
}
56+
.event-details-info {
57+
flex: 1 1 300px;
58+
display: flex;
59+
flex-direction: column;
60+
gap: 10px;
61+
min-width: 220px;
62+
}
63+
.event-details-title {
64+
margin: 0 0 10px 0;
65+
color: #0F114B;
66+
font-size: 2rem;
67+
font-weight: 700;
68+
}
69+
.event-details-row {
70+
display: flex;
71+
align-items: center;
72+
gap: 10px;
73+
font-size: 1.08rem;
74+
color: #222;
75+
margin-bottom: 2px;
76+
}
77+
.event-details-icon {
78+
font-size: 1.2em;
79+
opacity: 0.7;
80+
}
81+
.event-details-link {
82+
color: #1976d2;
83+
text-decoration: underline;
84+
word-break: break-all;
85+
}
86+
.event-details-link:hover {
87+
color: #0F114B;
88+
}
89+
.event-details-desc-block {
90+
margin-top: 32px;
91+
background: #f8f8f8;
92+
border-radius: 16px;
93+
padding: 20px 24px;
94+
box-shadow: 0 2px 8px rgba(135,210,167,0.07);
95+
}
96+
.event-details-desc-title {
97+
font-weight: 600;
98+
color: #0F114B;
99+
margin-bottom: 8px;
100+
font-size: 1.1rem;
101+
}
102+
.event-details-desc {
103+
color: #333;
104+
font-size: 1.05rem;
105+
max-height: 180px;
106+
overflow-y: auto;
107+
white-space: pre-line;
108+
}
109+
@media (max-width: 900px) {
110+
.event-details-main {
111+
flex-direction: column;
112+
gap: 18px;
113+
align-items: stretch;
114+
}
115+
.event-details-img {
116+
width: 100%;
117+
height: 180px;
118+
border-radius: 14px;
119+
}
120+
.event-details-img-wrap {
121+
min-width: 0;
122+
}
123+
}
124+
@media (max-width: 600px) {
125+
.event-details-card {
126+
padding: 18px 4vw 18px 4vw;
127+
max-width: 98vw;
128+
}
129+
.event-details-title {
130+
font-size: 1.2rem;
131+
}
132+
.event-details-desc-block {
133+
padding: 12px 8px;
134+
}
135+
}

organizer-frontend/src/components/EventDetails/EventDetails.jsx

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,77 @@
11
import React from "react";
2+
import './EventDetails.css';
3+
4+
function formatDate(dateStr, timeStr) {
5+
if (!dateStr) return "—";
6+
const date = new Date(dateStr + (timeStr ? 'T' + timeStr : ''));
7+
return date.toLocaleDateString('ru-RU', { day: '2-digit', month: 'long', year: 'numeric' }) +
8+
(timeStr ? `, ${date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })}` : '');
9+
}
210

311
function EventDetails({ event, onBack }) {
12+
if (!event) return null;
413
return (
5-
<div style={{padding: 32}}>
6-
<button onClick={onBack} style={{marginBottom: 24, background:'#87D2A7', color:'#0F114B', border:'none', borderRadius:8, padding:'10px 20px', fontWeight:600, fontSize:15, cursor:'pointer'}}>Назад</button>
7-
<h2 style={{marginBottom: 16}}>{event.title}</h2>
8-
<img src={event.img || event.imageUrl} alt={event.title} style={{width: 220, height: 220, objectFit: 'cover', borderRadius: 16, marginBottom: 24}} />
9-
<div><b>Дата:</b> {event.date} {event.time && <span>в {event.time}</span>}</div>
10-
<div><b>Место:</b> {event.location || event.place}</div>
11-
<div><b>Цена:</b> {event.price}</div>
12-
<div><b>Жанр:</b> {event.genre}</div>
13-
<div><b>Длительность:</b> {event.duration}</div>
14-
<div><b>Режиссёр:</b> {event.director}</div>
15-
<div><b>Ссылка:</b> <a href={event.link} target="_blank" rel="noopener noreferrer">{event.link}</a></div>
16-
<div style={{marginTop: 16}}><b>Описание:</b><br />{event.description}</div>
14+
<div className="event-details-card animate-in">
15+
<button className="event-details-back" onClick={onBack}>
16+
← Назад
17+
</button>
18+
<div className="event-details-main">
19+
<div className="event-details-img-wrap">
20+
<img
21+
className="event-details-img"
22+
src={event.img || event.imageUrl || './no-image.png'}
23+
alt={event.title}
24+
onError={e => e.target.src = './no-image.png'}
25+
/>
26+
</div>
27+
<div className="event-details-info">
28+
<h2 className="event-details-title">{event.title || 'Без названия'}</h2>
29+
<div className="event-details-row">
30+
<span className="event-details-icon">📅</span>
31+
<span>{formatDate(event.date, event.time)}</span>
32+
</div>
33+
{event.place || event.location ? (
34+
<div className="event-details-row">
35+
<span className="event-details-icon">📍</span>
36+
<span>{event.place || event.location}</span>
37+
</div>
38+
) : null}
39+
{event.price ? (
40+
<div className="event-details-row">
41+
<span className="event-details-icon">💸</span>
42+
<span>{event.price}</span>
43+
</div>
44+
) : null}
45+
{event.genre ? (
46+
<div className="event-details-row">
47+
<span className="event-details-icon">🎭</span>
48+
<span>{event.genre}</span>
49+
</div>
50+
) : null}
51+
{event.duration ? (
52+
<div className="event-details-row">
53+
<span className="event-details-icon">⏱️</span>
54+
<span>{event.duration}</span>
55+
</div>
56+
) : null}
57+
{event.director ? (
58+
<div className="event-details-row">
59+
<span className="event-details-icon">🎬</span>
60+
<span>{event.director}</span>
61+
</div>
62+
) : null}
63+
{event.link ? (
64+
<div className="event-details-row">
65+
<span className="event-details-icon">🔗</span>
66+
<a href={event.link} target="_blank" rel="noopener noreferrer" className="event-details-link">{event.link}</a>
67+
</div>
68+
) : null}
69+
</div>
70+
</div>
71+
<div className="event-details-desc-block">
72+
<div className="event-details-desc-title">Описание</div>
73+
<div className="event-details-desc">{event.description || '—'}</div>
74+
</div>
1775
</div>
1876
);
1977
}

organizer-frontend/src/components/EventTableRow/EventTableRow.jsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import React from "react";
22

33
function EventTableRow({ event, index, selected, onSelect, onClick }) {
4+
// Проверка на пустой event
5+
if (!event) return null;
46
return (
5-
<tr style={{borderBottom: '1px solid #eee', cursor: 'pointer'}} onClick={() => onClick(index)}>
7+
<tr style={{borderBottom: '1px solid #eee', cursor: 'pointer', color: '#222'}} onClick={() => onClick(index)}>
68
<td style={{padding: '10px'}} onClick={e => e.stopPropagation()}>
79
<input
810
type="checkbox"
911
checked={selected.includes(index)}
1012
onChange={() => onSelect(index)}
1113
/>
1214
</td>
13-
<td style={{padding: '10px', color: '#1976d2', textDecoration: 'underline'}}>{event.title}</td>
14-
<td style={{padding: '10px'}}>{event.date}</td>
15-
<td style={{padding: '10px'}}>{event.location || event.place}</td>
16-
<td style={{padding: '10px'}}>{event.description}</td>
17-
<td style={{padding: '10px'}}>
18-
<img src={event.img || event.imageUrl} alt={event.title} style={{width: 60, height: 60, objectFit: 'cover', borderRadius: 8}} />
15+
<td style={{padding: '10px', color: '#1976d2', textDecoration: 'underline'}}>{event.title || '-'}</td>
16+
<td style={{padding: '10px', color: '#222'}}>{event.date || '-'}</td>
17+
<td style={{padding: '10px', color: '#222'}}>{event.place || event.location || '-'}</td>
18+
<td style={{padding: '10px', maxWidth: 250, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', color: '#222'}}>{event.description || '-'}</td>
19+
<td style={{padding: '10px', display: 'flex', alignItems: 'center', gap: 8}}>
20+
{event.img || event.imageUrl ? (
21+
<img src={event.img || event.imageUrl} alt={event.title} style={{width: 60, height: 60, objectFit: 'cover', borderRadius: 8}} />
22+
) : (
23+
<span style={{color:'#aaa'}}>Нет изображения</span>
24+
)}
1925
</td>
2026
</tr>
2127
);

organizer-frontend/src/components/EventsList.jsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ function EventsList({}) {
6868
setSelected([]);
6969
};
7070

71+
const handleDeleteEvent = async (eventId) => {
72+
if (!eventId || !token) return;
73+
await fetch(`${API_URL}/${eventId}`, {
74+
method: 'DELETE',
75+
headers: {
76+
'Authorization': `Bearer ${token}`
77+
}
78+
});
79+
setEvents(events => events.filter(ev => ev.id !== eventId));
80+
setSelected(selected => selected.filter(idx => events[idx]?.id !== eventId));
81+
};
82+
7183
return (
7284
<>
7385
<Header />

0 commit comments

Comments
 (0)