Skip to content

Commit 08a18d7

Browse files
Merge pull request #4330 from OneCommunityGlobal/Prem-Fix-Event_images-not_loading
Prem - Fix event images not loading
2 parents 77e7791 + 9da79fc commit 08a18d7

1 file changed

Lines changed: 137 additions & 69 deletions

File tree

src/components/CommunityPortal/CPDashboard.jsx

Lines changed: 137 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,91 @@ import { useState, useEffect } from 'react';
22
import { Container, Row, Col, Card, CardBody, Button, Input } from 'reactstrap';
33
import './CPDashboard.css';
44
import { FaCalendarAlt, FaMapMarkerAlt, FaUserAlt } from 'react-icons/fa';
5-
import { toast } from 'react-toastify';
5+
import { ENDPOINTS } from '../../utils/URL';
6+
import axios from 'axios';
67

78
export function CPDashboard() {
89
const [events, setEvents] = useState([]);
910
const [search, setSearch] = useState('');
10-
const [selectedDate, setSelectedDate] = useState('');
11-
const [dateError, setDateError] = useState('');
11+
const [isLoading, setIsLoading] = useState(false);
12+
const [error, setError] = useState(null);
13+
const [pagination, setPagination] = useState({
14+
currentPage: 1,
15+
totalPages: 5,
16+
total: 0,
17+
limit: 6,
18+
});
19+
20+
const FALLBACK_IMG =
21+
'https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=600&q=60';
22+
23+
const FixedRatioImage = ({ src, alt, fallback }) => (
24+
<div
25+
style={{
26+
width: '100%',
27+
aspectRatio: '4 / 3',
28+
overflow: 'hidden',
29+
background: '#f2f2f2',
30+
}}
31+
>
32+
<img
33+
src={src || fallback}
34+
alt={alt}
35+
loading="lazy"
36+
onError={e => {
37+
if (e.currentTarget.src !== fallback) e.currentTarget.src = fallback;
38+
}}
39+
style={{
40+
width: '100%',
41+
height: '100%',
42+
objectFit: 'cover',
43+
display: 'block',
44+
}}
45+
/>
46+
</div>
47+
);
1248

1349
useEffect(() => {
14-
const mockEvents = [
15-
{
16-
id: 1,
17-
title: 'PGSA Lunch Talks',
18-
date: 'Friday, December 6 at 12:00PM EST',
19-
location: 'Disque 919',
20-
organizer: 'Physics Graduate Student Association',
21-
image: 'https://via.placeholder.com/300',
22-
},
23-
{
24-
id: 2,
25-
title: 'Hot Chocolate/Bake Sale',
26-
date: 'Friday, December 6 at 12:00PM EST',
27-
location: 'G.C LeBow - Lobby Tabling Space 2',
28-
organizer: 'Kappa Phi Gamma, Sorority Inc.',
29-
image: 'https://via.placeholder.com/300',
30-
},
31-
{
32-
id: 3,
33-
title: 'Holiday Lunch',
34-
date: 'Friday, December 6 at 12:00PM EST',
35-
location: 'Hill Conference Room',
36-
organizer: 'Chemical and Biological Engineering Graduate Society',
37-
image: 'https://via.placeholder.com/300',
38-
},
39-
];
40-
setEvents(mockEvents);
50+
const fetchEvents = async () => {
51+
setIsLoading(true);
52+
53+
try {
54+
const response = await axios.get(ENDPOINTS.EVENTS);
55+
console.log('Fetched events:', response.data.events);
56+
setEvents(response.data.events);
57+
} catch (err) {
58+
console.error('Here', err);
59+
setError('Failed to load events');
60+
} finally {
61+
setIsLoading(false);
62+
}
63+
};
64+
65+
fetchEvents();
4166
}, []);
4267

43-
const handleDateChange = e => {
44-
const value = e.target.value;
45-
setSelectedDate(value);
68+
const formatDate = dateStr => {
69+
if (!dateStr) return 'Date TBD';
70+
const date = new Date(dateStr);
71+
return date.toLocaleString('en-US', {
72+
weekday: 'long',
73+
month: 'long',
74+
day: 'numeric',
75+
hour: 'numeric',
76+
minute: '2-digit',
77+
});
78+
};
4679

47-
const today = new Date();
48-
today.setHours(0, 0, 0, 0); // midnight today
80+
const filteredEvents = events.filter(event =>
81+
event.title?.toLowerCase().includes(search.toLowerCase()),
82+
);
4983

50-
const chosen = new Date(value);
84+
const totalPages = Math.ceil(filteredEvents.length / pagination.limit);
5185

52-
if (chosen < today) {
53-
toast.error('Past dates are not supported. Please select a future date.');
54-
setSelectedDate('');
55-
return;
56-
}
57-
};
86+
const displayedEvents = filteredEvents.slice(
87+
(pagination.currentPage - 1) * pagination.limit,
88+
pagination.currentPage * pagination.limit,
89+
);
5890

5991
return (
6092
<Container fluid className="dashboard-container">
@@ -70,17 +102,6 @@ export function CPDashboard() {
70102
className="dashboard-search"
71103
/>
72104
</div>
73-
{/* <Dropdown isOpen={dropdownOpen} toggle={toggleDropdown} className="community-dropdown">
74-
<DropdownToggle caret color="secondary">
75-
Community Portal
76-
</DropdownToggle>
77-
<DropdownMenu>
78-
<DropdownItem onClick={() => handleNavigation('/home')}>Home</DropdownItem>
79-
<DropdownItem onClick={() => handleNavigation('/events')}>Events</DropdownItem>
80-
<DropdownItem onClick={() => handleNavigation('/about')}>About Us</DropdownItem>
81-
<DropdownItem onClick={() => handleNavigation('/contact')}>Contact</DropdownItem>
82-
</DropdownMenu>
83-
</Dropdown> */}
84105
</div>
85106
</header>
86107

@@ -139,34 +160,81 @@ export function CPDashboard() {
139160

140161
<Col md={9} className="dashboard-main">
141162
<h2 className="section-title">Events</h2>
142-
<Row>
143-
{events.length > 0 ? (
144-
events.map(event => (
145-
<Col md={4} key={event.id} className="event-card-col">
146-
<Card className="event-card">
163+
164+
{error && <div className="alert alert-danger">{error}</div>}
165+
166+
{isLoading ? (
167+
<div className="d-flex justify-content-center mt-4"></div>
168+
) : displayedEvents.length > 0 ? (
169+
<Row>
170+
{displayedEvents.map(event => (
171+
<Col md={4} key={event._id || event.id} className="event-card-col">
172+
<Card
173+
className="event-card"
174+
style={{
175+
display: 'flex',
176+
flexDirection: 'column',
177+
borderRadius: 14,
178+
overflow: 'hidden',
179+
}}
180+
>
147181
<div className="event-card-img-container">
148-
<img src={event.image} alt={event.title} className="event-card-img" />
182+
<FixedRatioImage
183+
src={event.coverImage}
184+
alt={event.title}
185+
fallback={FALLBACK_IMG}
186+
/>
149187
</div>
150-
<CardBody>
188+
<CardBody style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
151189
<h5 className="event-title">{event.title}</h5>
152190
<p className="event-date">
153-
<FaCalendarAlt className="event-icon" /> {event.date}
191+
<FaCalendarAlt className="event-icon" /> {formatDate(event.date)}
154192
</p>
155193
<p className="event-location">
156-
<FaMapMarkerAlt className="event-icon" /> {event.location}
194+
<FaMapMarkerAlt className="event-icon" /> {event.location || 'TBD'}
157195
</p>
158196
<p className="event-organizer">
159-
<FaUserAlt className="event-icon" /> {event.organizer}
197+
<FaUserAlt className="event-icon" /> {event.maxAttendees || 'No limit'}{' '}
198+
Attendees limit
160199
</p>
161200
</CardBody>
162201
</Card>
163202
</Col>
164-
))
165-
) : (
166-
<div className="no-events">No events available</div>
167-
)}
168-
</Row>
169-
<div className="dashboard-actions">
203+
))}
204+
</Row>
205+
) : (
206+
<div className="no-events">No events available</div>
207+
)}
208+
209+
<div className="d-flex justify-content-center mt-4">
210+
<div className="pagination-controls">
211+
<Button
212+
color="secondary"
213+
disabled={pagination.currentPage === 1}
214+
onClick={() =>
215+
setPagination(prev => ({ ...prev, currentPage: prev.currentPage - 1 }))
216+
}
217+
>
218+
Previous
219+
</Button>
220+
221+
<span className="mx-3">
222+
Page {pagination.currentPage} of {totalPages}
223+
</span>
224+
225+
<Button
226+
color="secondary"
227+
disabled={pagination.currentPage === totalPages}
228+
onClick={() =>
229+
setPagination(prev => ({ ...prev, currentPage: prev.currentPage + 1 }))
230+
}
231+
>
232+
Next
233+
</Button>
234+
</div>
235+
</div>
236+
237+
<div className="dashboard-actions text-center mt-4">
170238
<Button color="primary">Show Past Events</Button>
171239
</div>
172240
</Col>

0 commit comments

Comments
 (0)