{{/* Hugo Blox: Contact Info Block */}} {{/* Documentation: https://hugoblox.com/blocks/ */}} {{/* License: https://github.com/HugoBlox/kit/blob/main/LICENSE.md */}} {{/* Initialise */}} {{ $page := .wcPage }} {{ $block := .wcBlock }} {{ $content := $block.content }} {{ if not (reflect.IsMap $content) }}{{ $content = dict }}{{ end }} {{ $design := $block.design }} {{ if not (reflect.IsMap $design) }}{{ $design = dict }}{{ end }} {{/* Enable Alpine.js for copy-to-clipboard functionality */}} {{ $page.Store.Set "has_alpine" true }} {{ $default_title := i18n "block_contact_title" | default "Contact Us" }} {{ $title := $default_title }} {{ $title_raw := index $content "title" }} {{ if eq (printf "%T" $title_raw) "string" }} {{ $title_raw = strings.TrimSpace $title_raw }} {{ if ne $title_raw "" }} {{ $title = $title_raw }} {{ end }} {{ end }} {{ $title = $title | emojify | $page.RenderString }} {{ $subtitle := "" }} {{ $subtitle_raw := index $content "subtitle" }} {{ if eq (printf "%T" $subtitle_raw) "string" }} {{ $subtitle = $subtitle_raw | emojify | $page.RenderString }} {{ end }} {{ $visit_title := i18n "block_contact_visit_title" | default "Visit Us" }} {{ $visit_title_raw := index $content "visit_title" }} {{ if eq (printf "%T" $visit_title_raw) "string" }} {{ $visit_title_raw = strings.TrimSpace $visit_title_raw }} {{ if ne $visit_title_raw "" }} {{ $visit_title = $visit_title_raw }} {{ end }} {{ end }} {{ $connect_title_raw := "" }} {{ $connect_title_value := index $content "connect_title" }} {{ if eq (printf "%T" $connect_title_value) "string" }} {{ $connect_title_raw = strings.TrimSpace $connect_title_value }} {{ end }} {{ $connect_title_standard := $connect_title_raw | default (i18n "block_contact_connect_title" | default "Connect") }} {{ $connect_title_single := $connect_title_raw | default (i18n "block_contact_connect_title" | default "Let's Connect") }} {{ $connect_text := "" }} {{ $connect_text_raw := index $content "text" }} {{ if eq (printf "%T" $connect_text_raw) "string" }} {{ $connect_text = strings.TrimSpace $connect_text_raw }} {{ end }} {{ if not $connect_text }} {{ $connect_text = "I'm always open to discussing new projects, opportunities, or just having a chat." }} {{ end }} {{ $address_lines := slice }} {{ $address_raw := index $content "address" }} {{ if and $address_raw (reflect.IsMap $address_raw) }} {{ $lines_raw := index $address_raw "lines" }} {{ if reflect.IsSlice $lines_raw }} {{ range $lines_raw }} {{ $line := strings.TrimSpace (printf "%v" .) }} {{ if $line }}{{ $address_lines = $address_lines | append $line }}{{ end }} {{ end }} {{ else if eq (printf "%T" $lines_raw) "string" }} {{ $line := strings.TrimSpace $lines_raw }} {{ if $line }}{{ $address_lines = slice $line }}{{ end }} {{ end }} {{ else if eq (printf "%T" $address_raw) "string" }} {{ $line := strings.TrimSpace $address_raw }} {{ if $line }}{{ $address_lines = slice $line }}{{ end }} {{ end }} {{ $office_hours := slice }} {{ $office_raw := index $content "office_hours" }} {{ if reflect.IsSlice $office_raw }} {{ range $office_raw }} {{ $line := strings.TrimSpace (printf "%v" .) }} {{ if $line }}{{ $office_hours = $office_hours | append $line }}{{ end }} {{ end }} {{ else if eq (printf "%T" $office_raw) "string" }} {{ $line := strings.TrimSpace $office_raw }} {{ if $line }}{{ $office_hours = slice $line }}{{ end }} {{ end }} {{ $map_url := "" }} {{ $map_url_raw := index $content "map_url" }} {{ if eq (printf "%T" $map_url_raw) "string" }} {{ $map_url = strings.TrimSpace $map_url_raw }} {{ end }} {{ $map_embed := "" }} {{ $map_embed_raw := index $content "map_embed" }} {{ if eq (printf "%T" $map_embed_raw) "string" }} {{ $map_embed = $map_embed_raw }} {{ end }} {{ $show_form := partial "functions/coerce_bool" (dict "value" (index $content "show_form") "default" false) }} {{ $form_action := "" }} {{ $form_action_raw := index $content "form_action" }} {{ if eq (printf "%T" $form_action_raw) "string" }} {{ $form_action = strings.TrimSpace $form_action_raw }} {{ end }} {{ if not $form_action }}{{ $form_action = "#" }}{{ end }} {{/* Check if Visit Us card has content */}} {{ $has_visit_content := or (gt (len $address_lines) 0) (gt (len $office_hours) 0) $map_url }} {{/* Check if Connect card has content - fallback to author profile if no email/social */}} {{ $author := "me" }} {{ $author_raw := index $content "username" }} {{ if eq (printf "%T" $author_raw) "string" }} {{ $author = strings.TrimSpace $author_raw }} {{ end }} {{ $profile := partial "functions/get_author_profile" $author }} {{ $authors := partialCached "functions/get_authors_data" $page site.Language.Lang }} {{ $author_data := index $authors (urlize $author) }} {{ $email := "" }} {{ $email_raw := index $content "email" }} {{ if eq (printf "%T" $email_raw) "string" }} {{ $email = strings.TrimSpace $email_raw }} {{ end }} {{ if and (not $email) $author_data (reflect.IsMap $author_data) }} {{ $author_email_raw := index $author_data "email" }} {{ if eq (printf "%T" $author_email_raw) "string" }} {{ $email = strings.TrimSpace $author_email_raw }} {{ end }} {{ end }} {{ $phone := "" }} {{ $phone_raw := index $content "phone" }} {{ if eq (printf "%T" $phone_raw) "string" }} {{ $phone = strings.TrimSpace $phone_raw }} {{ end }} {{ if and (not $phone) $author_data (reflect.IsMap $author_data) }} {{ $author_phone_raw := index $author_data "phone" }} {{ if eq (printf "%T" $author_phone_raw) "string" }} {{ $phone = strings.TrimSpace $author_phone_raw }} {{ end }} {{ end }} {{ $social_raw := index $content "social" }} {{ if eq $social_raw nil }}{{ $social_raw = $profile.links }}{{ end }} {{ $social := slice }} {{ if reflect.IsSlice $social_raw }} {{ range $social_raw }} {{ $url := "" }} {{ $icon := "hero/link" }} {{ $label := "" }} {{ if reflect.IsMap . }} {{ $url_raw := index . "url" | default (index . "link") }} {{ if eq (printf "%T" $url_raw) "string" }} {{ $url = strings.TrimSpace $url_raw }} {{ end }} {{ $icon_raw := index . "icon" }} {{ if eq (printf "%T" $icon_raw) "string" }} {{ $icon = $icon_raw }} {{ end }} {{ $label_raw := index . "label" | default (index . "name") }} {{ if eq (printf "%T" $label_raw) "string" }} {{ $label = $label_raw }} {{ end }} {{ else if eq (printf "%T" .) "string" }} {{ $url = strings.TrimSpace . }} {{ end }} {{ if $url }} {{ $social = $social | append (dict "url" $url "icon" $icon "label" $label) }} {{ end }} {{ end }} {{ else if eq (printf "%T" $social_raw) "string" }} {{ $url := strings.TrimSpace $social_raw }} {{ if $url }} {{ $social = slice (dict "url" $url "icon" "hero/link" "label" "") }} {{ end }} {{ end }} {{ $prospective_raw := index $content "prospective" }} {{ $prospective := dict }} {{ if and $prospective_raw (reflect.IsMap $prospective_raw) }} {{ $prospective = $prospective_raw }} {{ end }} {{ $prospective_title := "" }} {{ $prospective_title_raw := index $prospective "title" }} {{ if eq (printf "%T" $prospective_title_raw) "string" }} {{ $prospective_title = strings.TrimSpace $prospective_title_raw }} {{ end }} {{ $prospective_text := "" }} {{ $prospective_text_raw := index $prospective "text" }} {{ if eq (printf "%T" $prospective_text_raw) "string" }} {{ $prospective_text = strings.TrimSpace $prospective_text_raw }} {{ end }} {{ $prospective_button := index $prospective "button" }} {{ if not (reflect.IsMap $prospective_button) }}{{ $prospective_button = dict }}{{ end }} {{ $prospective_button_text := "" }} {{ with index $prospective_button "text" }}{{ $prospective_button_text = strings.TrimSpace (printf "%v" .) }}{{ end }} {{ $prospective_button_url := "" }} {{ with index $prospective_button "url" }}{{ $prospective_button_url = strings.TrimSpace (printf "%v" .) }}{{ end }} {{ $has_connect_content := or $email $phone (gt (len $social) 0) $prospective_title $prospective_text $prospective_button_text $prospective_button_url }} {{/* Determine grid layout - single column centered if only one card */}} {{ $grid_class := "grid-cols-1 lg:grid-cols-2" }} {{ $card_max_width := "" }} {{ $is_single_card := false }} {{ if and $has_visit_content (not $has_connect_content) }} {{ $grid_class = "grid-cols-1" }} {{ $card_max_width = "max-w-3xl mx-auto" }} {{ $is_single_card = true }} {{ else if and $has_connect_content (not $has_visit_content) }} {{ $grid_class = "grid-cols-1" }} {{ $card_max_width = "max-w-3xl mx-auto" }} {{ $is_single_card = true }} {{ end }}
{{/* Section Header */}}
{{ with $title }}

