Skip to content

Commit 3e3a009

Browse files
committed
fix: CourseModal speaker image handling and styles
1 parent 5121ff4 commit 3e3a009

File tree

1 file changed

+47
-51
lines changed

1 file changed

+47
-51
lines changed

src/components/home/CourseModal.astro

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type { Course } from "../../types/schedule";
77
<div class="modal-close-container">
88
<span class="close">&times;</span>
99
</div>
10-
<img id="modalPersonImage" src="" alt="Speaker" class="modal-person-image" style="display: none;" />
1110
<h2 id="modalTitle" class="emfont-NotoSansTC-600"></h2>
1211
<h3 id="modalSubtitle" class="emfont-NotoSansTC-600"></h3>
1312
<div class="section-title emfont-NotoSansTC-600">課程介紹</div>
@@ -45,12 +44,12 @@ import type { Course } from "../../types/schedule";
4544
background-color: #028fdb;
4645
color: #efefef;
4746
padding: 3rem;
48-
border-radius: 8px;
47+
border-radius: 16px;
4948
max-width: 800px;
5049
width: 90%;
5150
position: relative !important;
5251
margin: auto;
53-
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
52+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
5453
max-height: 96dvh;
5554
overflow-y: auto;
5655
-webkit-overflow-scrolling: touch;
@@ -203,47 +202,42 @@ import type { Course } from "../../types/schedule";
203202
border-bottom: 1px solid #a2a2a2;
204203
}
205204

206-
.modal-person-image {
207-
position: absolute;
208-
top: 1.5rem;
209-
right: 3.5rem;
210-
width: 90px;
211-
height: 90px;
212-
border-radius: 50%;
213-
object-fit: cover;
214-
z-index: 5;
215-
}
216-
217205
@media (max-width: 600px) {
218206
.modal {
219207
padding: 0;
220208
align-items: center;
221209
}
222210

223211
.modal-content {
224-
padding: 1.5rem;
225-
width: 90%;
212+
padding: 2rem 1.5rem;
213+
width: 95%;
226214
max-height: 90dvh;
227215
overflow-y: auto;
228-
border-radius: 12px;
229-
margin: 0 0 env(safe-area-inset-bottom, 20px);
216+
border-radius: 18px;
217+
margin: 2rem 0 env(safe-area-inset-bottom, 20px);
230218
-webkit-overflow-scrolling: touch;
231219
overscroll-behavior-y: contain;
232-
padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 20px));
220+
padding-bottom: calc(2rem + env(safe-area-inset-bottom, 20px));
233221
}
234222

235223
#modalTitle {
236224
font-size: 1.5rem;
237225
padding-right: 0;
226+
line-height: 1.3;
238227
}
239228

240229
#modalSubtitle {
241230
font-size: 1rem;
242231
margin-bottom: 1.5rem;
243232
}
244233

245-
.modal-person-image {
246-
display: none;
234+
.section-title {
235+
font-size: 1.2rem;
236+
margin-top: 1.2rem;
237+
}
238+
239+
.description-container {
240+
margin-bottom: 1.5rem;
247241
}
248242

249243
.close-button {
@@ -263,20 +257,32 @@ import type { Course } from "../../types/schedule";
263257
font-size: 1.618rem !important;
264258
font-weight: 600;
265259
color: #efefef;
266-
margin-bottom: 0.5rem;
260+
margin-bottom: 0.8rem;
267261
display: flex !important;
268262
place-items: center;
269-
gap: 0.75rem !important;
263+
gap: 1rem !important;
270264
}
271265

272266
#speakerDescription .speaker-inline-image {
273-
width: 40px;
274-
height: 40px;
267+
width: 55px;
268+
height: 55px;
275269
border-radius: 50%;
276270
object-fit: cover;
277271
flex-shrink: 0;
278272
}
279273

274+
@media (max-width: 600px) {
275+
#speakerDescription .speaker-name {
276+
font-size: 1.4rem !important;
277+
gap: 0.75rem !important;
278+
}
279+
280+
#speakerDescription .speaker-inline-image {
281+
width: 45px;
282+
height: 45px;
283+
}
284+
}
285+
280286
#speakerDescription p {
281287
margin-bottom: 1rem;
282288
line-height: 1.6;
@@ -354,7 +360,12 @@ import type { Course } from "../../types/schedule";
354360
// Function to render markdown content
355361
function renderMarkdown(text) {
356362
if (!text) return '';
357-
return marked.parse(text);
363+
try {
364+
return marked.parse(text);
365+
} catch (e) {
366+
console.error('Error parsing markdown:', e);
367+
return text; // Fallback to plain text
368+
}
358369
}
359370

