Skip to content

Commit f68bafb

Browse files
committed
feat: contributors: enhance single contributor page
This commit improves the contributor profile page by: - Adding a timeline component for contributions - Refactoring layout for better content presentation
1 parent b08d1a2 commit f68bafb

File tree

3 files changed

+144
-104
lines changed

3 files changed

+144
-104
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// assets/scss/components/_contributor-timeline.scss
2+
3+
.contributor-timeline {
4+
@apply relative pl-8;
5+
6+
// The vertical timeline bar
7+
&::before {
8+
content: '';
9+
@apply absolute top-0 left-[0.3rem] w-0.5 h-full bg-border dark:bg-darkmode-border;
10+
}
11+
}
12+
13+
// New style for the year marker
14+
.timeline-year {
15+
@apply relative h-12; // Height to space out the years
16+
17+
span {
18+
@apply absolute bg-body dark:bg-darkmode-body px-3 py-0.5 text-xs font-bold uppercase tracking-wider text-gray-500 dark:text-gray-400 rounded-full z-10;
19+
// Center on the timeline bar (left: 0.3rem; width: w-0.5 which is 0.125rem). Center = 0.3 + (0.125/2) = 0.3625rem
20+
left: calc(0.3rem + (0.125rem / 2));
21+
top: 50%;
22+
transform: translate(-50%, -50%);
23+
}
24+
}
25+
26+
27+
.timeline-item {
28+
@apply relative mb-8;
29+
30+
// The dot on the timeline
31+
&::before {
32+
content: '';
33+
@apply absolute -left-[2.1rem] top-1.5 w-4 h-4 rounded-full border-4 border-body dark:border-darkmode-body;
34+
background-color: var(--color-primary-new);
35+
}
36+
37+
// Remove bottom margin on the last item for a clean finish
38+
&:last-child {
39+
@apply mb-0;
40+
}
41+
}
42+
43+
.timeline-item-content {
44+
@apply p-5 rounded-lg bg-theme-light dark:bg-darkmode-theme-light shadow-md hover:shadow-lg transition-shadow duration-300 ease-in-out;
45+
}
46+
47+
.timeline-item-badge {
48+
// Removed mb-2 as layout is now controlled by flexbox
49+
@apply inline-block bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-200 text-xs font-semibold px-2 py-0.5 rounded-full;
50+
}

assets/scss/main.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
@import "components/hardware-card-wide"; // Add this line
4242

4343
@import "components/og-preview";
44+
@import "components/contributor-timeline";
4445
// Import new custom typography and buttons
45-
@import "components/mega-menu"; // Add this line
46+
@import "components/mega-menu";
4647
@import "typography-custom";

layouts/contributors/single.html

Lines changed: 92 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,116 @@
11
{{ define "main" }}
2-
{{ partial "page-header" . }}
2+
{{ partial "page-header" . }}
33

4-
<section class="section pt-6">
5-
<div class="container">
6-
<div class="row justify-center">
7-
{{/* Contributor Details Column */}}
8-
<div class="lg:col-4 mb-8">
9-
<div class="p-6 rounded bg-theme-light dark:bg-darkmode-theme-light shadow-lg">
4+
<section class="section pt-6">
5+
<div class="container">
6+
<div class="row justify-center">
7+
{{/* Contributor Details Column (Left Sidebar) */}}
8+
<aside class="lg:col-4 mb-8">
9+
<div class="sticky top-24">
10+
<div class="p-6 rounded-lg bg-theme-light dark:bg-darkmode-theme-light shadow-lg">
1011
{{ if .Params.image }}
11-
{{ partial "image" (dict "Src" .Params.image "Context" . "Alt" .Title "Class" "mx-auto mb-6 rounded-full" "Size" "150x150" "Command" "Fill") }}
12+
{{ partial "image" (dict "Src" .Params.image "Context" . "Alt" .Title "Class" "mx-auto mb-6 rounded-full" "Size" "150x150" "Command" "Fill") }}
1213
{{ end }}
1314
<h2 class="text-3xl font-bold text-center mb-3">{{ .Title }}</h2>
1415
{{ if .Params.social }}
15-
<ul class="contributor-socials flex justify-center space-x-3 mb-6">
16-
{{ range .Params.social }}
17-
<li>
18-
<a href="{{ .link | safeURL }}" target="_blank" rel="noopener noreferrer" aria-label="{{ .title }}" class="text-xl">
19-
{{ $iconData := partial "helpers/parse-fa-class.html" .icon }}
20-
{{ partial "icon.html" (dict "style" $iconData.style "name" $iconData.name "class" "") }}
21-
</a>
22-
</li>
23-
{{ end }}
24-
</ul>
16+
<ul class="contributor-socials flex justify-center space-x-3 mb-6">
17+
{{ range .Params.social }}
18+
<li>
19+
<a href="{{ .link | safeURL }}" target="_blank" rel="noopener noreferrer" aria-label="{{ .title }}" class="text-xl">
20+
{{ $iconData := partial "helpers/parse-fa-class.html" .icon }}
21+
{{ partial "icon.html" (dict "style" $iconData.style "name" $iconData.name "class" "") }}
22+
</a>
23+
</li>
24+
{{ end }}
25+
</ul>
2526
{{ end }}
26-
<div class="content prose dark:prose-invert max-w-none dark:text-darkmode-light text-text text-sm">
27+
<div class="content prose prose-sm dark:prose-invert max-w-none dark:text-darkmode-light text-text">
2728
{{ .Content }}
2829
</div>
2930
</div>
3031
</div>
32+
</aside>
3133

