Skip to content

Commit 9e79468

Browse files
authored
RW25 - Second phase - Speakers & Sessions (#495)
* add speaker cards to the homepage * speaker carousel on homepage * responsive speaker carousel * speaker index and show page - wip * fix speaker index and cards * speaker show page responsiveness wip * add session cards * add 2025 speakers * use 2025 layout for all speakers * add speaker sessions * fix session date * style session page * fix responsiveness * update speakers info * sort speakers * fix carrousel - go back to beginning when we reach the end * put back speaker card 2024 as it was * put back speaker card 2024 as it was * clean code * add role and company to speaker show page * front-end fixes * remove speaker image from sponsor folder
1 parent 2fa36a0 commit 9e79468

File tree

81 files changed

+1367
-11
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+1367
-11
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
<a href="/world/2025/speakers" class="nav-link">Speakers</a>
12
<a href="/world/2025/faq/general" class="nav-link">FAQs</a>
23
<a href="/world/2025/rails_at_scale" class="nav-link">Rails at Scale Summit</a>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{% assign speaker_url = include.speaker.path | split: '/' | last | remove_first: '.md' %}
2+
{% assign session = include.session %}
3+
4+
{% assign clean_path = session.path | replace: '_world_sessions/2025', '' | replace: '.md', '' %}
5+
6+
<div class="session-card"
7+
title="{{ session.title }}"
8+
aria-label="Go to {{ session.title }} session page"
9+
onclick="openWindow( '/world/2025{{ clean_path }}')"
10+
onkeydown="handleEnterOrSpaceWindowOpen(event, '/world/2025{{ clean_path }}')">
11+
<h3>{{ session.title }}</h3>
12+
<p>{{ include.speaker.first_name }} {{ include.speaker.last_name }} - {{ include.speaker.tagline }}{% if include.speaker.company %}, {{ include.speaker.company }} {% endif %}</p>
13+
</div>
14+
15+
<script>
16+
openWindow = (url, openTab = false) =>{
17+
const openType = openTab ? '_blank' : '_self';
18+
window.open(url, openType);
19+
}
20+
21+
handleEnterOrSpaceWindowOpen = (e, url) => {
22+
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
23+
openWindow(url);
24+
}
25+
}
26+
</script>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{% assign speaker_url = include.path | split: '/' | last | remove_first: '.md' %}
2+
3+
<div class="speaker-card"
4+
role="button"
5+
title="{{ include.first_name }} {{ include.last_name }}"
6+
aria-label="Go to {{ include.first_name }} {{ include.last_name }}'s speaker page"
7+
onclick="openWindow('/world/2025/speakers/{{ speaker_url }}')"
8+
onkeydown="handleEnterOrSpaceWindowOpen(event, '/world/2025/speakers/{{ speakerUrl }}')">
9+
<div class="card-content">
10+
<div class="hexagon-frame">
11+
<img src="{{ include.photo }}" alt="{{ include.first_name }} {{ include.last_name }}'s photo" loading="lazy">
12+
</div>
13+
14+
<div class="info-container">
15+
<div class="info">
16+
<h3>{{ include.first_name }} {{ include.last_name }}</h3>
17+
</div>
18+
19+
<div class="info">
20+
<p>
21+
{{ include.tagline }}{% if include.company and include.company != "false" %}, {{ include.company }}{% endif %}
22+
</p>
23+
</div>
24+
</div>
25+
</div>
26+
</div>
27+
28+
<script>
29+
openWindow = (url, openTab = false) =>{
30+
const openType = openTab ? '_blank' : '_self';
31+
window.open(url, openType);
32+
}
33+
34+
handleEnterOrSpaceWindowOpen = (e, url) => {
35+
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
36+
openWindow(url);
37+
}
38+
}
39+
</script>