{{ . }}

{{ end }} {{ with $subtitle }}

{{ . }}

{{ end }}
{{/* Contact Cards Grid */}}
{{/* Visit Us Card - Only show if has content */}} {{ if $has_visit_content }}
{{ partial "functions/get_icon" (dict "name" "hero/map-pin" "attributes" "class=\"w-6 h-6 text-primary-600 dark:text-primary-400\"") }}

{{ $visit_title }}

{{ if gt (len $address_lines) 0 }}
{{ range $address_lines }}

{{ . }}

{{ end }}
{{ end }} {{ if gt (len $office_hours) 0 }}

{{ i18n "block_contact_office_hours" | default "Office Hours" }}

{{ range $office_hours }}

{{ . }}

{{ end }}
{{ end }} {{ if $map_url }} {{ $map_link := $map_url }} {{ $map_target := "" }} {{ $map_scheme := (urls.Parse $map_link).Scheme }} {{ if not $map_scheme }} {{ if not (hasPrefix $map_link "#") }} {{ $map_link = $map_link | relLangURL }} {{ end }} {{ else if in (slice "http" "https") $map_scheme }} {{ $map_target = "target=\"_blank\" rel=\"noopener\"" }} {{ end }} {{ partial "functions/get_icon" (dict "name" "hero/map" "attributes" "class=\"w-5 h-5 mr-2\"") }} {{ i18n "block_contact_view_on_map" | default "View on Map" }} {{ end }}
{{ end }} {{/* Connect Card - Only show if has content */}} {{ if $has_connect_content }}
{{/* Filter social links - remove mailto if email is shown separately */}} {{ $filtered_social := slice }} {{ range $social }} {{ $url := index . "url" }} {{ if and $url (not (and $email (hasPrefix $url "mailto:"))) }} {{ $filtered_social = $filtered_social | append . }} {{ end }} {{ end }} {{ if $is_single_card }} {{/* Single card layout - horizontal on desktop */}}
{{/* Left: Email & CTA */}}