360371
document.addEventListener("astro:page-load", () => {
@@ -393,7 +404,6 @@ import type { Course } from "../../types/schedule";
393404
const linksContainerEl = modalElement.querySelector("#modalLinks") as HTMLElement;
394405
const speakerSectionTitleEl = modalElement.querySelector("#speakerSectionTitle") as HTMLElement;
395406
const speakerDescriptionEl = modalElement.querySelector("#speakerDescription") as HTMLElement;
396-
const modalPersonImageEl = modalElement.querySelector("#modalPersonImage") as HTMLImageElement;
397407

398408
if (modalTitleEl) modalTitleEl.textContent = course.zh.title?.split("\n")[0] || "";
399409
if (modalSubtitleEl) modalSubtitleEl.textContent = course.zh.title?.split("\n")[1] || "";
@@ -402,7 +412,6 @@ import type { Course } from "../../types/schedule";
402412
if (course.type === "Game") {
403413
if (speakerSectionTitleEl) speakerSectionTitleEl.style.display = "none";
404414
if (speakerDescriptionEl) speakerDescriptionEl.style.display = "none";
405-
if (modalPersonImageEl) modalPersonImageEl.style.display = "none";
406415
} else if (course.type === "Community") {
407416
// Handle Community type events - show booth list instead of speakers
408417
if (speakerSectionTitleEl) {
@@ -427,7 +436,6 @@ import type { Course } from "../../types/schedule";
427436
}
428437
speakerDescriptionEl.classList.add("description-text");
429438
}
430-
if (modalPersonImageEl) modalPersonImageEl.style.display = "none";
431439
} else {
432440
// Show speaker section for non-Game and non-Community events
433441
if (speakerSectionTitleEl) speakerSectionTitleEl.style.display = "block";
@@ -449,29 +457,18 @@ import type { Course } from "../../types/schedule";
449457
const speakersWithDesc = speakers?.filter(speaker => speaker.zh.bio && speaker.zh.bio.trim() !== "") || [];
450458

451459
if (speakers && speakers.length === 1) {
452-
// Single speaker - show image in top-right position
460+
// Single speaker - add image in speaker section
453461
const speaker = speakers[0];
454-
if (modalPersonImageEl && speaker.id) {
455-
// Use .webp extension
456-
modalPersonImageEl.src = `/2025/speakers/${speaker.id}.webp`;
457-
modalPersonImageEl.style.display = "block";
458-
modalPersonImageEl.onerror = () => {
459-
modalPersonImageEl.style.display = "none";
460-
};
461-
}
462+
const imageHtml = speaker.id ? `<img src="/2025/speakers/${speaker.id}.webp" alt="${speaker.zh.name}" class="speaker-inline-image">` : "";
462463

463-
// Show speaker description without inline image
464+
// Show speaker description with inline image
464465
if (speakersWithDesc.length > 0) {
465-
speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${speakersWithDesc[0].zh.name}</div>${renderMarkdown(speakersWithDesc[0].zh.bio)}`;
466+
speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${imageHtml}<span>${speakersWithDesc[0].zh.name}</span></div>${renderMarkdown(speakersWithDesc[0].zh.bio)}`;
466467
} else if (speakerText) {
467-
speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${speaker.zh.name}</div>${speakerText}是本課程的講師。<br>其他資訊可能得等你自己通靈`;
468+
speakerDescriptionEl.innerHTML = `<div class="speaker-name emfont-NotoSansTC-600">${imageHtml}<span>${speaker.zh.name}</span></div>${speakerText}是本課程的講師。<br>其他資訊可能得等你自己通靈`;
468469
}
469470
} else if (speakers && speakers.length > 1) {
470-
// Multiple speakers - hide top image and show inline images
471-
if (modalPersonImageEl) {
472-
modalPersonImageEl.style.display = "none";
473-
}
474-
471+
// Multiple speakers with inline images
475472
if (speakersWithDesc.length > 0) {
476473
speakerDescriptionEl.innerHTML = speakersWithDesc.map(speaker => {
477474
// Use .webp extension
@@ -487,9 +484,6 @@ import type { Course } from "../../types/schedule";
487484
}
488485
} else {
489486
// No speakers
490-
if (modalPersonImageEl) {
491-
modalPersonImageEl.style.display = "none";
492-
}
493487
speakerDescriptionEl.innerHTML = "無講者資訊";
494488
}
495489
speakerDescriptionEl.classList.add("description-text");
@@ -585,14 +579,16 @@ import type { Course } from "../../types/schedule";
585579

586580
// Close modal function
587581
const closeModal = () => {
588-
if (modalElement) {
582+
if (modalElement && modalContent) {
589583
modalContent.style.transform = "scale(0)";
590584
modalElement.style.backdropFilter = "blur(0px)";
591585
modalContent.style.transition = "transform .3s cubic-bezier(.5, 1, 0, 1)";
592586
modalElement.style.backgroundColor = "transparent";
593587
setTimeout(() => {
594588
modalElement.style.display = "none";
595-
modalContent.style.transition = "transform .3s cubic-bezier(.5, 1, .1, 1.20)";
589+
if (modalContent) {
590+
modalContent.style.transition = "transform .3s cubic-bezier(.5, 1, .1, 1.20)";
591+
}
596592
}, 300);
597593
document.body.style.overflow = "";
598594
}

0 commit comments

Comments
 (0)