_includes/world/2025/homepage_sections/image_carousel.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div class="section full-height mobile-fit-content">
1+
<div class="section world-images-container full-height mobile-fit-content">
22
<div class="carousel-container">
33
<div class="scroll-carousel">
44
<img src="/assets/world/2025/images/carousel/carousel1.jpg" alt="people networking" />
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{% assign keynote_speakers = site.world_speakers | where_exp: 'item', 'item.path contains "2025"' | where: 'keynote', true | sort: 'first_name' %}
2+
{% assign sorted_speakers = site.world_speakers | where_exp: 'item', 'item.path contains "2025"' | where: 'keynote', false | sort: 'first_name' %}
3+
4+
<div class="section speakers-container title-center">
5+
<h2>This year's speakers</h2>
6+
7+
<div class="carousel-container">
8+
<img class="carousel-arrow left" src="/assets/world/2025/icons/chevron.svg" alt="go left on the carousel">
9+
10+
<div class="carousel-wrapper">
11+
<div class="speaker-carousel">
12+
{% for speaker in keynote_speakers %}
13+
{%
14+
include world/2025/components/speaker_card.html
15+
first_name=speaker.first_name
16+
last_name=speaker.last_name
17+
tagline=speaker.tagline
18+
company=speaker.company
19+
photo=speaker.image_path
20+
path=speaker.path
21+
%}
22+
{% endfor %}
23+
24+
{% for speaker in sorted_speakers %}
25+
{%
26+
include world/2025/components/speaker_card.html
27+
first_name=speaker.first_name
28+
last_name=speaker.last_name
29+
tagline=speaker.tagline
30+
company=speaker.company
31+
photo=speaker.image_path
32+
path=speaker.path
33+
%}
34+
{% endfor %}
35+
</div>
36+
</div>
37+
38+
<img class="carousel-arrow right" src="/assets/world/2025/icons/chevron.svg" alt="go right on the carousel">
39+
</div>
40+
41+
<div class="button-center">
42+
<a href="/world/2025/speakers" class="button-primary"><span>Go to speaker showcase</span></a>
43+
</div>
44+
</div>
45+
46+
<script>
47+
const carousel = document.querySelector(".speaker-carousel");
48+
const leftBtn = document.querySelector(".carousel-arrow.left");
49+
const rightBtn = document.querySelector(".carousel-arrow.right");
50+
51+
// Scroll 1 card width per click
52+
const scrollAmount = carousel.clientWidth / 3;
53+
54+
rightBtn.addEventListener("click", () => {
55+
const maxScrollLeft = carousel.scrollWidth - carousel.clientWidth;
56+
const nextScroll = carousel.scrollLeft + scrollAmount;
57+
58+
// If the next scroll goes beyond the last visible card, go back to the start (with '-25' to avoid breaking the card)
59+
// Otherwise, scroll forward by scrollAmount
60+
if (nextScroll >= maxScrollLeft - 25) {
61+
carousel.scrollTo({ left: 0, behavior: "smooth" });
62+
} else {
63+
carousel.scrollBy({ left: scrollAmount, behavior: "smooth" });
64+
}
65+
});
66+
67+
leftBtn.addEventListener("click", () => {
68+
carousel.scrollBy({ left: -scrollAmount, behavior: "smooth" })
69+
});
70+
</script>

_layouts/world/2025/session.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
layout: world/2025/default
3+
---
4+
5+
{% assign filteredSpeakers = site.world_speakers | where_exp:"speaker", "speaker.path contains page.speaker" | where_exp: 'item', 'item.path contains "2025"' %}
6+
{% assign speaker = filteredSpeakers | first %}
7+
8+
<div class="session-page">
9+
<div class="session-content">
10+
<h1>{{ page.title }}</h1>
11+
<p>{{ content }}</p>
12+
</div>
13+
14+
<div>
15+
{% if speaker %}
16+
{% include world/2025/components/speaker_card.html
17+
first_name=speaker.first_name
18+
last_name=speaker.last_name
19+
tagline=speaker.tagline
20+
company=speaker.company
21+
photo=speaker.image_path
22+
path=speaker.path
23+
%}
24+
{% endif %}
25+
</div>
26+
</div>

