mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
- Create @manacore/shared-landing-ui package with reusable components (FeatureSection, StepsSection, FAQSection, CTASection, Card atoms) - Add complete landing page for manadeck app - Refactor märchenzauber landing to use shared components (remove local CTA, FAQ, Features, HowItWorks sections) - Add German localization for manacore and memoro landing pages - Update workspace configuration and package dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
169 lines
7.4 KiB
Text
169 lines
7.4 KiB
Text
---
|
|
/**
|
|
* Shared Footer component
|
|
* Highly configurable footer for landing pages
|
|
*/
|
|
import Container from '../atoms/Container.astro';
|
|
import Button from '../atoms/Button.astro';
|
|
|
|
interface FooterLink {
|
|
label: string;
|
|
href: string;
|
|
icon?: string;
|
|
external?: boolean;
|
|
}
|
|
|
|
interface FooterSection {
|
|
title: string;
|
|
links: FooterLink[];
|
|
}
|
|
|
|
interface SocialLink {
|
|
platform: 'linkedin' | 'twitter' | 'facebook' | 'instagram' | 'youtube' | 'github';
|
|
href: string;
|
|
}
|
|
|
|
interface Props {
|
|
brand: {
|
|
name: string;
|
|
tagline?: string;
|
|
logo?: string;
|
|
};
|
|
sections?: FooterSection[];
|
|
socialLinks?: SocialLink[];
|
|
copyright?: string;
|
|
ctaButton?: {
|
|
text: string;
|
|
href: string;
|
|
variant?: 'primary' | 'secondary';
|
|
};
|
|
secondaryButton?: {
|
|
text: string;
|
|
href: string;
|
|
};
|
|
class?: string;
|
|
lang?: string;
|
|
}
|
|
|
|
const {
|
|
brand,
|
|
sections = [],
|
|
socialLinks = [],
|
|
copyright,
|
|
ctaButton,
|
|
secondaryButton,
|
|
class: className = '',
|
|
lang = 'de'
|
|
} = Astro.props;
|
|
|
|
const currentYear = new Date().getFullYear();
|
|
|
|
const socialIcons = {
|
|
linkedin: `<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-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.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"/>`,
|
|
twitter: `<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"/>`,
|
|
facebook: `<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.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>`,
|
|
instagram: `<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/>`,
|
|
youtube: `<path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/>`,
|
|
github: `<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"/>`
|
|
};
|
|
|
|
const socialHoverColors = {
|
|
linkedin: 'hover:text-[#0077b5]',
|
|
twitter: 'hover:text-white',
|
|
facebook: 'hover:text-[#1877f2]',
|
|
instagram: 'hover:text-[#E4405F]',
|
|
youtube: 'hover:text-[#FF0000]',
|
|
github: 'hover:text-white'
|
|
};
|
|
---
|
|
|
|
<footer class:list={["bg-[var(--color-background-page)] py-12 md:py-16", className]}>
|
|
<Container>
|
|
{/* Main Footer Grid */}
|
|
{sections.length > 0 && (
|
|
<div class:list={[
|
|
"grid gap-8 mb-12",
|
|
sections.length === 2 && "grid-cols-2 md:grid-cols-4",
|
|
sections.length === 3 && "grid-cols-2 md:grid-cols-3 lg:grid-cols-4",
|
|
sections.length >= 4 && "grid-cols-2 md:grid-cols-4 lg:grid-cols-5"
|
|
]}>
|
|
{sections.map((section) => (
|
|
<div class="flex flex-col">
|
|
<h3 class="text-xs sm:text-sm font-medium text-[var(--color-text-muted)] uppercase tracking-wider mb-4">
|
|
{section.title}
|
|
</h3>
|
|
<ul class="space-y-2">
|
|
{section.links.map((link) => (
|
|
<li>
|
|
<a
|
|
href={link.href}
|
|
class="flex items-center gap-2 px-3 py-2 bg-white/5 hover:bg-white/10 rounded-lg text-sm transition-all text-[var(--color-text-secondary)] hover:text-[var(--color-text-primary)]"
|
|
target={link.external ? "_blank" : undefined}
|
|
rel={link.external ? "noopener noreferrer" : undefined}
|
|
>
|
|
{link.icon && <span class="w-4 h-4">{link.icon}</span>}
|
|
{link.label}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{/* Social Links */}
|
|
{socialLinks.length > 0 && (
|
|
<div class="border-t border-[var(--color-border)] pt-8 mb-8">
|
|
<div class="flex justify-center space-x-6">
|
|
{socialLinks.map((social) => (
|
|
<a
|
|
href={social.href}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
class:list={[
|
|
"text-[var(--color-text-muted)] transition-colors",
|
|
socialHoverColors[social.platform]
|
|
]}
|
|
>
|
|
<span class="sr-only">{social.platform}</span>
|
|
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
|
<Fragment set:html={socialIcons[social.platform]} />
|
|
</svg>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* CTA Buttons */}
|
|
{(ctaButton || secondaryButton) && (
|
|
<div class="flex flex-col sm:flex-row gap-4 justify-center mb-8">
|
|
{secondaryButton && (
|
|
<Button href={secondaryButton.href} variant="secondary" size="md">
|
|
{secondaryButton.text}
|
|
</Button>
|
|
)}
|
|
{ctaButton && (
|
|
<Button href={ctaButton.href} variant={ctaButton.variant ?? 'primary'} size="md">
|
|
{ctaButton.text}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{/* Copyright */}
|
|
<div class="text-center">
|
|
<p class="text-[var(--color-text-muted)] text-xs sm:text-sm">
|
|
{copyright || `© ${currentYear} ${brand.name}. All rights reserved.`}
|
|
</p>
|
|
{brand.tagline && (
|
|
<p class="text-[var(--color-text-muted)] text-xs mt-1">
|
|
{brand.tagline}
|
|
</p>
|
|
)}
|
|
</div>
|
|
|
|
<slot />
|
|
</Container>
|
|
</footer>
|