mirror of
https://github.com/tiennm99/HugoBlox-kit.git
synced 2026-10-20 02:16:40 +00:00
239 lines
11 KiB
HTML
239 lines
11 KiB
HTML
{{/* Hugo Blox: Team Showcase */}}
|
|
{{/* Documentation: https://hugoblox.com/blocks/ */}}
|
|
{{/* License: https://github.com/HugoBlox/hugo-blox-builder/blob/main/LICENSE.md */}}
|
|
|
|
{{/* Initialise */}}
|
|
{{ $page := .wcPage }}
|
|
{{ $block := .wcBlock }}
|
|
{{ $show_social := $block.design.show_social | default true }}
|
|
{{ $show_interests := $block.design.show_interests | default false }}
|
|
{{ $show_role := $block.design.show_role | default true }}
|
|
{{ $show_organizations := $block.design.show_organizations | default false }}
|
|
|
|
{{ $title := $block.content.title | emojify | $page.RenderString }}
|
|
{{ $subtitle := $block.content.subtitle | emojify | $page.RenderString }}
|
|
{{ $text := $block.content.text | emojify | $page.RenderString }}
|
|
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
{{/* Section Header */}}
|
|
<div class="flex flex-col items-center text-center mb-12">
|
|
{{ with $title }}
|
|
<h2 class="text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900 dark:text-white tracking-tight">
|
|
{{ . }}
|
|
</h2>
|
|
{{ end }}
|
|
|
|
{{ with $subtitle }}
|
|
<p class="mt-4 text-xl text-gray-600 dark:text-gray-400">
|
|
{{ . }}
|
|
</p>
|
|
{{ end }}
|
|
|
|
{{ with $text }}
|
|
<div class="mt-6 prose prose-lg lg:prose-xl dark:prose-invert max-w-3xl">
|
|
{{ . }}
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
|
|
{{/* Build profiles from data/authors */}}
|
|
{{ $allProfiles := slice }}
|
|
{{ range $slug, $_ := site.Data.authors }}
|
|
{{ $allProfiles = $allProfiles | append (partial "functions/get_author_profile" (dict "slug" $slug)) }}
|
|
{{ end }}
|
|
|
|
{{ $groups := $block.content.user_groups }}
|
|
|
|
{{ if $groups }}
|
|
{{ range $group := $groups }}
|
|
{{ $groupProfiles := slice }}
|
|
{{ range $allProfiles }}
|
|
{{ $u := .user_groups | default (slice) }}
|
|
{{ if gt (len (intersect $u (slice $group))) 0 }}
|
|
{{ $groupProfiles = $groupProfiles | append . }}
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ $groupProfiles = sort $groupProfiles "title" }}
|
|
|
|
{{ if and $groupProfiles (gt (len $groups) 1) }}
|
|
<div class="col-span-full mb-4">
|
|
<h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-6 pb-2 border-b border-gray-200 dark:border-gray-700">
|
|
{{ $group | markdownify }}
|
|
</h3>
|
|
</div>
|
|
{{ end }}
|
|
|
|
<div class="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 w-full">
|
|
{{ range $profile := $groupProfiles }}
|
|
{{ $avatar := $profile.avatar }}
|
|
{{ $link := printf "/authors/%s/" $profile.slug }}
|
|
|
|
<div class="group relative">
|
|
<div class="relative overflow-hidden rounded-2xl bg-white dark:bg-gray-800 shadow-lg hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1">
|
|
|
|
{{ if $avatar }}
|
|
<a href="{{ $link }}" class="block relative h-64 overflow-hidden">
|
|
{{ $image := $avatar.Fill "400x400 Center webp" }}
|
|
<img src="{{ $image.RelPermalink }}"
|
|
alt="{{ $profile.title }}"
|
|
width="{{ $image.Width }}"
|
|
height="{{ $image.Height }}"
|
|
loading="lazy"
|
|
class="w-full h-full object-cover transition-transform duration-300 group-hover:scale-110">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
</a>
|
|
{{ end }}
|
|
|
|
<div class="p-6">
|
|
<h3 class="text-xl font-bold text-gray-900 dark:text-white mb-1">
|
|
<a href="{{ $link }}" class="hover:text-primary-600 dark:hover:text-primary-400 transition-colors">
|
|
{{ $profile.title }}
|
|
</a>
|
|
</h3>
|
|
|
|
{{ if $show_role }}
|
|
<div class="text-gray-600 dark:text-gray-400 mb-3">
|
|
{{ with $profile.role }}<p class="font-medium">{{ . }}</p>{{ end }}
|
|
{{ if and $show_organizations $profile.affiliations }}
|
|
{{ range first 1 $profile.affiliations }}
|
|
<p class="text-sm mt-1">{{ .name }}</p>
|
|
{{ end }}
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
|
|
{{ with $profile.bio }}
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4 line-clamp-2">
|
|
{{ . }}
|
|
</p>
|
|
{{ end }}
|
|
|
|
{{ if and $show_interests $profile.interests }}
|
|
<div class="mb-4">
|
|
<div class="flex flex-wrap gap-1">
|
|
{{ range first 3 $profile.interests }}
|
|
<span class="inline-block bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 text-xs px-2 py-1 rounded">
|
|
{{ . }}
|
|
</span>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
|
|
{{ if and $show_social $profile.links }}
|
|
<div class="flex gap-3 pt-2 border-t border-gray-200 dark:border-gray-700">
|
|
{{ range $profile.links }}
|
|
{{ $l := .url | default .link }}
|
|
{{ $scheme := (urls.Parse $l).Scheme }}
|
|
{{ $target := "" }}
|
|
{{ if not $scheme }}
|
|
{{ $l = (.url | default .link) | relLangURL }}
|
|
{{ if eq (path.Ext $l) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }}
|
|
{{ else if in (slice "http" "https") $scheme }}
|
|
{{ $target = "target=\"_blank\" rel=\"noopener\"" }}
|
|
{{ end }}
|
|
|
|
<a href="{{ $l | safeURL }}"
|
|
{{ $target | safeHTMLAttr }}
|
|
aria-label="{{ .icon }}"
|
|
{{ with .label }} title="{{ . }}"{{ end }}
|
|
class="text-gray-500 hover:text-primary-600 dark:text-gray-400 dark:hover:text-primary-400 transition-colors">
|
|
{{ partial "functions/get_icon" (dict "name" .icon "attributes" "class=\"w-5 h-5\"") }}
|
|
</a>
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
{{ else }}
|
|
{{ $allProfiles = sort $allProfiles "title" }}
|
|
<div class="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
|
{{ range $profile := $allProfiles }}
|
|
{{ $avatar := $profile.avatar }}
|
|
{{ $link := printf "/authors/%s/" $profile.slug }}
|
|
<div class="group relative">
|
|
<div class="relative overflow-hidden rounded-2xl bg-white dark:bg-gray-800 shadow-lg hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1">
|
|
{{ if $avatar }}
|
|
<a href="{{ $link }}" class="block relative h-64 overflow-hidden">
|
|
{{ $image := $avatar.Fill "400x400 Center webp" }}
|
|
<img src="{{ $image.RelPermalink }}"
|
|
alt="{{ $profile.title }}"
|
|
width="{{ $image.Width }}"
|
|
height="{{ $image.Height }}"
|
|
loading="lazy"
|
|
class="w-full h-full object-cover transition-transform duration-300 group-hover:scale-110">
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
</a>
|
|
{{ end }}
|
|
<div class="p-6">
|
|
<h3 class="text-xl font-bold text-gray-900 dark:text-white mb-1">
|
|
<a href="{{ $link }}" class="hover:text-primary-600 dark:hover:text-primary-400 transition-colors">
|
|
{{ $profile.title }}
|
|
</a>
|
|
</h3>
|
|
{{ if $show_role }}
|
|
<div class="text-gray-600 dark:text-gray-400 mb-3">
|
|
{{ with $profile.role }}<p class="font-medium">{{ . }}</p>{{ end }}
|
|
{{ if and $show_organizations $profile.affiliations }}
|
|
{{ range first 1 $profile.affiliations }}
|
|
<p class="text-sm mt-1">{{ .name }}</p>
|
|
{{ end }}
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
{{ with $profile.bio }}
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4 line-clamp-2">{{ . }}</p>
|
|
{{ end }}
|
|
{{ if and $show_interests $profile.interests }}
|
|
<div class="mb-4">
|
|
<div class="flex flex-wrap gap-1">
|
|
{{ range first 3 $profile.interests }}
|
|
<span class="inline-block bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 text-xs px-2 py-1 rounded">{{ . }}</span>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
{{ if and $show_social $profile.links }}
|
|
<div class="flex gap-3 pt-2 border-t border-gray-200 dark:border-gray-700">
|
|
{{ range $profile.links }}
|
|
{{ $l := .url | default .link }}
|
|
{{ $scheme := (urls.Parse $l).Scheme }}
|
|
{{ $target := "" }}
|
|
{{ if not $scheme }}
|
|
{{ $l = (.url | default .link) | relLangURL }}
|
|
{{ if eq (path.Ext $l) ".pdf" }}{{ $target = "target=\"_blank\" rel=\"noopener\"" }}{{ end }}
|
|
{{ else if in (slice "http" "https") $scheme }}
|
|
{{ $target = "target=\"_blank\" rel=\"noopener\"" }}
|
|
{{ end }}
|
|
<a href="{{ $l | safeURL }}" {{ $target | safeHTMLAttr }} aria-label="{{ .icon }}" {{ with .label }} title="{{ . }}"{{ end }} class="text-gray-500 hover:text-primary-600 dark:text-gray-400 dark:hover:text-primary-400 transition-colors">
|
|
{{ partial "functions/get_icon" (dict "name" .icon "attributes" "class=\"w-5 h-5\"") }}
|
|
</a>
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
|
|
{{/* Call to Action */}}
|
|
{{ with $block.content.cta }}
|
|
<div class="mt-12 text-center">
|
|
<a href="{{ .url }}" class="inline-flex items-center px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg shadow-lg hover:shadow-xl transition-all duration-300">
|
|
{{ .text }}
|
|
{{ with .icon }}
|
|
{{ partial "functions/get_icon" (dict "name" . "attributes" "class=\"ml-2 w-5 h-5\"") }}
|
|
{{ end }}
|
|
</a>
|
|
</div>
|
|
{{ end }}
|
|
|
|
</div>
|