32-
{{/* Contributions Column */}}
33-
<div class="lg:col-8">
34-
<h2 class="text-3xl font-semibold mb-8 text-center lg:text-left">Contributions</h2>
35-
36-
{{ $contributorName := .Title }}
37-
{{ $authoredPages := slice }}
38-
39-
{{ range site.RegularPages }}
40-
{{ $isAuthor := false }}
41-
{{ if .Params.author }}
42-
{{ if reflect.IsSlice .Params.author }}
43-
{{ if in .Params.author $contributorName }}{{ $isAuthor = true }}{{ end }}
44-
{{ else }}
45-
{{ if eq .Params.author $contributorName }}{{ $isAuthor = true }}{{ end }}
46-
{{ end }}
47-
{{ end }}
48-
{{ if $isAuthor }}
49-
{{ $authoredPages = $authoredPages | append . }}
50-
{{ end }}
51-
{{ end }}
52-
53-
{{ $contributionSections := slice
54-
(dict "key" "initiatives" "title" "Initiatives" "matchField" "ParentType")
55-
(dict "key" "blog" "title" "Blog Posts" "matchField" "Section")
56-
(dict "key" "workshops" "title" "Workshops" "matchField" "Section")
57-
(dict "key" "student-talks" "title" "Student Talks Sessions" "matchField" "Section")
58-
(dict "key" "hacking-hours" "title" "Hacking Hour Sessions" "matchField" "Type")
59-
}}
60-
61-
{{ $hasContributions := false }}
34+
{{/* Contributions Column (Main Content) */}}
35+
<div class="lg:col-8">
36+
<h2 class="text-3xl font-semibold mb-8 text-center lg:text-left">Contributions</h2>
6237

63-
{{ range $contributionSections }}
64-
{{ $sectionKey := .key }}
65-
{{ $sectionTitle := .title }}
66-
{{ $matchField := .matchField }}
67-
{{ $pagesForThisSection := slice }}
38+
{{ $contributorName := .Title }}
39+
{{ $authoredPages := slice }}
40+
{{ range where site.RegularPages "Params.author" "!=" nil }}
41+
{{ if in .Params.author $contributorName }}
42+
{{ $authoredPages = $authoredPages | append . }}
43+
{{ end }}
44+
{{ end }}
6845

69-
{{ range $authoredPages }}
70-
{{ $matchValue := "" }}
71-
{{ if eq $matchField "Section" }}{{ $matchValue = .Section }}{{ end }}
72-
{{ if eq $matchField "Type" }}{{ $matchValue = .Type }}{{ end }}
73-
{{ if eq $matchField "ParentType" }}{{ with .Parent }}{{ $matchValue = .Type }}{{ end }}{{ end }}
74-
75-
76-
{{ if eq (lower $matchValue) (lower $sectionKey) }}
77-
{{ $pagesForThisSection = $pagesForThisSection | append . }}
78-
{{ end }}
46+
{{/* Section 1: Initiatives */}}
47+
{{ $initiatives_unsorted := where $authoredPages "Type" "eq" "initiatives" }}
48+
{{ $initiatives := sort $initiatives_unsorted "Title" }}
49+
{{ if $initiatives }}
50+
<div class="mb-12">
51+
<h3 class="text-2xl font-semibold mb-5 border-b-2 border-primary dark:border-darkmode-primary pb-2">Initiatives Led</h3>
52+
<div class="grid md:grid-cols-2 gap-6">
53+
{{ range $initiatives }}
54+
<div>
55+
{{ partial "components/initiative-card.html" . }}
56+
</div>
7957
{{ end }}
58+
</div>
59+
</div>
60+
{{ end }}
8061

