diff --git a/src/components/CommunityPortal/Activities/activityId/Activity.jsx b/src/components/CommunityPortal/Activities/activityId/Activity.jsx deleted file mode 100644 index 4105da0d45..0000000000 --- a/src/components/CommunityPortal/Activities/activityId/Activity.jsx +++ /dev/null @@ -1,251 +0,0 @@ -import { useEffect, useState } from 'react'; -import CommentSection from './CommentSection/CommentSection'; -import './Activity.module.css'; - -const data = { - eventName: 'Event Name', - eventType: 'Event or Course', - eventLocation: 'San Francisco, CA 94108', - eventLink: 'https://devforum.zoom.us', - eventDate: 'Monday, Sept 2', - eventTime: '9:00 AM - 11:00 AM', - eventOrganizer: 'Alex Brain', - eventCapacity: '7/20', - eventRating: 4, - eventStatus: 'Activated', - eventStatusClass: 'status-active', - eventDescription: - 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', - eventParticipates: [{ name: 'Summer' }, { name: 'Jimmy' }], - eventComments: [ - { - id: 1, - name: 'Summer', - comment: - 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', - time: '2 hours ago', - }, - { - id: 2, - name: 'Jason', - comment: - 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', - time: '2 hours ago', - }, - { - id: 3, - name: 'Jimmy', - comment: - 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', - time: '2 hours ago', - }, - ], - eventFAQs: [ - { id: 1, question: 'What is the event about?', answer: 'This is a sample answer to the FAQ.' }, - { id: 2, question: 'How do I register?', answer: 'This is a sample answer to the FAQ.' }, - ], -}; - -function Activity() { - const [tab, setTab] = useState('Description'); - const [event, setEvent] = useState(data); - - const handleTabClick = tabName => { - setTab(tabName); - }; - - useEffect(() => { - setEvent(data); - }, [data]); - - return ( -
-
-
-
Participated
-
-

{event.eventType}

-

{event.eventName}

-

{event.eventLocation}

- - {event.eventLink} - -
-
- Date -
- {event.eventDate} -
-
- Time -
- {event.eventTime} -
-
- Organizer -
- {event.eventOrganizer} -
-
- Capacity -
- {event.eventCapacity} -
-
- Overall Rating -
- {Array.from({ length: event.eventRating }, (_, i) => ( - - ★ - - ))} - {Array.from({ length: 5 - event.eventRating }, (_, i) => ( - - ☆ - - ))} -
-
- Status -
- {event.eventStatus} -
-
-
- - -
-
-
-
September 2024
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SMTWTFS
1234567
891011121314
15161718192021
22232425262728
2930
-
-
- -
- - - - -
- {tab === 'Description' && ( -
-

{event.eventDescription}

-
- )} - {tab === 'Participates' && ( -
- {event.eventParticipates.map(participant => ( -
- - {participant.name[0]} - -
{participant.name}
-
- ))} -
- )} - {tab === 'FAQs' && ( -
- {event.eventFAQs.map(faq => ( -
-

{faq.question}

-

{faq.answer}

-
- ))} -
- )} - {tab === 'Comments' && } -
-
- ); -} - -export default Activity; diff --git a/src/components/CommunityPortal/Activities/activityId/Activity.module.css b/src/components/CommunityPortal/Activities/activityId/Activity.module.css deleted file mode 100644 index 41e243e92b..0000000000 --- a/src/components/CommunityPortal/Activities/activityId/Activity.module.css +++ /dev/null @@ -1,266 +0,0 @@ -.activity-container { - display: flex; - flex-direction: column; - align-items: center; - padding: 20px; - background-color: #f9f9f9; -} - -.activity-event-card { - border: 1px solid #ccc; - border-radius: 10px; - padding: 16px; - font-family: Arial, sans-serif; - background-color: #fff; - max-width: 1100px; -} - -.activity-event-header { - display: flex; - gap: 20px; -} - -.activity-event-image { - width: 180px; - height: 180px; - background-color: #e0e0e0; - text-align: center; - line-height: 180px; - font-weight: bold; - color: #555; -} - -.activity-event-details { - flex-grow: 2; -} - -.activity-event-type { - font-size: 12px; - color: gray; -} - -.activity-event-title { - margin: 5px 0; -} - -.activity-event-location { - font-size: 14px; -} - -.activity-event-link { - color: #1a73e8; - text-decoration: none; -} - -.activity-event-info { - display: flex; - flex-wrap: wrap; - gap: 20px; - margin-top: 10px; -} - -.activity-event-info > div { - min-width: 120px; -} - -.activity-capacity { - color: red; -} - -.activity-status-active { - color: green; - font-weight: bold; -} - -.activity-event-buttons { - margin-top: 10px; -} - -.feedback-btn, -.contact-btn { - padding: 5px 12px; - margin-right: 10px; - border: none; - border-radius: 4px; - background-color: #dedede; - cursor: pointer; -} - -.activity-calendar-box { - min-width: 220px; - text-align: center; -} - -.activity-calendar-header { - font-weight: bold; - margin-bottom: 5px; -} - -.activity-calendar-table { - width: 100%; - border-collapse: collapse; -} - -.activity-calendar-table th, -.activity-calendar-table td { - width: 14.2%; - padding: 4px; - border: 1px solid #ddd; -} - -.activity-active-date { - background-color: #f48fb1; - border-radius: 50%; -} - -.activity-event-tabs { - display: flex; - gap: 20px; - border-top: 1px solid #ddd; - margin-top: 20px; - padding-top: 10px; -} - -.activity-tab { - padding: 6px 12px; - cursor: pointer; -} - -.activity-tab.active { - border-bottom: 2px solid #000; - font-weight: bold; -} - -.activity-participates-section { - margin-top: 20px; - display: flex; - flex-direction: row; - gap: 20px; -} - -.activity-participant { - display: flex; - gap: 5px; -} - -.activity-faqs-section { - margin-top: 20px; -} - -.activity-faq p { - color: #555; -} - -.activity-faq h3 { - color: #000; -} - -.activity-icon { - width: 30px; - height: 30px; - border-radius: 50%; - color: #fff; - text-align: center; - line-height: 30px; - font-weight: bold; -} - -.purple { - background-color: purple; -} - -.blue { - background-color: #3366ff; -} - -@media (max-width: 800px) { - .activity-event-card { - max-width: 98vw; - padding: 8px; - } - - .activity-event-header { - flex-direction: column; - gap: 10px; - align-items: stretch; - } - - .activity-event-image { - width: 120px; - height: 160px; - line-height: 120px; - font-size: 18px; - margin: 10px auto; - } - - .activity-calendar-box { - min-width: unset; - width: 100%; - margin-top: 10px; - } - - .activity-event-details { - width: 100%; - } - - .activity-event-info { - flex-direction: column; - gap: 8px; - } - - .activity-event-tabs { - justify-content: center; - gap: 10px; - flex-wrap: wrap; - font-size: 15px; - } - - .activity-participates-section { - flex-direction: column; - gap: 10px; - } -} - -@media (max-width: 500px) { - .activity-event-card { - padding: 4px; - font-size: 14px; - } - - .activity-event-title { - font-size: 18px; - } - - .activity-event-image { - height: 180px; - line-height: 80px; - font-size: 15px; - } - - .activity-calendar-header { - font-size: 14px; - } - - .activity-calendar-table th, - .activity-calendar-table td { - padding: 2px; - font-size: 12px; - } - - .activity-icon { - width: 24px; - height: 24px; - line-height: 24px; - font-size: 13px; - } - - .activity-event-tabs { - font-size: 13px; - justify-content: space-evenly; - gap: 0; - } - - .activity-tab { - padding: 6px 6px; - } -} diff --git a/src/components/CommunityPortal/Activities/activityId/ActivityFeedback.jsx b/src/components/CommunityPortal/Activities/activityId/ActivityFeedback.jsx new file mode 100644 index 0000000000..dd8024e0b3 --- /dev/null +++ b/src/components/CommunityPortal/Activities/activityId/ActivityFeedback.jsx @@ -0,0 +1,308 @@ +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; +import CommentSection from './CommentSection/CommentSection'; +import Switch from '@mui/material/Switch'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Typography from '@mui/material/Typography'; +import Feedback from './FeedBackSection/Feedback'; +import { feedbackData } from './FeedbackData'; +import styles from './ActivityFeedback.module.css'; + +const data = { + eventName: 'Event Name', + eventType: 'Event or Course', + eventLocation: 'San Francisco, CA 94108', + eventLink: 'https://devforum.zoom.us', + eventDate: 'Monday, Sept 2', + eventTime: '9:00 AM - 11:00 AM', + eventOrganizer: 'Alex Brain', + eventCapacity: '7/20', + eventRating: 4, + eventStatus: 'Activated', + createdAt: '2025-09-20', + eventDescription: + 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', + eventParticipates: [{ name: 'Summer' }, { name: 'Jimmy' }], + eventComments: [ + { + id: 1, + name: 'Summer', + comment: + 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', + time: '2 hours ago', + }, + { + id: 2, + name: 'Jason', + comment: + 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', + time: '2 hours ago', + }, + { + id: 3, + name: 'Jimmy', + comment: + 'this is activity comments. this is activity comments. this is activity comments. this is activity comments. this is activity comments.', + time: '2 hours ago', + }, + ], + eventFAQs: [ + { id: 1, question: 'What is the event about?', answer: 'This is a sample answer to the FAQ.' }, + { id: 2, question: 'How do I register?', answer: 'This is a sample answer to the FAQ.' }, + ], +}; + +const getAvatarColorClass = (name = '', index = 0, stylesRef) => { + let hash = 0; + for (let i = 0; i < name.length; i += 1) { + hash = (hash << 5) - hash + name.charCodeAt(i); + hash |= 0; + } + const isPurple = (hash + index) % 2 === 0; + return isPurple ? stylesRef.purple : stylesRef.blue; +}; + +function ActivityFeedback() { + const darkMode = useSelector(state => state.theme?.darkMode); + const [tab, setTab] = useState('Feedback'); + const [event, setEvent] = useState(data); + const [viewSelected, setViewSelected] = useState('Host'); + const [reviewsChecked, setReviewsChecked] = useState(true); + const [suggestionChecked, setSuggestionChecked] = useState(false); + const [feedbackList, setFeedbackList] = useState(feedbackData); + const [showFeedbackModal, setShowFeedbackModal] = useState(false); + const views = ['Host', 'Participant']; + + useEffect(() => { + setEvent(data); + }, []); + + return ( +
+
+
+
+
Participated
+ +
+
+
+

{event.eventType}

+

{event.eventName}

+

{event.eventLocation}

+ + {event.eventLink} + +
+ +
+ {views.map(sec => ( + + ))} +
+
+ +
+
+ Date +
+ {event.eventDate} +
+
+ Time +
+ {event.eventTime} +
+
+ Organizer +
+ {event.eventOrganizer} +
+
+ Capacity +
+ {event.eventCapacity} +
+
+ Overall Rating +
+ {Array.from({ length: event.eventRating }, (_, i) => ( + + ★ + + ))} + {Array.from({ length: 5 - event.eventRating }, (_, i) => ( + + ☆ + + ))} +
+
+ Status +
+ {event.eventStatus} +
+ + {viewSelected === 'Host' && ( +
+ setReviewsChecked(e.target.checked)} + color="primary" + /> + } + label={ + Allow Reviews + } + /> +
+ setSuggestionChecked(e.target.checked)} + color="primary" + /> + } + label={ + + Suggestions Only + + } + /> +
+ )} +
+ + {viewSelected !== 'Host' && ( +
+ +
+ )} +
+ +
+
September 2024
+ + + + {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map(day => ( + + ))} + + + + {[0, 1, 2, 3, 4].map(row => ( + + {Array.from({ length: 7 }).map((_, col) => { + const day = row * 7 + col + 1; + return ( + + ); + })} + + ))} + +
{day}
+ {day <= 31 ? day : ''} +
+
+
+ +
+ {['Description', 'Participates', 'Comments', 'FAQs', 'Feedback'].map(name => ( + + ))} +
+ + {tab === 'Description' && ( +
+

{event.eventDescription}

+
+ )} + + {tab === 'Participates' && ( +
+ {event.eventParticipates.map((p, i) => ( +
+ + {p.name[0]} + +
{p.name}
+
+ ))} +
+ )} + + {tab === 'FAQs' && ( +
+ {event.eventFAQs.map(faq => ( +
+

{faq.question}

+

{faq.answer}

+
+ ))} +
+ )} + + {tab === 'Comments' && ( + + )} + + {tab === 'Feedback' && viewSelected === 'Host' && ( + + )} + + {tab === 'Feedback' && viewSelected !== 'Host' && ( + + )} +
+
+
+ ); +} + +export default ActivityFeedback; diff --git a/src/components/CommunityPortal/Activities/activityId/ActivityFeedback.module.css b/src/components/CommunityPortal/Activities/activityId/ActivityFeedback.module.css new file mode 100644 index 0000000000..790cb9f15f --- /dev/null +++ b/src/components/CommunityPortal/Activities/activityId/ActivityFeedback.module.css @@ -0,0 +1,541 @@ +.activityContainer { + display: flex; + flex-direction: column; + align-items: center; + padding: 20px; + background-color: #f3f5f9; + color: #0f172a; + min-height: 100vh; + box-sizing: border-box; + transition: background-color 0.3s ease, color 0.3s ease; +} + +.activityEventCard { + border: 1px solid #e2e8f0; + border-radius: 16px; + padding: 20px; + font-family: Arial, sans-serif; + background-color: #ffffff; + max-width: 1100px; + width: 100%; + box-shadow: 0 14px 30px rgba(15, 23, 42, 0.08); + transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; +} + +.activityEventHeader { + display: flex; + gap: 20px; + align-items: flex-start; +} + +.titlesAndViews { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + gap: 20px; +} + +.titles { + display: flex; + flex-direction: column; + gap: 4px; +} + +.viewToggler { + padding: 12px 0; + display: flex; + gap: 10px; +} + +.activityEventImage { + width: 180px; + height: 180px; + background: linear-gradient(145deg, #e2e8f0, #f8fafc); + text-align: center; + line-height: 180px; + font-weight: bold; + color: #475569; + border-radius: 12px; + border: 1px solid #e2e8f0; +} + +.activityEventDetails { + flex-grow: 2; +} + +.activityEventType { + font-size: 12px; + color: #64748b; + text-transform: uppercase; + letter-spacing: 0.6px; +} + +.activityEventTitle { + margin: 2px 0 0; + font-size: 24px; + color: #0f172a; +} + +.activityEventLocation { + font-size: 14px; + color: #475569; +} + +.activityEventLink { + color: #1d4ed8; + text-decoration: none; + font-size: 14px; +} + +.activityEventLink:hover { + text-decoration: underline; +} + +.activityEventInfo { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 14px; + color: #1e293b; +} + +.activityEventInfo > div { + min-width: 120px; +} + +.activityEventInfo strong { + color: #0f172a; +} + +.activityCapacity { + color: #dc2626; + font-weight: 600; +} + +.activityStatusActive { + color: #16a34a; + font-weight: 700; +} + +.activityStar { + color: #f7c948; + margin-right: 2px; +} + +.activityStarEmpty { + color: #cbd5e1; + margin-right: 2px; +} + +.switchToggle { + color: #0f172a; + font-weight: 600; +} + +.activityEventButtons { + margin-top: 12px; +} + +.contactBtn { + padding: 8px 14px; + margin-right: 10px; + border: 1px solid #cbd5e1; + border-radius: 999px; + background-color: #f1f5f9; + color: #1e293b; + cursor: pointer; + transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease; +} + +.contactBtn:hover { + background-color: #e2e8f0; + border-color: #b8c9e3; + color: #1e3a8a; +} + +.activityCalendarBox { + min-width: 220px; + text-align: center; + background: #f8fafc; + border-radius: 12px; + border: 1px solid #e2e8f0; + padding: 10px 12px; +} + +.activityCalendarHeader { + font-weight: 700; + margin-bottom: 6px; + color: #1e293b; +} + +.activityCalendarTable { + width: 100%; + border-collapse: collapse; + font-size: 12px; +} + +.activityCalendarTable th, +.activityCalendarTable td { + width: 14.2%; + padding: 4px; + border: 1px solid #e2e8f0; + color: #475569; +} + +.activityCalendarTable td:hover { + background: #eef2f7; + color: #1e3a8a; +} + +.activityCalendarTable th { + background: #eef2f7; + font-weight: 600; +} + +.activityActiveDate { + background-color: #f472b6; + border-radius: 50%; + color: #ffffff; + font-weight: 700; +} + +.activityEventTabs { + display: flex; + gap: 16px; + border-top: 1px solid #e2e8f0; + margin-top: 20px; + padding-top: 12px; +} + +.activityTab { + padding: 6px 12px; + cursor: pointer; + border: 1px solid transparent; + border-radius: 999px; + background: transparent; + color: #475569; + transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease; +} + +.activityTab:hover { + color: #1e3a8a; + background: #f1f5f9; + border-color: #c7d6ea; +} + +.activityTabActive { + border-bottom: 2px solid #1e3a8a; + font-weight: 700; + color: #1e3a8a; + border-radius: 0; + padding-bottom: 8px; +} + +.active { + background: #f1f5f9; + border-color: #c7d6ea; + color: #1e3a8a; + box-shadow: 0 6px 12px rgba(30, 58, 138, 0.12); +} + +.activityParticipatesSection { + margin-top: 20px; + display: flex; + flex-direction: row; + gap: 20px; +} + +.activityParticipant { + display: flex; + align-items: center; + gap: 8px; + color: #1e293b; +} + +.activityFaqsSection { + margin-top: 20px; + display: flex; + flex-direction: column; + gap: 12px; +} + +.activityFaq { + padding: 12px 14px; + border-radius: 12px; + border: 1px solid #e2e8f0; + background: #f8fafc; +} + +.activityFaqTitle { + color: #0f172a; + margin: 0 0 6px; +} + +.activityFaqText { + color: #475569; + margin: 0; +} + +.activityEventDescription p { + color: #1e293b; + padding: 10px 0; + line-height: 1.6; +} + +.activityIcon { + width: 30px; + height: 30px; + border-radius: 50%; + color: #fff; + text-align: center; + line-height: 30px; + font-weight: bold; +} + +.purple { + background-color: #7c3aed; +} + +.blue { + background-color: #2563eb; +} + +@media (max-width: 800px) { + .activityEventCard { + max-width: 98vw; + padding: 12px; + } + + .activityEventHeader { + flex-direction: column; + gap: 12px; + align-items: stretch; + } + + .titlesAndViews { + flex-direction: column; + align-items: flex-start; + } + + .activityEventImage { + width: 120px; + height: 160px; + line-height: 120px; + font-size: 18px; + margin: 10px 0; + } + + .activityCalendarBox { + min-width: unset; + width: 100%; + margin-top: 10px; + } + + .activityEventDetails { + width: 100%; + } + + .activityEventInfo { + flex-direction: column; + gap: 8px; + } + + .activityEventTabs { + justify-content: center; + gap: 10px; + flex-wrap: wrap; + font-size: 15px; + } + + .activityParticipatesSection { + flex-direction: column; + gap: 10px; + } +} + +@media (max-width: 500px) { + .activityEventCard { + padding: 8px; + font-size: 14px; + } + + .activityEventTitle { + font-size: 18px; + } + + .activityEventImage { + height: 180px; + line-height: 80px; + font-size: 15px; + } + + .activityCalendarHeader { + font-size: 14px; + } + + .activityCalendarTable th, + .activityCalendarTable td { + padding: 2px; + font-size: 12px; + } + + .activityIcon { + width: 24px; + height: 24px; + line-height: 24px; + font-size: 13px; + } + + .activityEventTabs { + font-size: 13px; + justify-content: space-evenly; + gap: 0; + } + + .activityTab { + padding: 6px 6px; + } +} + +.darkMode .activityContainer { + background-color: #1b2a41; + color: #e2e8f0; +} + +.darkMode { + background-color: #1b2a41; + min-height: 100vh; +} + +.darkMode .activityEventCard { + border: 1px solid #2f425d; + background-color: #1f3048; + box-shadow: 0 18px 40px rgba(2, 8, 18, 0.5); +} + +.darkMode .activityEventImage { + background: linear-gradient(145deg, #243853, #2b3f5d); + color: #cbd5e1; + border-color: #2f425d; +} + +.darkMode .activityEventType { + color: #cbd5e1; +} + +.darkMode .activityEventTitle { + color: #f8fafc; +} + +.darkMode .activityEventLocation { + color: #e2e8f0; +} + +.darkMode .activityEventLink { + color: #93c5fd; +} + +.darkMode .activityEventInfo { + color: #e2e8f0; +} + +.darkMode .activityEventInfo strong { + color: #f8fafc; +} + +.darkMode .switchToggle { + color: #e2e8f0; +} + +.darkMode .contactBtn { + background-color: #243853; + border-color: #4b637f; + color: #e2e8f0; +} + +.darkMode .contactBtn:hover { + background-color: #2c4463; + border-color: #5a7698; + color: #f8fafc; +} + +.darkMode .activityCalendarBox { + background: #243853; + border-color: #2f425d; +} + +.darkMode .activityCalendarHeader { + color: #f8fafc; +} + +.darkMode .activityCalendarTable th, +.darkMode .activityCalendarTable td { + border-color: #2f425d; + color: #cbd5e1; +} + +.darkMode .activityCalendarTable th { + background: #1f2f48; +} + +.darkMode .activityCalendarTable td:hover { + background: #2c4463; + color: #f8fafc; +} + +.darkMode .activityActiveDate { + background-color: #f472b6; + color: #0b1220; +} + +.darkMode .activityEventTabs { + border-top-color: #2f425d; +} + +.darkMode .activityTab { + color: #cbd5e1; +} + +.darkMode .activityTab:hover { + color: #f8fafc; + background: #243853; + border-color: #4b637f; +} + +.darkMode .activityTabActive { + border-bottom-color: #93c5fd; + color: #93c5fd; +} + +.darkMode .active { + background: #243853; + border-color: #4b637f; + color: #f8fafc; + box-shadow: 0 10px 18px rgba(8, 18, 32, 0.35); +} + +.darkMode .activityParticipatesSection { + color: #e2e8f0; +} + +.darkMode .activityParticipant { + color: #e2e8f0; +} + +.darkMode .activityFaq { + background: #243853; + border-color: #2f425d; +} + +.darkMode .activityFaqTitle { + color: #f8fafc; +} + +.darkMode .activityFaqText { + color: #cbd5e1; +} + +.darkMode .activityEventDescription p { + color: #e2e8f0; +} diff --git a/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.css b/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.css deleted file mode 100644 index de162d7a3f..0000000000 --- a/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.css +++ /dev/null @@ -1,60 +0,0 @@ -.activity-comment-text { - flex: 1; - background-color: #f4f4f4; - padding: 10px; - border-radius: 6px; -} - -.activity-comment-footer { - font-size: 12px; - color: gray; - margin-top: 5px; -} - -.activity-comment { - display: flex; - align-items: flex-start; - gap: 10px; -} - -.activity-comments-section { - margin-top: 20px; - display: flex; - flex-direction: column; - gap: 20px; -} - -.activity-comment-user { - display: flex; - gap: 5px; -} - -.activity-icon { - width: 30px; - height: 30px; - border-radius: 50%; - color: #fff; - text-align: center; - line-height: 30px; - font-weight: bold; -} - -.purple { - background-color: purple; -} - -.blue { - background-color: #3366ff; -} - -@media (max-width: 800px) { - .activity-comment { - flex-direction: column; - gap: 5px; - } - - .activity-comments-section { - gap: 10px; - padding: 15px; - } -} diff --git a/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.jsx b/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.jsx index d5b46c6e76..96feab65de 100644 --- a/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.jsx +++ b/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.jsx @@ -1,19 +1,37 @@ -import './CommentSection.css'; +import styles from './CommentSection.module.css'; +import { useSelector } from 'react-redux'; + +const getAvatarColorClass = (name = '', index = 0, stylesRef) => { + let hash = 0; + for (let i = 0; i < name.length; i += 1) { + hash = (hash << 5) - hash + name.charCodeAt(i); + hash |= 0; + } + const isPurple = (hash + index) % 2 === 0; + return isPurple ? stylesRef.purple : stylesRef.blue; +}; function CommentSection({ comments }) { + const darkMode = useSelector(state => state.theme?.darkMode); return ( -
-
- {comments.map(comment => ( -
-
- +
+
+ {comments.map((comment, index) => ( +
+
+ {comment.name[0]}
-
+
{comment.comment} -
+
{comment.name} - {comment.time}
diff --git a/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.module.css b/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.module.css new file mode 100644 index 0000000000..a31272b58d --- /dev/null +++ b/src/components/CommunityPortal/Activities/activityId/CommentSection/CommentSection.module.css @@ -0,0 +1,86 @@ +.activityCommentFooter { + font-size: 12px; + color: gray; + margin-top: 5px; + transition: color 0.3s ease; +} + +.activityComment { + display: flex; + align-items: flex-start; + gap: 10px; + transition: background-color 0.3s ease; +} + +.activityCommentsSection { + margin-top: 20px; + display: flex; + flex-direction: column; + gap: 20px; + transition: all 0.3s ease; +} + +.activityCommentUser { + display: flex; + gap: 5px; +} + +.activityCommentText { + flex: 1; + background-color: #f4f4f4; + padding: 10px; + border-radius: 6px; + transition: background-color 0.3s ease, color 0.3s ease; +} + +.activityIcon { + width: 30px; + height: 30px; + border-radius: 50%; + color: #fff; + text-align: center; + line-height: 30px; + font-weight: bold; + transition: transform 0.2s ease; +} + +.activityIcon:hover { + transform: scale(1.1); +} + +.purple { + background-color: purple; +} + +.blue { + background-color: #3366ff; +} + +@media (max-width: 800px) { + .activityComment { + flex-direction: column; + gap: 5px; + } + + .activityCommentsSection { + gap: 10px; + padding: 15px; + } +} + +.darkMode .activityCommentFooter { + color: #aaa; +} + +.darkMode .activityComment { + background-color: transparent; +} + +.darkMode .activityCommentsSection { + background-color: transparent; +} + +.darkMode .activityCommentText { + background-color: #3a506b; + color: #ffffff; +} diff --git a/src/components/CommunityPortal/Activities/activityId/FeedBackSection/Feedback.jsx b/src/components/CommunityPortal/Activities/activityId/FeedBackSection/Feedback.jsx new file mode 100644 index 0000000000..cad408e059 --- /dev/null +++ b/src/components/CommunityPortal/Activities/activityId/FeedBackSection/Feedback.jsx @@ -0,0 +1,405 @@ +import { useEffect, useMemo, useState } from 'react'; +import { useSelector } from 'react-redux'; +import styles from './Feedback.module.css'; +import { FaSearch } from 'react-icons/fa'; +import { MdArrowUpward, MdArrowDownward } from 'react-icons/md'; +import { AiFillStar, AiOutlineStar } from 'react-icons/ai'; +import FeedbackModal from './FeedbackModal'; + +const nowISO = () => new Date().toISOString(); + +function Feedback({ + reviewsEnabled = true, + suggestionsOnly = false, + isHost = false, + eventCreatedAt = null, + showModal = false, + setShowModal = null, + feedbackList, + setFeedbackList, +}) { + // local list (in real app you'd fetch) + const [searchTerm, setSearchTerm] = useState(''); + const [filterBy, setFilterBy] = useState('date'); + const [sortOrder, setSortOrder] = useState('desc'); + const [visibilityFilter, setVisibilityFilter] = useState('all'); + const [showSuggestionsOnly, setShowSuggestionsOnly] = useState(false); + + // modal form state (participant) + const [modalOpen, setModalOpen] = useState(showModal); + const [modalRating, setModalRating] = useState(0); + const [modalComment, setModalComment] = useState(''); + const [modalSuggestionText, setModalSuggestionText] = useState(''); + const [modalPrivate, setModalPrivate] = useState(false); + const [visibleCount, setVisibleCount] = useState(2); + + // reflect incoming modal prop + useEffect(() => { + if (typeof showModal === 'boolean') setModalOpen(showModal); + }, [showModal]); + + useEffect(() => { + // If parent gave setShowModal, keep synchronized + if (setShowModal) { + setShowModal(modalOpen); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [modalOpen]); + + useEffect(() => { + // Placeholder for API call to fetch feedback data + // For now we use dummyFeedback above. + }, []); + + // dark mode for styling + const darkMode = useSelector(state => state.theme?.darkMode); + + // helper: determine if event was created within one month + const eventWithinFirstMonth = useMemo(() => { + if (!eventCreatedAt) return false; + const created = new Date(eventCreatedAt); + const oneMonthLater = new Date(created); + oneMonthLater.setMonth(oneMonthLater.getMonth() + 1); + return new Date() <= oneMonthLater; + }, [eventCreatedAt]); + + const handleSearch = e => setSearchTerm(e.target.value); + const handleFilterChange = e => setFilterBy(e.target.value); + const handleSortChange = () => setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc'); + + const renderStars = feedback => + Array.from({ length: 5 }, (_, i) => ( + + {i < (feedback.rating || 0) ? : } + + )); + + // Filtering & sorting for host view + const filteredFeedback = feedbackList + .filter(fb => { + // visibility filter + if (visibilityFilter !== 'all' && fb.visibility !== visibilityFilter) return false; + // search match + const q = searchTerm.trim().toLowerCase(); + if (!q) return true; + return ( + (fb.comment || '').toLowerCase().includes(q) || + (fb.name || '').toLowerCase().includes(q) || + (fb.rating !== null && String(fb.rating).includes(q)) + ); + }) + .sort((a, b) => { + if (filterBy === 'date') { + return sortOrder === 'asc' + ? new Date(a.date) - new Date(b.date) + : new Date(b.date) - new Date(a.date); + } + if (filterBy === 'rating') { + return sortOrder === 'asc' + ? (a.rating || 0) - (b.rating || 0) + : (b.rating || 0) - (a.rating || 0); + } + return 0; + }); + + // Participant submit handlers (local only) + const handleSubmitFeedback = () => { + if (!reviewsEnabled && !suggestionsOnly) return; // can't submit + const isSuggestion = suggestionsOnly; + const visibility = eventWithinFirstMonth ? 'host-only' : modalPrivate ? 'host-only' : 'public'; + const newItem = { + id: feedbackList.length + 1, + name: 'You', + rating: isSuggestion ? null : modalRating, + comment: isSuggestion ? modalSuggestionText || modalComment : modalComment, + date: nowISO().slice(0, 10), + visibility: isSuggestion ? 'suggestion' : visibility, + }; + setFeedbackList(prev => [newItem, ...prev]); + // reset modal + setModalComment(''); + setModalSuggestionText(''); + setModalRating(5); + setModalPrivate(false); + setModalOpen(false); + if (setShowModal) setShowModal(false); + }; + + const handleOpenModal = () => { + setModalOpen(true); + if (setShowModal) setShowModal(true); + }; + + // Host-only and suggestion lists + const suggestionList = feedbackList.filter(fb => fb.visibility === 'suggestion'); + + return ( +
+
+ {isHost && ( + <> +
+
+ + +
+ +
+ + + + + +
+
+ +
+ + +
+ + {showSuggestionsOnly ? ( +
+ {suggestionList.length === 0 ? ( +
No suggestions yet.
+ ) : ( + suggestionList.map(s => ( +
+ User +
+
+ {s.name} + {s.date} +
+

{s.comment}

+
+
+ )) + )} +
+ ) : ( +
+ {filteredFeedback.length === 0 ? ( +
No feedback matches your filters.
+ ) : ( + filteredFeedback.slice(0, visibleCount).map(feedback => ( +
+ User +
+
+ {feedback.name} + {feedback.date} + {/* Visibility badge */} + + {feedback.visibility === 'host-only' + ? 'Private' + : feedback.visibility === 'suggestion' + ? 'Suggestion' + : 'Public'} + +
+ + {/* rating */} + {feedback.rating !== null && ( +
{renderStars(feedback)}
+ )} + +

{feedback.comment}

+
+
+ )) + )} +
+ )} + {visibleCount < feedbackList.length && ( +
+ +
+ )} + + )} + + {/* Participant view / modal */} + {!isHost && ( + <> + {/* Notice if reviews disabled */} + {!reviewsEnabled && !suggestionsOnly && ( +
+ Reviews are currently disabled for this event. +
+ )} + + {/* Button to open modal if parent didn't provide one */} + {!modalOpen && (reviewsEnabled || suggestionsOnly) && ( +
+ +
+ )} + + {/* Modal-like simple panel (replace with your modal component if you have one) */} + {modalOpen && ( + { + setModalOpen(false); + if (setShowModal) setShowModal(false); + }} + onSubmit={handleSubmitFeedback} + show={modalOpen} + importantLabel={ + eventWithinFirstMonth + ? 'Your feedback is only visible to the host for the first month.' + : null + } + disableSubmit={ + (!suggestionsOnly && !modalComment && !modalRating) || + (suggestionsOnly && !modalSuggestionText) || + (!reviewsEnabled && !suggestionsOnly) + } + > + {suggestionsOnly ? ( +
+ +