Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Failing after 7m46s
- Updated deployment script to check for existing containers and free ports before starting a new container. - Added a new script to check the status of the Gitea runner, including service checks, running processes, Docker containers, common directories, and network connections.
146 lines
5.6 KiB
TypeScript
146 lines
5.6 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import { Heart, Code } from 'lucide-react';
|
|
import { SiGithub, SiLinkedin } from 'react-icons/si';
|
|
import Link from 'next/link';
|
|
import { useLocale, useTranslations } from "next-intl";
|
|
import { useConsent } from "./ConsentProvider";
|
|
|
|
const Footer = () => {
|
|
const locale = useLocale();
|
|
const t = useTranslations("footer");
|
|
const { resetConsent } = useConsent();
|
|
|
|
const [currentYear] = useState(() => new Date().getFullYear());
|
|
|
|
const socialLinks = [
|
|
{ icon: SiGithub, href: 'https://github.com/Denshooter', label: 'GitHub' },
|
|
{ icon: SiLinkedin, href: 'https://linkedin.com/in/dkonkol', label: 'LinkedIn' }
|
|
];
|
|
|
|
return (
|
|
<footer className="relative py-12 px-4 bg-white border-t border-stone-200">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="flex flex-col md:flex-row justify-between items-center space-y-6 md:space-y-0">
|
|
{/* Brand */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
transition={{ duration: 0.4 }}
|
|
className="flex items-center space-x-3"
|
|
>
|
|
<motion.div
|
|
whileHover={{ rotate: 360, scale: 1.1 }}
|
|
transition={{ duration: 0.5 }}
|
|
className="w-12 h-12 bg-gradient-to-br from-liquid-mint to-liquid-lavender rounded-xl flex items-center justify-center shadow-md"
|
|
>
|
|
<Code className="w-6 h-6 text-stone-800" />
|
|
</motion.div>
|
|
<div>
|
|
<Link href={`/${locale}`} className="text-xl font-bold font-mono text-stone-800 hover:text-liquid-blue transition-colors">
|
|
dk<span className="text-liquid-rose">0</span>
|
|
</Link>
|
|
<p className="text-xs text-stone-500">{t("role")}</p>
|
|
</div>
|
|
</motion.div>
|
|
|
|
{/* Social Links */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
transition={{ duration: 0.4, delay: 0.05 }}
|
|
className="flex space-x-3"
|
|
>
|
|
{socialLinks.map((social) => (
|
|
<motion.a
|
|
key={social.label}
|
|
href={social.href}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
whileHover={{ scale: 1.15, y: -3 }}
|
|
whileTap={{ scale: 0.95 }}
|
|
className="p-3 bg-stone-50 hover:bg-white rounded-xl text-stone-600 hover:text-stone-900 transition-all duration-200 border border-stone-200 hover:border-stone-300 shadow-sm"
|
|
aria-label={social.label}
|
|
>
|
|
<social.icon size={18} />
|
|
</motion.a>
|
|
))}
|
|
</motion.div>
|
|
|
|
{/* Copyright */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
transition={{ duration: 0.4, delay: 0.1 }}
|
|
className="flex items-center space-x-2 text-stone-400 text-sm"
|
|
>
|
|
<span>© {currentYear}</span>
|
|
<motion.div
|
|
animate={{ scale: [1, 1.2, 1] }}
|
|
transition={{ duration: 1.5, repeat: Infinity }}
|
|
>
|
|
<Heart size={14} className="text-liquid-rose fill-liquid-rose" />
|
|
</motion.div>
|
|
<span>{t("madeIn")}</span>
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Legal Links */}
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 10 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
transition={{ duration: 0.4, delay: 0.15 }}
|
|
className="mt-8 pt-6 border-t border-stone-100 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0"
|
|
>
|
|
<div className="flex space-x-6 text-sm">
|
|
<Link
|
|
href={`/${locale}/legal-notice`}
|
|
className="text-stone-500 hover:text-stone-800 transition-colors duration-200"
|
|
>
|
|
{t("legalNotice")}
|
|
</Link>
|
|
<Link
|
|
href={`/${locale}/privacy-policy`}
|
|
className="text-stone-500 hover:text-stone-800 transition-colors duration-200"
|
|
>
|
|
{t("privacyPolicy")}
|
|
</Link>
|
|
<button
|
|
type="button"
|
|
onClick={() => resetConsent()}
|
|
className="text-stone-500 hover:text-stone-800 transition-colors duration-200"
|
|
title={t("privacySettingsTitle")}
|
|
>
|
|
{t("privacySettings")}
|
|
</button>
|
|
<Link
|
|
href="/404"
|
|
className="text-stone-500 hover:text-stone-800 transition-colors duration-200 font-mono text-xs"
|
|
title="Kernel Panic 404"
|
|
>
|
|
404
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="text-xs text-stone-400 flex items-center space-x-1">
|
|
<span>{t("builtWith")}</span>
|
|
<span className="text-stone-600 font-semibold">Next.js</span>
|
|
<span className="text-stone-300">•</span>
|
|
<span className="text-stone-600 font-semibold">TypeScript</span>
|
|
<span className="text-stone-300">•</span>
|
|
<span className="text-stone-600 font-semibold">Tailwind CSS</span>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</footer>
|
|
);
|
|
};
|
|
|
|
export default Footer;
|