81-
{{ if $pagesForThisSection }}
82-
{{ $hasContributions = true }}
83-
<div class="mb-10">
84-
<h3 class="text-2xl font-semibold mb-5 border-b-2 border-primary dark:border-darkmode-primary pb-2">{{ $sectionTitle }}</h3>
85-
<ul class="space-y-4">
86-
{{ $sortedPagesForThisSection := $pagesForThisSection }}
87-
{{ if eq $sectionKey "initiatives" }}
88-
{{ $sortedPagesForThisSection = sort $pagesForThisSection "Title" "asc" }}
89-
{{ else }}
90-
{{ $sortedPagesForThisSection = sort $pagesForThisSection "Date" "desc" }}
91-
{{ end }}
62+
{{/* Section 2: Combined Timeline of Other Contributions */}}
63+
{{ $otherContributions := $authoredPages | complement $initiatives }}
64+
{{ $sortedTimelineItems := sort $otherContributions "Date" "desc" }}
65+
{{ $groupedByYear := $sortedTimelineItems.GroupByDate "2006" }}
66+
{{ $sortedGroups := sort $groupedByYear ".Key" "desc" }}
9267

93-
{{ range $sortedPagesForThisSection }}
94-
<li>
95-
<div class="p-5 rounded bg-theme-light dark:bg-darkmode-theme-light shadow-md hover:shadow-lg transition-shadow duration-300 ease-in-out">
96-
<a href="{{ .RelPermalink }}" class="text-xl font-semibold text-primary dark:text-darkmode-primary hover:underline">{{ .Title }}</a>
97-
{{ if and .Date (ne $sectionKey "initiatives") }}
98-
<p class="text-sm text-text dark:text-darkmode-light mt-1">
99-
{{ .Date.Format "January 2, 2006" }}
100-
{{ if .Params.start_time }}
101-
at {{ .Params.start_time }}{{ if .Params.end_time }} - {{ .Params.end_time }}{{ end }}{{ if .Params.time_zone }} {{ .Params.time_zone }}{{ end }}
102-
{{ end }}
103-
</p>
104-
{{ end }}
105-
{{ if .Description }}
106-
<p class="text-gray-600 dark:text-gray-400 mt-2 text-sm">{{ .Description }}</p>
107-
{{ end }}
108-
</div>
109-
</li>
110-
{{ end }}
111-
</ul>
68+
{{ if $sortedTimelineItems }}
69+
<div class="mb-10">
70+
<h3 class="text-2xl font-semibold mb-6 {{ if $initiatives }}border-t-2 border-border dark:border-darkmode-border pt-8{{ end }}">Activity Timeline</h3>
71+
<div class="contributor-timeline">
72+
{{ range $group := $sortedGroups }}
73+
<div class="timeline-year">
74+
<span>{{ .Key }}</span>
75+
</div>
76+
{{ range .Pages }}
77+
<div class="timeline-item">
78+
<div class="timeline-item-content">
79+
<div class="flex justify-between items-start gap-4">
80+
{{/* Left side: Title and Date */}}
81+
<div>
82+
<h4 class="text-xl font-semibold mb-1">
83+
<a href="{{ .RelPermalink }}" class="text-dark dark:text-darkmode-dark hover:text-primary dark:hover:text-darkmode-primary">{{ .Title }}</a>
84+
</h4>
85+
<p class="text-sm text-gray-500 dark:text-gray-400">
86+
{{ .Date.Format "January 2" }}
87+
</p>
88+
</div>
89+
{{/* Right side: Badge */}}
90+
<span class="timeline-item-badge flex-shrink-0">
91+
{{ .Type | default .Section | humanize | title }}
92+
</span>
93+
</div>
94+
{{ if .Description }}
95+
<p class="text-gray-600 dark:text-gray-400 mt-3 text-sm">{{ .Description }}</p>
96+
{{ end }}
11297
</div>
113-
{{ end }}
114-
{{ end }}
115-
116-
{{ if not $hasContributions }}
117-
<div class="p-6 rounded bg-theme-light dark:bg-darkmode-theme-light shadow text-center">
118-
<p class="text-lg text-gray-600 dark:text-gray-400">No specific contributions (blog posts, workshops, initiatives, etc.) found for this individual on the site yet.</p>
119-
<p class="text-sm text-gray-500 dark:text-gray-500 mt-2">They might be active in other ways or their contributions are not yet categorized here.</p>
12098
</div>
121-
{{ end }}
99+
{{ end }}
100+
{{ end }}
101+
</div>
102+
</div>
103+
{{ end }}
122104

105+
{{ if not (or $initiatives $sortedTimelineItems) }}
106+
<div class="p-6 rounded bg-theme-light dark:bg-darkmode-theme-light shadow text-center">
107+
<p class="text-lg text-gray-600 dark:text-gray-400">No specific contributions (blog posts, workshops, initiatives, etc.) found for this individual on the site yet.</p>
108+
<p class="text-sm text-gray-500 dark:text-gray-500 mt-2">They might be active in other ways or their contributions are not yet categorized here.</p>
123109
</div>
110+
{{ end }}
111+
124112
</div>
125113
</div>
126-
</section>
114+
</div>
115+
</section>
127116
{{ end }}

0 commit comments

Comments
 (0)