|
| 1 | +import React from "react"; |
| 2 | +import { MeetupSession } from "../types"; |
| 3 | +import { |
| 4 | + formatMeetupDate, |
| 5 | + formatCountdown, |
| 6 | + MeetingStatus, |
| 7 | +} from "../utils/dateUtils"; |
| 8 | +import { generateGoogleCalendarUrl } from "../utils/calendarUtils"; |
| 9 | +import styles from "../styles.module.css"; |
| 10 | + |
| 11 | +interface SessionDetailsProps { |
| 12 | + session: MeetupSession; |
| 13 | + sessionDate: Date; |
| 14 | + meetingStatus: MeetingStatus; |
| 15 | + copied: boolean; |
| 16 | + onBack: () => void; |
| 17 | + onCopyLink: (link: string) => void; |
| 18 | +} |
| 19 | + |
| 20 | +/** |
| 21 | + * Component to display detailed session information |
| 22 | + */ |
| 23 | +export const SessionDetails: React.FC<SessionDetailsProps> = ({ |
| 24 | + session, |
| 25 | + sessionDate, |
| 26 | + meetingStatus, |
| 27 | + copied, |
| 28 | + onBack, |
| 29 | + onCopyLink, |
| 30 | +}) => { |
| 31 | + const handleAddToCalendar = () => { |
| 32 | + const calendarUrl = generateGoogleCalendarUrl(session, sessionDate); |
| 33 | + window.open(calendarUrl, "_blank", "noopener,noreferrer"); |
| 34 | + }; |
| 35 | + |
| 36 | + // Join button is enabled from start of meeting day until meeting ends |
| 37 | + const isJoinEnabled = |
| 38 | + meetingStatus === MeetingStatus.STARTING_SOON || |
| 39 | + meetingStatus === MeetingStatus.ONGOING; |
| 40 | + |
| 41 | + // Get appropriate date/time display text |
| 42 | + const getDateTimeDisplay = (): string => { |
| 43 | + switch (meetingStatus) { |
| 44 | + case MeetingStatus.STARTING_SOON: |
| 45 | + return `Today's meeting ${formatCountdown(sessionDate)}`; |
| 46 | + case MeetingStatus.ONGOING: |
| 47 | + return "Meeting ongoing"; |
| 48 | + case MeetingStatus.ENDED: |
| 49 | + case MeetingStatus.BEFORE_DAY: |
| 50 | + default: |
| 51 | + return formatMeetupDate(sessionDate); |
| 52 | + } |
| 53 | + }; |
| 54 | + |
| 55 | + return ( |
| 56 | + <> |
| 57 | + <button className={styles.backButton} onClick={onBack} type="button"> |
| 58 | + <svg |
| 59 | + width="16" |
| 60 | + height="16" |
| 61 | + viewBox="0 0 24 24" |
| 62 | + fill="none" |
| 63 | + xmlns="http://www.w3.org/2000/svg" |
| 64 | + aria-hidden="true" |
| 65 | + > |
| 66 | + <path |
| 67 | + d="M15 18L9 12L15 6" |
| 68 | + stroke="currentColor" |
| 69 | + strokeWidth="2" |
| 70 | + strokeLinecap="round" |
| 71 | + strokeLinejoin="round" |
| 72 | + /> |
| 73 | + </svg> |
| 74 | + Back to sessions |
| 75 | + </button> |
| 76 | + |
| 77 | + <div className={styles.dateSection}> |
| 78 | + <svg |
| 79 | + className={styles.sectionIcon} |
| 80 | + width="20" |
| 81 | + height="20" |
| 82 | + viewBox="0 0 24 24" |
| 83 | + fill="none" |
| 84 | + xmlns="http://www.w3.org/2000/svg" |
| 85 | + aria-hidden="true" |
| 86 | + > |
| 87 | + <circle |
| 88 | + cx="12" |
| 89 | + cy="12" |
| 90 | + r="10" |
| 91 | + stroke="currentColor" |
| 92 | + strokeWidth="2" |
| 93 | + /> |
| 94 | + <path |
| 95 | + d="M12 6V12L16 14" |
| 96 | + stroke="currentColor" |
| 97 | + strokeWidth="2" |
| 98 | + strokeLinecap="round" |
| 99 | + /> |
| 100 | + </svg> |
| 101 | + <div className={styles.dateText}> |
| 102 | + <p className={styles.dateLabel}>Date & Time</p> |
| 103 | + <p className={styles.dateValue}>{getDateTimeDisplay()}</p> |
| 104 | + </div> |
| 105 | + </div> |
| 106 | + |
| 107 | + <div className={styles.linkSection}> |
| 108 | + <p className={styles.linkLabel}>Meeting Link</p> |
| 109 | + <div className={styles.linkActions}> |
| 110 | + <a |
| 111 | + href={isJoinEnabled ? session.meetupLink : undefined} |
| 112 | + target="_blank" |
| 113 | + rel="noopener noreferrer" |
| 114 | + className={`${styles.linkButton} ${ |
| 115 | + !isJoinEnabled ? styles.disabled : "" |
| 116 | + }`} |
| 117 | + aria-label={ |
| 118 | + isJoinEnabled |
| 119 | + ? "Open meetup link in new tab" |
| 120 | + : meetingStatus === MeetingStatus.ENDED |
| 121 | + ? "Meeting has ended" |
| 122 | + : "Event link will be available on meeting day" |
| 123 | + } |
| 124 | + aria-disabled={!isJoinEnabled} |
| 125 | + onClick={(e) => { |
| 126 | + if (!isJoinEnabled) { |
| 127 | + e.preventDefault(); |
| 128 | + } |
| 129 | + }} |
| 130 | + > |
| 131 | + <svg |
| 132 | + width="18" |
| 133 | + height="18" |
| 134 | + viewBox="0 0 24 24" |
| 135 | + fill="none" |
| 136 | + xmlns="http://www.w3.org/2000/svg" |
| 137 | + aria-hidden="true" |
| 138 | + > |
| 139 | + <path |
| 140 | + d="M18 13V19C18 19.5304 17.7893 20.0391 17.4142 20.4142C17.0391 20.7893 16.5304 21 16 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V8C3 7.46957 3.21071 6.96086 3.58579 6.58579C3.96086 6.21071 4.46957 6 5 6H11" |
| 141 | + stroke="currentColor" |
| 142 | + strokeWidth="2" |
| 143 | + strokeLinecap="round" |
| 144 | + strokeLinejoin="round" |
| 145 | + /> |
| 146 | + <path |
| 147 | + d="M15 3H21V9" |
| 148 | + stroke="currentColor" |
| 149 | + strokeWidth="2" |
| 150 | + strokeLinecap="round" |
| 151 | + strokeLinejoin="round" |
| 152 | + /> |
| 153 | + <path |
| 154 | + d="M10 14L21 3" |
| 155 | + stroke="currentColor" |
| 156 | + strokeWidth="2" |
| 157 | + strokeLinecap="round" |
| 158 | + strokeLinejoin="round" |
| 159 | + /> |
| 160 | + </svg> |
| 161 | + Join Event |
| 162 | + </a> |
| 163 | + <button |
| 164 | + onClick={() => onCopyLink(session.meetupLink)} |
| 165 | + className={`${styles.linkButton} ${copied ? styles.copied : ""}`} |
| 166 | + aria-label={copied ? "Link copied" : "Copy meetup link"} |
| 167 | + type="button" |
| 168 | + > |
| 169 | + {copied ? ( |
| 170 | + <> |
| 171 | + <svg |
| 172 | + width="18" |
| 173 | + height="18" |
| 174 | + viewBox="0 0 24 24" |
| 175 | + fill="none" |
| 176 | + xmlns="http://www.w3.org/2000/svg" |
| 177 | + aria-hidden="true" |
| 178 | + > |
| 179 | + <path |
| 180 | + d="M20 6L9 17L4 12" |
| 181 | + stroke="currentColor" |
| 182 | + strokeWidth="2" |
| 183 | + strokeLinecap="round" |
| 184 | + strokeLinejoin="round" |
| 185 | + /> |
| 186 | + </svg> |
| 187 | + Copied! |
| 188 | + </> |
| 189 | + ) : ( |
| 190 | + <> |
| 191 | + <svg |
| 192 | + width="18" |
| 193 | + height="18" |
| 194 | + viewBox="0 0 24 24" |
| 195 | + fill="none" |
| 196 | + xmlns="http://www.w3.org/2000/svg" |
| 197 | + aria-hidden="true" |
| 198 | + > |
| 199 | + <rect |
| 200 | + x="9" |
| 201 | + y="9" |
| 202 | + width="13" |
| 203 | + height="13" |
| 204 | + rx="2" |
| 205 | + ry="2" |
| 206 | + stroke="currentColor" |
| 207 | + strokeWidth="2" |
| 208 | + strokeLinecap="round" |
| 209 | + strokeLinejoin="round" |
| 210 | + /> |
| 211 | + <path |
| 212 | + d="M5 15H4C3.46957 15 2.96086 14.7893 2.58579 14.4142C2.21071 14.0391 2 13.5304 2 13V4C2 3.46957 2.21071 2.96086 2.58579 2.58579C2.96086 2.21071 3.46957 2 4 2H13C13.5304 2 14.0391 2.21071 14.4142 2.58579C14.7893 2.96086 15 3.46957 15 4V5" |
| 213 | + stroke="currentColor" |
| 214 | + strokeWidth="2" |
| 215 | + strokeLinecap="round" |
| 216 | + strokeLinejoin="round" |
| 217 | + /> |
| 218 | + </svg> |
| 219 | + Copy Link |
| 220 | + </> |
| 221 | + )} |
| 222 | + </button> |
| 223 | + </div> |
| 224 | + </div> |
| 225 | + |
| 226 | + <div className={styles.calendarSection}> |
| 227 | + <button |
| 228 | + onClick={handleAddToCalendar} |
| 229 | + className={styles.calendarButton} |
| 230 | + aria-label="Add to Google Calendar" |
| 231 | + type="button" |
| 232 | + > |
| 233 | + <svg |
| 234 | + width="20" |
| 235 | + height="20" |
| 236 | + viewBox="0 0 24 24" |
| 237 | + fill="none" |
| 238 | + xmlns="http://www.w3.org/2000/svg" |
| 239 | + aria-hidden="true" |
| 240 | + > |
| 241 | + <rect |
| 242 | + x="3" |
| 243 | + y="4" |
| 244 | + width="18" |
| 245 | + height="18" |
| 246 | + rx="2" |
| 247 | + ry="2" |
| 248 | + stroke="currentColor" |
| 249 | + strokeWidth="2" |
| 250 | + strokeLinecap="round" |
| 251 | + strokeLinejoin="round" |
| 252 | + /> |
| 253 | + <path |
| 254 | + d="M16 2V6" |
| 255 | + stroke="currentColor" |
| 256 | + strokeWidth="2" |
| 257 | + strokeLinecap="round" |
| 258 | + strokeLinejoin="round" |
| 259 | + /> |
| 260 | + <path |
| 261 | + d="M8 2V6" |
| 262 | + stroke="currentColor" |
| 263 | + strokeWidth="2" |
| 264 | + strokeLinecap="round" |
| 265 | + strokeLinejoin="round" |
| 266 | + /> |
| 267 | + <path |
| 268 | + d="M3 10H21" |
| 269 | + stroke="currentColor" |
| 270 | + strokeWidth="2" |
| 271 | + strokeLinecap="round" |
| 272 | + strokeLinejoin="round" |
| 273 | + /> |
| 274 | + <path |
| 275 | + d="M12 14L12 14.01" |
| 276 | + stroke="currentColor" |
| 277 | + strokeWidth="2.5" |
| 278 | + strokeLinecap="round" |
| 279 | + strokeLinejoin="round" |
| 280 | + /> |
| 281 | + </svg> |
| 282 | + Add to Google Calendar |
| 283 | + </button> |
| 284 | + </div> |
| 285 | + </> |
| 286 | + ); |
| 287 | +}; |
0 commit comments