Skip to content

Commit 0f5f93e

Browse files
committed
Fixed image issue on dashboard
1 parent b8630ba commit 0f5f93e

File tree

1 file changed

+141
-54
lines changed

1 file changed

+141
-54
lines changed

src/components/CommunityPortal/CPDashboard.jsx

Lines changed: 141 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,92 @@ 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 { ENDPOINTS } from '../../utils/URL';
6+
import axios from 'axios';
57

68
export function CPDashboard() {
79
const [events, setEvents] = useState([]);
810
const [search, setSearch] = 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+
);
948

1049
useEffect(() => {
11-
const mockEvents = [
12-
{
13-
id: 1,
14-
title: 'PGSA Lunch Talks',
15-
date: 'Friday, December 6 at 12:00PM EST',
16-
location: 'Disque 919',
17-
organizer: 'Physics Graduate Student Association',
18-
image: 'https://via.placeholder.com/300',
19-
},
20-
{
21-
id: 2,
22-
title: 'Hot Chocolate/Bake Sale',
23-
date: 'Friday, December 6 at 12:00PM EST',
24-
location: 'G.C LeBow - Lobby Tabling Space 2',
25-
organizer: 'Kappa Phi Gamma, Sorority Inc.',
26-
image: 'https://via.placeholder.com/300',
27-
},
28-
{
29-
id: 3,
30-
title: 'Holiday Lunch',
31-
date: 'Friday, December 6 at 12:00PM EST',
32-
location: 'Hill Conference Room',
33-
organizer: 'Chemical and Biological Engineering Graduate Society',
34-
image: 'https://via.placeholder.com/300',
35-
},
36-
];
37-
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();
3866
}, []);
3967

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+
};
79+
80+
const filteredEvents = events.filter(event =>
81+
event.title?.toLowerCase().includes(search.toLowerCase()),
82+
);
83+
84+
const totalPages = Math.ceil(filteredEvents.length / pagination.limit);
85+
86+
const displayedEvents = filteredEvents.slice(
87+
(pagination.currentPage - 1) * pagination.limit,
88+
pagination.currentPage * pagination.limit,
89+
);
90+
4091
return (
4192
<Container fluid className="dashboard-container">
4293
<header className="dashboard-header">
@@ -51,17 +102,6 @@ export function CPDashboard() {
51102
className="dashboard-search"
52103
/>
53104
</div>
54-
{/* <Dropdown isOpen={dropdownOpen} toggle={toggleDropdown} className="community-dropdown">
55-
<DropdownToggle caret color="secondary">
56-
Community Portal
57-
</DropdownToggle>
58-
<DropdownMenu>
59-
<DropdownItem onClick={() => handleNavigation('/home')}>Home</DropdownItem>
60-
<DropdownItem onClick={() => handleNavigation('/events')}>Events</DropdownItem>
61-
<DropdownItem onClick={() => handleNavigation('/about')}>About Us</DropdownItem>
62-
<DropdownItem onClick={() => handleNavigation('/contact')}>Contact</DropdownItem>
63-
</DropdownMenu>
64-
</Dropdown> */}
65105
</div>
66106
</header>
67107

@@ -110,34 +150,81 @@ export function CPDashboard() {
110150

111151
<Col md={9} className="dashboard-main">
112152
<h2 className="section-title">Events</h2>
113-
<Row>
114-
{events.length > 0 ? (
115-
events.map(event => (
116-
<Col md={4} key={event.id} className="event-card-col">
117-
<Card className="event-card">
153+
154+
{error && <div className="alert alert-danger">{error}</div>}
155+
156+
{isLoading ? (
157+
<div className="d-flex justify-content-center mt-4"></div>
158+
) : displayedEvents.length > 0 ? (
159+
<Row>
160+
{displayedEvents.map(event => (
161+
<Col md={4} key={event._id || event.id} className="event-card-col">
162+
<Card
163+
className="event-card"
164+
style={{
165+
display: 'flex',
166+
flexDirection: 'column',
167+
borderRadius: 14,
168+
overflow: 'hidden',
169+
}}
170+
>
118171
<div className="event-card-img-container">
119-
<img src={event.image} alt={event.title} className="event-card-img" />
172+
<FixedRatioImage
173+
src={event.coverImage}
174+
alt={event.title}
175+
fallback={FALLBACK_IMG}
176+
/>
120177
</div>
121-
<CardBody>
178+
<CardBody style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
122179
<h5 className="event-title">{event.title}</h5>
123180
<p className="event-date">
124-
<FaCalendarAlt className="event-icon" /> {event.date}
181+
<FaCalendarAlt className="event-icon" /> {formatDate(event.date)}
125182
</p>
126183
<p className="event-location">
127-
<FaMapMarkerAlt className="event-icon" /> {event.location}
184+
<FaMapMarkerAlt className="event-icon" /> {event.location || 'TBD'}
128185
</p>
129186
<p className="event-organizer">
130-
<FaUserAlt className="event-icon" /> {event.organizer}
187+
<FaUserAlt className="event-icon" /> {event.maxAttendees || 'No limit'}{' '}
188+
Attendees limit
131189
</p>
132190
</CardBody>
133191
</Card>
134192
</Col>
135-
))
136-
) : (
137-
<div className="no-events">No events available</div>
138-
)}
139-
</Row>
140-
<div className="dashboard-actions">
193+
))}
194+
</Row>
195+
) : (
196+
<div className="no-events">No events available</div>
197+
)}
198+
199+
<div className="d-flex justify-content-center mt-4">
200+
<div className="pagination-controls">
201+
<Button
202+
color="secondary"
203+
disabled={pagination.currentPage === 1}
204+
onClick={() =>
205+
setPagination(prev => ({ ...prev, currentPage: prev.currentPage - 1 }))
206+
}
207+
>
208+
Previous
209+
</Button>
210+
211+
<span className="mx-3">
212+
Page {pagination.currentPage} of {totalPages}
213+
</span>
214+
215+
<Button
216+
color="secondary"
217+
disabled={pagination.currentPage === totalPages}
218+
onClick={() =>
219+
setPagination(prev => ({ ...prev, currentPage: prev.currentPage + 1 }))
220+
}
221+
>
222+
Next
223+
</Button>
224+
</div>
225+
</div>
226+
227+
<div className="dashboard-actions text-center mt-4">
141228
<Button color="primary">Show Past Events</Button>
142229
</div>
143230
</Col>

0 commit comments

Comments
 (0)