{{ $connect_title_single }}

{{ $connect_text }}

{{ with $email }} {{/* Email with click-to-copy */}}
{{/* Toast notification */}}
✓ Copied to clipboard!
{{/* Primary CTA Button */}} {{ partial "functions/get_icon" (dict "name" "hero/paper-airplane" "attributes" "class=\"w-5 h-5 mr-2\"") }} Send a message {{ end }} {{ with $phone }}
{{ partial "functions/get_icon" (dict "name" "hero/phone" "attributes" "class=\"w-6 h-6 text-primary-600 dark:text-primary-400\"") }}

Call me

{{ . }}

{{ end }}
{{/* Right: Social Links */}} {{ if gt (len $filtered_social) 0 }}

{{ i18n "block_contact_follow_me" | default "Find me on" }}

{{ range $filtered_social }} {{ $social_url := index . "url" }} {{ $social_label := index . "label" }} {{ $social_icon := index . "icon" }} {{ $link := $social_url }} {{ $target := "" }} {{ $scheme := (urls.Parse $link).Scheme }} {{ if not $scheme }} {{ if not (hasPrefix $link "#") }} {{ $link = $link | relLangURL }} {{ end }} {{ else if in (slice "http" "https") $scheme }} {{ $target = "target=\"_blank\" rel=\"noopener\"" }} {{ end }}
{{ partial "functions/get_icon" (dict "name" $social_icon "attributes" "class=\"w-7 h-7\"") }}
{{ end }}
{{ end }}
{{ else }} {{/* Standard card layout (when shown alongside Visit Us) */}}
{{ partial "functions/get_icon" (dict "name" "hero/chat-bubble-left-right" "attributes" "class=\"w-6 h-6 text-primary-600 dark:text-primary-400\"") }}