_layouts/world/2025/speaker.html

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
layout: world/2025/default
3+
---
4+
5+
{% assign speaker_id = page.path | split: '/' | last %}
6+
{% assign filteredSessions = site.world_sessions | where_exp: 'item', 'item.path contains "2025"'%}
7+
{% assign speakerSessions = filteredSessions | where: 'speaker', speaker_id %}
8+
9+
<div class="speaker-show-page">
10+
<div class="illustration-background">
11+
<img src="/assets/world/2025/images/shape.png" alt="shape lines">
12+
</div>
13+
14+
<div class="speaker-presentation">
15+
<div class="hexagon-frame">
16+
<img class="headshot" src="{{ page.image_path }}" alt="{{ page.first_name }} {{ page.last_name }}'s photo" loading="lazy">
17+
</div>
18+
19+
<div class="speaker-info">
20+
<h1>{{ page.first_name }} {{ page.last_name }}</h1>
21+
<h3>{{ page.tagline }}{% if page.company and page.company != "false" %}, {{ page.company }}{% endif %}</h3>
22+
<p>{{ content }}</p>
23+
24+
<div class="social-links">
25+
{% if page.github %}
26+
<a href="{{ page.github }}">
27+
<img src="/assets/world/2025/icons/github.png" alt="github logo" width="30"/>
28+
</a>
29+
{% endif %}
30+
{% if page.linkedin %}
31+
<a href="{{ page.linkedin }}">
32+
<img src="/assets/world/2025/icons/linkedin.png" alt="linkedin logo" width="30"/>
33+
</a>
34+
{% endif %}
35+
{% if page.twitter %}
36+
<a href="{{ page.twitter }}">
37+
<img src="/assets/world/2025/icons/x.png" alt="X logo" width="30"/>
38+
</a>
39+
{% endif %}
40+
</div>
41+
</div>
42+
</div>
43+
44+
{% if speakerSessions.size > 0 %}
45+
<div class="speaker-sessions">
46+
<h2>Sessions by this speaker</h2>
47+
48+
<div class="sessions-container">
49+
{% for session in speakerSessions %}
50+
{% include world/2025/components/session_card.html session=session speaker=page %}
51+
{% endfor %}
52+
</div>
53+
</div>
54+
{% endif %}
55+
</div>

_sass/world/2025/base/_colors.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ $button-secondary-gradient: linear-gradient(270deg, $dark-purple 17%, $red 100%)
99
$purple-gradient: linear-gradient(180deg, $dark-purple, $dark-purple, $fushia, $fushia);
1010
$red-gradient: linear-gradient(180deg, $red, $red, $dark-purple, $dark-purple);
1111
$fushia-to-red-gradient: linear-gradient(90deg, #880C51 0%, $red 100%);
12+
13+
$speaker-card-gradient: linear-gradient(180deg, rgba(59, 29, 98, 0%) 50%, $red 100%);
14+
$speaker-card-gradient-hover: linear-gradient(180deg, rgba(59, 29, 98, 0%) 0%, rgba(203, 12, 28, 50%) 31%, $red 100%);;
15+
16+
$session-card-gradient: linear-gradient(-90deg, rgba(59, 29, 98, 0%) 20%, $red 100%);
17+
$session-card-gradient-hover: linear-gradient(-90deg, rgba(59, 29, 98, 0%) 0%, $red 61%);

_sass/world/2025/base/_layout.scss

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ body {
4444
h1, h2, h3 { text-align: center; }
4545
}
4646

47-
&.description-center {
48-
p {
49-
text-align: center;
50-
width: 60%;
51-
margin: 25px auto 0 auto;
52-
}
47+
}
48+
49+
.container-center {
50+
text-align: center;
51+
padding: 0 10%;
52+
53+
@include media(MobileAndTabletScreens) {
54+
padding: 0 5%;
5355
}
5456
}

_sass/world/2025/base/_typography.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ h3, h4 {
4949
letter-spacing: 1px;
5050
}
5151

52-
5352
p {
5453
font-size: $x-large;
5554
font-variation-settings: $font-weight-400;

0 commit comments

Comments
 (0)