Skip to content

Commit 5bdbdd1

Browse files
Merge pull request #3133 from OneCommunityGlobal/nishita_insights_for_event_personalization
Nishita_Create_Insights_for_Event_Personalization
2 parents a8eb2a0 + f5af14a commit 5bdbdd1

3 files changed

Lines changed: 398 additions & 0 deletions

File tree

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
.popular-events-container {
2+
3+
max-height: 100%;
4+
margin: 0 auto;
5+
padding: 20px;
6+
font-family: Arial, sans-serif;
7+
background: white;
8+
}
9+
10+
.popular-events-container-dark {
11+
12+
margin: 0 auto;
13+
padding: 20px;
14+
font-family: Arial, sans-serif;
15+
background: #1B2A41;
16+
min-height: 100%;
17+
}
18+
19+
.header-container {
20+
display: flex;
21+
justify-content: space-between;
22+
align-items: center;
23+
}
24+
25+
.header-container-dark {
26+
display: flex;
27+
justify-content: space-between;
28+
align-items: center;
29+
color: #1C2541;
30+
}
31+
32+
.popular-events-header {
33+
font-size: 1.5rem;
34+
color: #000000;
35+
margin: 0;
36+
}
37+
38+
.popular-events-header-dark {
39+
font-size: 1.5rem;
40+
color: #ffffff;
41+
margin: 0;
42+
background-color: #1C2541;
43+
}
44+
45+
.filters {
46+
display: flex;
47+
gap: 10px;
48+
}
49+
50+
.filters-dark {
51+
display: flex;
52+
gap: 10px;
53+
background-color: #1C2541;
54+
}
55+
56+
.filters select {
57+
padding: 6px;
58+
font-size: 14px;
59+
border: 1px solid #ccc;
60+
border-radius: 5px;
61+
cursor: pointer;
62+
}
63+
64+
.stats {
65+
display: flex;
66+
flex-direction: column;
67+
gap: 20px;
68+
border-radius: 8px;
69+
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
70+
padding: 30px;
71+
}
72+
73+
.stats-dark {
74+
display: flex;
75+
flex-direction: column;
76+
gap: 20px;
77+
border-radius: 8px;
78+
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
79+
padding: 30px;
80+
background-color: #1C2541;
81+
}
82+
83+
.stat-item {
84+
display: flex;
85+
align-items: center;
86+
justify-content: space-between;
87+
}
88+
89+
90+
91+
.stat-label {
92+
flex: 1;
93+
font-size: 14px;
94+
font-weight: bold;
95+
color: #333;
96+
}
97+
98+
.stat-label-dark {
99+
flex: 1;
100+
font-size: 14px;
101+
font-weight: bold;
102+
color: #ffffff;
103+
}
104+
105+
.stat-bar {
106+
flex: 3;
107+
background: #f0f0f0;
108+
height: 8px;
109+
border-radius: 5px;
110+
margin: 0 10px;
111+
position: relative;
112+
overflow: hidden;
113+
}
114+
115+
.bar {
116+
height: 100%;
117+
border-radius: 5px;
118+
transition: width 0.5s ease-in-out;
119+
}
120+
121+
.bar.green {
122+
background-color: #4caf50;
123+
}
124+
125+
.bar.orange {
126+
background-color: #ff9800;
127+
}
128+
129+
.bar.red {
130+
background-color: #f44336;
131+
}
132+
133+
.stat-value {
134+
flex: 1;
135+
text-align: right;
136+
font-size: 14px;
137+
font-weight: bold;
138+
color: #333;
139+
}
140+
141+
.stat-value-dark {
142+
flex: 1;
143+
text-align: right;
144+
font-size: 14px;
145+
font-weight: bold;
146+
color: #ffffff;
147+
}
148+
149+
.summary {
150+
display: grid;
151+
grid-template-columns: repeat(4, 1fr);
152+
gap: 10px;
153+
max-height: 80px;
154+
margin-top: 20px;
155+
border-radius: 8px;
156+
text-align: center;
157+
padding-bottom: 20px;
158+
}
159+
160+
.summary-item {
161+
background: white;
162+
padding: 12px;
163+
border-radius: 8px;
164+
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
165+
display: flex;
166+
flex-direction: column;
167+
justify-content: center;
168+
align-items: center;
169+
max-height: 90px;
170+
min-height: 80px;
171+
overflow: hidden;
172+
text-align: center;
173+
}
174+
175+
.summary-item-dark {
176+
background: #3A506B;
177+
padding: 12px;
178+
border-radius: 8px;
179+
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
180+
display: flex;
181+
flex-direction: column;
182+
justify-content: center;
183+
align-items: center;
184+
max-height: 90px;
185+
min-height: 80px;
186+
overflow: hidden;
187+
text-align: center;
188+
}
189+
190+
.summary-title {
191+
font-size: 14px;
192+
font-weight: bold;
193+
text-align: center;
194+
white-space: normal;
195+
word-wrap: break-word;
196+
max-width: 90%;
197+
color: #777;
198+
}
199+
200+
.summary-title-dark {
201+
font-size: 14px;
202+
font-weight: bold;
203+
text-align: center;
204+
white-space: normal;
205+
word-wrap: break-word;
206+
max-width: 90%;
207+
color: #ffffff;
208+
}
209+
210+
.summary-value {
211+
font-size: 14px;
212+
font-weight: bold;
213+
color: #000;
214+
margin-top: 4px;
215+
}
216+
217+
.summary-value-dark {
218+
font-size: 14px;
219+
font-weight: bold;
220+
color: #ffffff;
221+
margin-top: 4px;
222+
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import { useState } from 'react';
2+
import './EventStats.css';
3+
import { useSelector } from 'react-redux';
4+
5+
const dummyData = [
6+
{
7+
id: 1,
8+
type: 'Type of Event 1',
9+
attended: 20,
10+
enrolled: 25,
11+
time: 'Morning',
12+
location: 'Offline',
13+
},
14+
{
15+
id: 2,
16+
type: 'Type of Event 2',
17+
attended: 19,
18+
enrolled: 20,
19+
time: 'Afternoon',
20+
location: 'Online',
21+
},
22+
{
23+
id: 3,
24+
type: 'Type of Event 3',
25+
attended: 12,
26+
enrolled: 18,
27+
time: 'Night',
28+
location: 'Offline',
29+
},
30+
{
31+
id: 4,
32+
type: 'Type of Event 4',
33+
attended: 11,
34+
enrolled: 20,
35+
time: 'Morning',
36+
location: 'Online',
37+
},
38+
{
39+
id: 5,
40+
type: 'Type of Event 5',
41+
attended: 8,
42+
enrolled: 20,
43+
time: 'Afternoon',
44+
location: 'Offline',
45+
},
46+
{ id: 6, type: 'Type of Event 6', attended: 7, enrolled: 22, time: 'Night', location: 'Offline' },
47+
{
48+
id: 7,
49+
type: 'Type of Event 7',
50+
attended: 4,
51+
enrolled: 20,
52+
time: 'Morning',
53+
location: 'Online',
54+
},
55+
];
56+
57+
export default function PopularEvents() {
58+
const [timeFilter, setTimeFilter] = useState('All day');
59+
const [typeFilter, setTypeFilter] = useState('All');
60+
61+
const calculatePercentage = (attended, enrolled) => Math.round((attended / enrolled) * 100);
62+
63+
const getBarColor = percentage => {
64+
if (percentage > 60) return 'green';
65+
if (percentage > 40) return 'orange';
66+
return 'red';
67+
};
68+
69+
const filteredData = dummyData.filter(event => {
70+
const timeMatch = timeFilter === 'All day' || event.time === timeFilter;
71+
const typeMatch = typeFilter === 'All' || event.location === typeFilter;
72+
return timeMatch && typeMatch;
73+
});
74+
75+
const mostPopularEvent = filteredData.reduce(
76+
(max, event) =>
77+
calculatePercentage(event.attended, event.enrolled) >
78+
calculatePercentage(max.attended, max.enrolled)
79+
? event
80+
: max,
81+
filteredData[0] || {},
82+
);
83+
84+
const leastPopularEvent = filteredData.reduce(
85+
(min, event) =>
86+
calculatePercentage(event.attended, event.enrolled) <
87+
calculatePercentage(min.attended, min.enrolled)
88+
? event
89+
: min,
90+
filteredData[0] || {},
91+
);
92+
const darkMode = useSelector(state => state.theme.darkMode);
93+
return (
94+
<div className={`popular-events-container ${darkMode ? 'popular-events-container-dark' : ''}`}>
95+
<div className={`header-container ${darkMode ? 'header-container-dark' : ''}`}>
96+
<h2 className={`popular-events-header ${darkMode ? 'popular-events-header-dark' : ''}`}>
97+
Most Popular Event
98+
</h2>
99+
<div className={`filters ${darkMode ? 'filters-dark' : ''}`}>
100+
<select value={timeFilter} onChange={e => setTimeFilter(e.target.value)}>
101+
<option value="All day">All day</option>
102+
<option value="Morning">Morning</option>
103+
<option value="Afternoon">Afternoon</option>
104+
<option value="Night">Night</option>
105+
</select>
106+
<select value={typeFilter} onChange={e => setTypeFilter(e.target.value)}>
107+
<option value="All">All</option>
108+
<option value="Offline">Offline</option>
109+
<option value="Online">Online</option>
110+
</select>
111+
</div>
112+
</div>
113+
114+
<div className={`stats ${darkMode ? 'stats-dark' : ''}`}>
115+
{filteredData.map(event => (
116+
<div key={event.id} className="stat-item">
117+
<div className={`stat-label ${darkMode ? 'stat-label-dark' : ''}`}>{event.type}</div>
118+
<div className="stat-bar">
119+
<div
120+
className={`bar ${getBarColor(
121+
calculatePercentage(event.attended, event.enrolled),
122+
)}`}
123+
style={{ width: `${calculatePercentage(event.attended, event.enrolled)}%` }}
124+
/>
125+
</div>
126+
<div className={`stat-value ${darkMode ? 'stat-value-dark' : ''}`}>
127+
{`${calculatePercentage(event.attended, event.enrolled)}% (${event.attended}/${
128+
event.enrolled
129+
})`}
130+
</div>
131+
</div>
132+
))}
133+
</div>
134+
<div className="summary">
135+
<div className={`summary-item ${darkMode ? 'summary-item-dark' : ''}`}>
136+
<div className={`summary-title ${darkMode ? 'summary-title-dark' : ''}`}>
137+
Total Number of Events
138+
</div>
139+
<div className={`summary-value ${darkMode ? 'summary-value-dark' : ''}`}>
140+
{filteredData.length}
141+
</div>
142+
</div>
143+
<div className={`summary-item ${darkMode ? 'summary-item-dark' : ''}`}>
144+
<div className={`summary-title ${darkMode ? 'summary-title-dark' : ''}`}>
145+
Total Number of Event Enrollments
146+
</div>
147+
<div className={`summary-value ${darkMode ? 'summary-value-dark' : ''}`}>
148+
{filteredData.reduce((acc, event) => acc + event.enrolled, 0)}
149+
</div>
150+
</div>
151+
{filteredData.length > 0 && (
152+
<>
153+
<div className={`summary-item ${darkMode ? 'summary-item-dark' : ''}`}>
154+
<div className={`summary-title ${darkMode ? 'summary-title-dark' : ''}`}>
155+
Most Popular Event
156+
</div>
157+
<div className={`summary-value ${darkMode ? 'summary-value-dark' : ''}`}>
158+
{mostPopularEvent.type || 'N/A'}
159+
</div>
160+
</div>
161+
<div className={`summary-item ${darkMode ? 'summary-item-dark' : ''}`}>
162+
<div className={`summary-title ${darkMode ? 'summary-title-dark' : ''}`}>
163+
Least Popular Event
164+
</div>
165+
<div className={`summary-value ${darkMode ? 'summary-value-dark' : ''}`}>
166+
{leastPopularEvent.type || 'N/A'}
167+
</div>
168+
</div>
169+
</>
170+
)}
171+
</div>
172+
</div>
173+
);
174+
}

0 commit comments

Comments
 (0)