{{ $connect_title_standard }}

{{/* Contact Methods */}}
{{ with $email }}
{{ partial "functions/get_icon" (dict "name" "hero/envelope" "attributes" "class=\"w-5 h-5 text-primary-600 dark:text-primary-400\"") }}

Email

{{ . }}

{{ end }} {{ with $phone }}
{{ partial "functions/get_icon" (dict "name" "hero/phone" "attributes" "class=\"w-5 h-5 text-primary-600 dark:text-primary-400\"") }}

Phone

{{ . }}

{{ end }} {{/* Social Media */}} {{ if gt (len $filtered_social) 0 }}

{{ i18n "block_contact_follow_me" | default "Find me on" }}

{{ range $filtered_social }} {{ $social_url := index . "url" }} {{ $social_label := index . "label" }} {{ $social_icon := index . "icon" }} {{ $link := $social_url }} {{ $target := "" }} {{ $scheme := (urls.Parse $link).Scheme }} {{ if not $scheme }} {{ if not (hasPrefix $link "#") }} {{ $link = $link | relLangURL }} {{ end }} {{ else if in (slice "http" "https") $scheme }} {{ $target = "target=\"_blank\" rel=\"noopener\"" }} {{ end }} {{ partial "functions/get_icon" (dict "name" $social_icon "attributes" "class=\"w-5 h-5\"") }} {{ end }}
{{ end }}
{{ end }} {{/* Prospective Members - shown in both layouts */}} {{ if or $prospective_title $prospective_text $prospective_button_text $prospective_button_url }} {{ $prospective_heading := $prospective_title | default (i18n "block_contact_prospective_title" | default "Prospective Members") }}

{{ $prospective_heading }}

{{ with $prospective_text }}

{{ . }}

{{ end }} {{ if and $prospective_button_text $prospective_button_url }} {{ $cta_link := $prospective_button_url }} {{ $cta_target := "" }} {{ $cta_scheme := (urls.Parse $cta_link).Scheme }} {{ if not $cta_scheme }} {{ if not (hasPrefix $cta_link "#") }} {{ $cta_link = $cta_link | relLangURL }} {{ end }} {{ else if in (slice "http" "https") $cta_scheme }} {{ $cta_target = "target=\"_blank\" rel=\"noopener\"" }} {{ end }} {{ partial "functions/get_icon" (dict "name" "hero/user-plus" "attributes" "class=\"w-5 h-5 mr-2\"") }} {{ $prospective_button_text }} {{ end }}
{{ end }}
{{ end }}
{{/* Optional Map Embed */}} {{ with $map_embed }}
{{ . | safeHTML }}
{{ end }} {{/* Contact Form (optional) */}} {{ if $show_form }}

{{ i18n "block_contact_form_title" | default "Send us a Message" }}

{{ end }}