feat: add contacts from cms
This commit is contained in:
82
src/components/SiteContactItems.tsx
Normal file
82
src/components/SiteContactItems.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { Enum_Componentsharedcontact_Type } from '../graphql/graphql'
|
||||
import { toIcon } from '../lib/cms/contact/toIcon'
|
||||
import type { SiteConfigContact } from '../lib/cms/contact/types'
|
||||
|
||||
function hrefFor(contact: SiteConfigContact): string | undefined {
|
||||
switch (contact.type) {
|
||||
case Enum_Componentsharedcontact_Type.Phone:
|
||||
return `tel:${contact.value.replace(/\s/g, '')}`
|
||||
case Enum_Componentsharedcontact_Type.Email:
|
||||
return `mailto:${contact.value}`
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
function labelFor(contact: SiteConfigContact): string {
|
||||
const d = contact.displayValue?.trim()
|
||||
return d || contact.value
|
||||
}
|
||||
|
||||
export interface SiteContactItemsProps {
|
||||
contacts: readonly SiteConfigContact[]
|
||||
variant: 'inline' | 'footer'
|
||||
/** Applied to the outer wrapper (inline: flex row; footer: ul gets section spacing from parent) */
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function SiteContactItems({ contacts, variant, className }: SiteContactItemsProps) {
|
||||
if (!contacts.length) return null
|
||||
|
||||
if (variant === 'footer') {
|
||||
return (
|
||||
<ul className={className ?? 'space-y-4'}>
|
||||
{contacts.map(c => {
|
||||
const Icon = toIcon(c.type)
|
||||
const href = hrefFor(c)
|
||||
const label = labelFor(c)
|
||||
const content = href ? (
|
||||
<a href={href} className="hover:text-blue-400 transition-colors">
|
||||
{label}
|
||||
</a>
|
||||
) : (
|
||||
<span>{label}</span>
|
||||
)
|
||||
return (
|
||||
<li key={c.id} className="flex items-start gap-3">
|
||||
<Icon className="w-5 h-5 mt-1 shrink-0 text-blue-400" />
|
||||
<div>{content}</div>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
const rowClass = className ?? 'flex flex-wrap justify-center gap-6 text-sm text-gray-600'
|
||||
|
||||
return (
|
||||
<div className={rowClass}>
|
||||
{contacts.map(c => {
|
||||
const Icon = toIcon(c.type)
|
||||
const href = hrefFor(c)
|
||||
const label = labelFor(c)
|
||||
const linkClass = 'flex items-center gap-2 hover:text-blue-600 transition-colors'
|
||||
if (href) {
|
||||
return (
|
||||
<a key={c.id} href={href} className={linkClass}>
|
||||
<Icon className="w-4 h-4" />
|
||||
<span>{label}</span>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div key={c.id} className="flex items-center gap-2">
|
||||
<Icon className="w-4 h-4" />
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user