Skip to content

Commit 0a3d8cc

Browse files
authored
journey learning tracks UI (#57538)
1 parent dc2a9ed commit 0a3d8cc

File tree

3 files changed

+388
-1
lines changed

3 files changed

+388
-1
lines changed

src/landings/components/journey/JourneyLanding.tsx

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,105 @@
11
import { DefaultLayout } from '@/frame/components/DefaultLayout'
22
import { useLandingContext } from '@/landings/context/LandingContext'
33
import { LandingHero } from '@/landings/components/shared/LandingHero'
4+
import { JourneyLearningTracks } from './JourneyLearningTracks'
5+
6+
export type JourneyLearningTrack = {
7+
id: string
8+
title: string
9+
description: string
10+
trackName: string
11+
trackProduct: string
12+
guides?: Array<{
13+
href: string
14+
title: string
15+
}>
16+
}
417

518
export const JourneyLanding = () => {
619
const { title, intro, heroImage, introLinks } = useLandingContext()
720

21+
// Temp until we hookup real data
22+
const stubLearningTracks: JourneyLearningTrack[] = [
23+
{
24+
id: 'admin:get_started_with_your_enterprise_account',
25+
title: 'Get started with your enterprise account',
26+
description:
27+
'Set up your enterprise account and configure initial settings for your organization.',
28+
trackName: 'get_started_with_your_enterprise_account',
29+
trackProduct: 'admin',
30+
guides: [
31+
{
32+
href: '/admin/overview/about-enterprise-accounts?learn=get_started_with_your_enterprise_account&learnProduct=admin',
33+
title: 'About enterprise accounts',
34+
},
35+
{
36+
href: '/admin/managing-accounts-and-repositories/managing-users-in-your-enterprise/inviting-people-to-manage-your-enterprise?learn=get_started_with_your_enterprise_account&learnProduct=admin',
37+
title: 'Inviting people to manage your enterprise',
38+
},
39+
{
40+
href: '/admin/policies/enforcing-policies-for-your-enterprise/about-enterprise-policies?learn=get_started_with_your_enterprise_account&learnProduct=admin',
41+
title: 'About enterprise policies',
42+
},
43+
],
44+
},
45+
{
46+
id: 'admin:adopting_github_actions_for_your_enterprise_ghec',
47+
title: 'Adopt GitHub Actions for your enterprise',
48+
description:
49+
'Learn how to plan and implement a rollout of GitHub Actions in your enterprise.',
50+
trackName: 'adopting_github_actions_for_your_enterprise_ghec',
51+
trackProduct: 'admin',
52+
guides: [
53+
{
54+
href: '/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/about-github-actions-for-enterprises?learn=adopting_github_actions_for_your_enterprise_ghec&learnProduct=admin',
55+
title: 'About GitHub Actions for enterprises',
56+
},
57+
{
58+
href: '/actions/get-started/understand-github-actions?learn=adopting_github_actions_for_your_enterprise_ghec&learnProduct=admin',
59+
title: 'Understanding GitHub Actions',
60+
},
61+
{
62+
href: '/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/introducing-github-actions-to-your-enterprise?learn=adopting_github_actions_for_your_enterprise_ghec&learnProduct=admin',
63+
title: 'Introducing GitHub Actions to your enterprise',
64+
},
65+
{
66+
href: '/admin/managing-github-actions-for-your-enterprise/getting-started-with-github-actions-for-your-enterprise/migrating-your-enterprise-to-github-actions?learn=adopting_github_actions_for_your_enterprise_ghec&learnProduct=admin',
67+
title: 'Migrating your enterprise to GitHub Actions',
68+
},
69+
],
70+
},
71+
{
72+
id: 'actions:continuous-integration',
73+
title: 'Continuous integration with GitHub Actions',
74+
description:
75+
'Set up automated testing and building for your projects using GitHub Actions workflows.',
76+
trackName: 'continuous-integration',
77+
trackProduct: 'actions',
78+
guides: [
79+
{
80+
href: '/actions/automating-builds-and-tests/about-continuous-integration?learn=continuous-integration&learnProduct=actions',
81+
title: 'About continuous integration',
82+
},
83+
{
84+
href: '/actions/automating-builds-and-tests/building-and-testing-nodejs?learn=continuous-integration&learnProduct=actions',
85+
title: 'Building and testing Node.js',
86+
},
87+
{
88+
href: '/actions/automating-builds-and-tests/building-and-testing-python?learn=continuous-integration&learnProduct=actions',
89+
title: 'Building and testing Python',
90+
},
91+
],
92+
},
93+
]
94+
895
return (
996
<DefaultLayout>
1097
<div>
1198
<LandingHero title={title} intro={intro} heroImage={heroImage} introLinks={introLinks} />
1299

13-
<div>TODO</div>
100+
<div className="container-xl px-3 px-md-6 mt-6 mb-4">
101+
<JourneyLearningTracks tracks={stubLearningTracks} />
102+
</div>
14103
</div>
15104
</DefaultLayout>
16105
)
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
.learningTracks {
2+
border: 1px solid var(--borderColor-default, var(--color-border-default, #d1d9e0));
3+
border-radius: 12px;
4+
padding: 1.5rem;
5+
padding-bottom: .75rem;
6+
margin-bottom: 1rem;
7+
margin-left: 1rem;
8+
box-shadow:
9+
0px 1px 3px 0px rgba(31, 35, 40, 0.08),
10+
0px 1px 0px 0px rgba(31, 35, 40, 0.06);
11+
position: relative;
12+
z-index: 1;
13+
background-color: var(--bgColor-default, var(--color-canvas-default, #ffffff));
14+
}
15+
16+
.trackHeader {
17+
margin: 0 0 0.5rem 0;
18+
padding-right: 3rem;
19+
color: var(--fgColor-default, var(--color-fg-default, #1f2328));
20+
display: flex;
21+
align-items: center;
22+
gap: 0.5rem;
23+
}
24+
25+
.anchorLink {
26+
color: var(--fgColor-default, var(--color-fg-default, #1f2328));
27+
text-decoration: none;
28+
}
29+
30+
.trackDescription {
31+
margin: 0 0 1rem 0;
32+
color: var(--fgColor-muted, var(--color-fg-muted, #656d76));
33+
}
34+
35+
.expandButton {
36+
top: 0;
37+
right: 0;
38+
}
39+
40+
.trackGuides {
41+
margin-top: 1rem;
42+
margin-bottom: 1rem;
43+
padding-left: 0;
44+
list-style: none;
45+
counter-reset: guide-counter;
46+
}
47+
48+
.trackGuides li {
49+
margin-bottom: 0.75rem;
50+
padding-left: 2.5rem;
51+
position: relative;
52+
counter-increment: guide-counter;
53+
}
54+
55+
.trackGuides li::before {
56+
content: counter(guide-counter);
57+
position: absolute;
58+
left: 0;
59+
top: -0.125rem;
60+
width: 1.5rem;
61+
height: 1.5rem;
62+
background-color: transparent;
63+
border: 1px solid var(--borderColor-default, var(--color-border-default, #d0d7de));
64+
color: var(--fgColor-muted, var(--color-fg-muted, #656d76));
65+
border-radius: 50%;
66+
display: flex;
67+
align-items: center;
68+
justify-content: center;
69+
font-size: 0.70rem;
70+
font-weight: 600;
71+
line-height: 1;
72+
}
73+
74+
.guideLink {
75+
color: var(--fgColor-accent, var(--color-accent-fg, #0969da));
76+
text-decoration: none;
77+
}
78+
79+
/* Hide only the timeline line that extends below the last badge, preserve everything else */
80+
.timelineContainer :global(.Timeline-Item:last-child::before) {
81+
background: linear-gradient(to bottom, var(--borderColor-default, #d1d9e0) 0%, var(--borderColor-default, #d1d9e0) 30%, transparent 30%, transparent 100%) !important;
82+
}
83+
84+
.timelineBadge {
85+
background-color: var(--color-canvas-subtle, #f6f8fa) !important;
86+
border: 1px solid var(--borderColor-default, var(--color-border-default, #d1d9e0)) !important;
87+
}
88+
89+
/* Fix entire timeline component overlapping header */
90+
.timelineContainer {
91+
z-index: 0 !important;
92+
position: relative;
93+
}
94+
95+
.timelineContainer :global(.Timeline) {
96+
z-index: 0 !important;
97+
}
98+
99+
.timelineThinLine :global(.Timeline-Item::before) {
100+
width: 1px !important;
101+
}
102+
103+
/* Mobile-first: custom stacked layout */
104+
.mobileLayout {
105+
display: block;
106+
position: relative;
107+
z-index: 0;
108+
}
109+
110+
.mobileItem {
111+
margin-bottom: 2rem;
112+
text-align: center; /* Only for centering the badge */
113+
position: relative;
114+
}
115+
116+
.mobileBadge {
117+
width: 2rem;
118+
height: 2rem;
119+
background-color: var(--color-canvas-subtle, #f6f8fa);
120+
color: var(--fgColor-muted, var(--color-fg-muted));
121+
border: 1px solid var(--borderColor-default, var(--color-border-default, #d1d9e0));
122+
border-radius: 50%;
123+
display: inline-flex;
124+
align-items: center;
125+
justify-content: center;
126+
font-weight: 600;
127+
margin-bottom: 0.5rem;
128+
position: relative;
129+
z-index: 2;
130+
}
131+
132+
/* Add connecting line from badge downward */
133+
.mobileBadge::after {
134+
content: '';
135+
position: absolute;
136+
left: 50%;
137+
top: 100%;
138+
width: 1px;
139+
height: 2.5rem;
140+
background-color: var(--borderColor-default, var(--color-border-default, #d1d9e0));
141+
transform: translateX(-50%);
142+
z-index: 1;
143+
}
144+
145+
/* Add connecting line above badge (except first item) */
146+
.mobileItem:not(:first-child) .mobileBadge::before {
147+
content: '';
148+
position: absolute;
149+
left: 50%;
150+
bottom: 100%;
151+
width: 1px;
152+
height: 2.5rem;
153+
background-color: var(--borderColor-default, var(--color-border-default, #d1d9e0));
154+
transform: translateX(-50%);
155+
z-index: 1;
156+
}
157+
158+
.mobileConnector {
159+
width: 1px;
160+
height: 1rem;
161+
background-color: var(--borderColor-default, var(--color-border-default, #d1d9e0));
162+
margin: 0 auto;
163+
}
164+
165+
.mobileConnector:last-child {
166+
display: none; /* Hide connector after last item */
167+
}
168+
169+
.mobileItem .mobileTile {
170+
border: 1px solid var(--borderColor-default, var(--color-border-default, #d1d9e0));
171+
border-radius: 12px;
172+
padding: 1rem;
173+
margin-top: 0.5rem;
174+
text-align: left;
175+
box-shadow:
176+
0px 1px 3px 0px rgba(31, 35, 40, 0.08),
177+
0px 1px 0px 0px rgba(31, 35, 40, 0.06);
178+
position: relative;
179+
z-index: 3;
180+
background-color: var(--bgColor-default, var(--color-canvas-default, #ffffff));
181+
}
182+
183+
/* Desktop: show Timeline component */
184+
@media (min-width: 768px) {
185+
.mobileLayout {
186+
display: none;
187+
}
188+
189+
.timelineContainer {
190+
display: block;
191+
}
192+
}
193+
194+
/* Mobile: hide Timeline component */
195+
@media (max-width: 767px) {
196+
.timelineContainer {
197+
display: none;
198+
}
199+
}
200+
201+
/* Mobile: stack h3 and Token vertically when mobile layout is active */
202+
@media (max-width: 767px) {
203+
.trackHeader {
204+
flex-direction: column;
205+
align-items: flex-start;
206+
gap: 0.5rem;
207+
margin-bottom: 1.5rem;
208+
}
209+
210+
.trackHeader h3 {
211+
margin-bottom: .50rem;
212+
}
213+
}

0 commit comments

Comments
 (0)