166 lines
11 KiB
Plaintext
166 lines
11 KiB
Plaintext
---
|
|
import Layout from '../layouts/Layout.astro';
|
|
import Navbar from '../components/Navbar';
|
|
import Footer from '../components/Footer';
|
|
import { getSiteSettings, getSocialLinks } from '../lib/data';
|
|
|
|
const settings = await getSiteSettings();
|
|
const allLinks = await getSocialLinks();
|
|
const links = allLinks.filter(l => l.showInLinksPage !== false);
|
|
const resumeUrl = settings.resumeFile && settings.resumeFile !== '#' ? settings.resumeFile : '/CV-Cris-Charles-Garcia.pdf';
|
|
const profileAvatar = settings.heroImage || settings.logoImage || '/logo.png';
|
|
|
|
const formatDisplayUrl = (url: string) => {
|
|
try {
|
|
if (url.startsWith('mailto:')) return url.replace('mailto:', '');
|
|
return url.replace(/^https?:\/\/(www\.)?/, '').replace(/\/$/, '');
|
|
} catch {
|
|
return url;
|
|
}
|
|
};
|
|
|
|
const getIconSvg = (platform: string) => {
|
|
const p = platform.toLowerCase();
|
|
if (p.includes('github')) {
|
|
return '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>';
|
|
}
|
|
if (p.includes('linkedin')) {
|
|
return '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.779-1.75-1.75s.784-1.75 1.75-1.75 1.75.779 1.75 1.75-.784 1.75-1.75 1.75zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>';
|
|
}
|
|
if (p.includes('twitter') || p.includes('x.com')) {
|
|
return '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>';
|
|
}
|
|
if (p.includes('facebook') && !p.includes('messenger')) {
|
|
return '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874V12h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>';
|
|
}
|
|
if (p.includes('messenger')) {
|
|
return '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0C5.373 0 0 5.373 0 11.984c0 2.11.554 4.095 1.524 5.823L.61 24l6.452-3.388a11.58 11.58 0 0 0 4.938 1.077c6.627 0 12-5.373 12-11.984C24 5.373 18.627 0 12 0zm1.75 14.96l-3.316-3.535-6.46 3.535 7.106-7.55 3.328 3.535 6.44-3.535-7.106 7.55z"/></svg>';
|
|
}
|
|
if (p.includes('tiktok')) {
|
|
return '<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12.53.02C13.84 0 15.14.01 16.44 0c.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.09-1.03-1.87-1.09-2.93-3.16-2.61-5.25.38-2.52 2.5-4.46 5.04-4.46.73 0 1.43.16 2.07.46.06.03.11.05.16.08v4.18c-1.38-.24-2.81-.19-4.16.14-1.12.28-2.12 1.05-2.67 2.06-.55 1.01-.58 2.22-.09 3.25.48 1.01 1.41 1.72 2.49 2.03 1.1.32 2.27.32 3.37.01.69-.2 1.34-.55 1.87-.99.53-.44.97-.99 1.25-1.61.28-.62.43-1.28.46-1.95.06-2.69.02-5.38.02-8.07z"/></svg>';
|
|
}
|
|
if (p.includes('mail') || p.includes('email')) {
|
|
return '<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75" /></svg>';
|
|
}
|
|
return '<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" /></svg>';
|
|
};
|
|
---
|
|
|
|
<Layout
|
|
title={`Links & Socials | ${settings.fullName}`}
|
|
description="Official social links, contact options, and developer directory for Cris Charles Garcia."
|
|
>
|
|
<Navbar fullName={settings.fullName} logoImage={settings.logoImage} client:load />
|
|
|
|
<main class="min-h-screen py-20 px-4 sm:px-6 flex flex-col items-center justify-center relative">
|
|
<div class="w-full max-w-md flex flex-col items-center relative z-10 bento-enter">
|
|
|
|
{/* Profile Header Bento Card */}
|
|
<div class="w-full bento-card p-6 sm:p-7 text-center flex flex-col items-center mb-5">
|
|
<div class="w-20 h-20 rounded-full overflow-hidden border border-border-custom shadow-xs mb-4">
|
|
<img
|
|
src={profileAvatar}
|
|
alt={settings.fullName}
|
|
class="w-full h-full object-cover"
|
|
/>
|
|
</div>
|
|
|
|
<h1 class="text-2xl font-bold font-heading text-foreground-custom tracking-tight">
|
|
{settings.fullName}
|
|
</h1>
|
|
|
|
<p class="text-xs font-mono text-primary-custom mt-1 font-medium">
|
|
{settings.title} • {settings.location}
|
|
</p>
|
|
|
|
<p class="text-xs text-muted-foreground-custom max-w-xs mt-2.5 leading-relaxed">
|
|
Direct links to all my profiles, portfolios, and repositories.
|
|
</p>
|
|
|
|
{/* Quick CV Action */}
|
|
<div class="w-full grid grid-cols-2 gap-2 mt-5 pt-4 border-t border-border-custom">
|
|
<a
|
|
href={resumeUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="inline-flex items-center justify-center gap-1.5 px-3 py-2 rounded-xl bg-primary-custom text-white text-xs font-medium hover:bg-primary-custom/90 transition-all text-center"
|
|
>
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
|
</svg>
|
|
View CV ↗
|
|
</a>
|
|
|
|
<a
|
|
href={resumeUrl}
|
|
download="CV-Cris-Charles-Garcia.pdf"
|
|
class="inline-flex items-center justify-center gap-1.5 px-3 py-2 rounded-xl border border-border-custom hover:border-primary-custom/40 text-foreground-custom text-xs font-medium hover:bg-primary-custom/5 transition-all text-center"
|
|
>
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
|
|
</svg>
|
|
Download PDF
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Social Links Bento Matrix */}
|
|
<div class="w-full flex flex-col gap-3">
|
|
{links.map((link) => (
|
|
<a
|
|
href={link.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class="bento-card p-4 flex items-center justify-between group hover:border-primary-custom/40 transition-all cursor-pointer"
|
|
>
|
|
<div class="flex items-center gap-3.5 min-w-0">
|
|
<div class="w-10 h-10 rounded-xl bg-muted-custom/40 border border-border-custom flex items-center justify-center text-primary-custom shrink-0 group-hover:scale-105 transition-transform" set:html={getIconSvg(link.platform)}></div>
|
|
<div class="flex flex-col min-w-0">
|
|
<span class="text-sm font-bold font-heading text-foreground-custom group-hover:text-primary-custom transition-colors leading-tight">
|
|
{link.platform}
|
|
</span>
|
|
<span class="text-[11px] font-mono text-muted-foreground-custom truncate leading-tight mt-0.5" title={link.url}>
|
|
{formatDisplayUrl(link.url)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<span class="text-xs text-muted-foreground-custom group-hover:text-primary-custom group-hover:translate-x-0.5 transition-all shrink-0 ml-3">
|
|
↗
|
|
</span>
|
|
</a>
|
|
))}
|
|
|
|
{/* Home site link */}
|
|
<a
|
|
href="/"
|
|
class="bento-card p-4 flex items-center justify-between group hover:border-primary-custom/40 transition-all mt-2"
|
|
>
|
|
<div class="flex items-center gap-3.5">
|
|
<div class="w-10 h-10 rounded-xl bg-primary-custom/10 text-primary-custom flex items-center justify-center shrink-0">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
|
|
</svg>
|
|
</div>
|
|
<div class="flex flex-col">
|
|
<span class="text-sm font-bold font-heading text-foreground-custom group-hover:text-primary-custom transition-colors">
|
|
Main Portfolio
|
|
</span>
|
|
<span class="text-[11px] font-mono text-muted-foreground-custom">
|
|
Explore full projects & skills
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<span class="text-xs text-muted-foreground-custom group-hover:text-primary-custom group-hover:translate-x-0.5 transition-all">
|
|
→
|
|
</span>
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
</main>
|
|
|
|
<Footer fullName={settings.fullName} socialLinks={allLinks} client:load />
|
|
</Layout> |