Files
altbin.dev/app/about/page.tsx
T
2025-08-20 14:14:33 +02:00

173 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { Player } from "@lordicon/react";
import { motion } from "framer-motion";
import { ArrowLeft } from "lucide-react";
import { useRouter } from "next/navigation";
import { forwardRef, useEffect, useRef, useState } from "react";
// URLs dicônes Lordicon
const icons = {
simplicity: "https://cdn.lordicon.com/tsrgicte.json", // simplicité
shield: "https://cdn.lordicon.com/sjoccsdj.json", // sécurité
community: "https://cdn.lordicon.com/ubpgwkmy.json", // communauté / open source
github: "https://cdn.lordicon.com/jjxzcivr.json", // GitHub
discord: "https://cdn.lordicon.com/zvnxzuwv.json", // Discord
};
// Wrapper pour Lordicon
const LordIcon = forwardRef(function LordIcon(
{ url, size = 30, colorize = "#3b82f6" }: { url: string; size?: number; colorize?: string },
ref: any
) {
const [iconData, setIconData] = useState<any>(null);
useEffect(() => {
fetch(url).then((res) => res.json()).then(setIconData);
}, [url]);
if (!iconData) return null;
return <Player ref={ref} icon={iconData} size={size} colorize={colorize} />;
});
// Carte Feature
function FeatureCard({
title,
desc,
icon,
}: {
title: string;
desc: string;
icon: string;
}) {
const iconRef = useRef<any>(null);
return (
<motion.div
whileHover={{ scale: 1.03 }}
className="rounded-2xl bg-[#11131c] border border-white/10 p-6 shadow-lg hover:border-blue-500/40 transition-colors"
onMouseEnter={() => iconRef.current?.playFromBeginning()}
onMouseLeave={() => iconRef.current?.goToFirstFrame()}
>
<div className="flex items-center gap-3 mb-3">
<div className="p-2 rounded-xl bg-blue-500/20 text-blue-400">
<LordIcon ref={iconRef} url={icon} size={32} />
</div>
<h3 className="text-lg font-semibold">{title}</h3>
</div>
<p className="text-neutral-400 text-sm leading-relaxed">{desc}</p>
</motion.div>
);
}
// Bouton Contact
function ContactButton({
href,
icon,
text,
gradient,
shadow,
color = "#fff",
}: {
href: string;
icon: string;
text: string;
gradient: string;
shadow: string;
color?: string;
}) {
const iconRef = useRef<any>(null);
return (
<motion.a
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.97 }}
href={href}
target="_blank"
rel="noopener noreferrer"
className={`cursor-pointer inline-flex items-center gap-2 px-6 py-3 rounded-xl text-base font-medium text-white ${gradient} ${shadow} transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-400/60`}
onMouseEnter={() => iconRef.current?.playFromBeginning()}
onMouseLeave={() => iconRef.current?.goToFirstFrame()}
>
<LordIcon ref={iconRef} url={icon} size={32} colorize={color} />
<span>{text}</span>
</motion.a>
);
}
export default function AboutPage() {
const router = useRouter();
const features = [
{
title: "Simplicity",
desc: "Create a paste in seconds, distraction-free.",
icon: icons.simplicity,
},
{
title: "Security",
desc: "Protect your posts with a password or limited number of views.",
icon: icons.shield,
},
{
title: "Open Source",
desc: "Contribute to the project and improve the platform.",
icon: icons.community,
},
];
return (
<div className="p-8 relative min-h-screen bg-[#0e0f13] text-white">
{/* Navbar */}
<div className="flex justify-between items-center mb-12 max-w-6xl mx-auto">
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.97 }}
onClick={() => router.back()}
className="cursor-pointer inline-flex items-center gap-2 px-5 py-2 rounded-xl text-sm font-medium
text-white bg-gradient-to-r from-blue-600 to-blue-500 shadow-lg shadow-blue-500/30
hover:shadow-blue-500/50 transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-blue-400/60"
>
<ArrowLeft size={18} className="text-blue-200" />
Back
</motion.button>
<h1 className="text-lg font-bold text-neutral-300">AltBin</h1>
</div>
{/* Features */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-6 max-w-6xl mx-auto">
{features.map((f, i) => (
<FeatureCard key={i} title={f.title} desc={f.desc} icon={f.icon} />
))}
</div>
{/* Contact */}
<div className="mt-20 max-w-2xl mx-auto text-center">
<h2 className="text-xl md:text-2xl font-bold mb-4">Contact</h2>
<p className="text-neutral-400 mb-8">
Any <span className="text-blue-400">questions</span> or{" "}
<span className="text-blue-400">suggestions</span>?
Join the community or check out the source code
</p>
<div className="flex justify-center gap-4 flex-wrap">
<ContactButton
href="https://discord.gg/ton-serveur"
icon={icons.discord}
text="Join Discord"
gradient="bg-gradient-to-r from-indigo-600 to-indigo-500"
shadow="shadow-lg shadow-indigo-500/30 hover:shadow-indigo-500/50"
/>
<ContactButton
href="https://github.com/UltraLionfr/altbin.dev"
icon={icons.github}
text="GitHub"
gradient="bg-gradient-to-r from-gray-800 to-gray-700"
shadow="shadow-lg shadow-black/30 hover:shadow-blue-500/40"
/>
</div>
</div>
</div>
);
}