111 lines
4.2 KiB
TypeScript
111 lines
4.2 KiB
TypeScript
import { motion } from 'framer-motion';
|
|
import { ExternalLink, Book, Wrench, Code, Server } from 'lucide-react';
|
|
|
|
const resourceCategories = [
|
|
{
|
|
title: 'Documentation',
|
|
icon: Book,
|
|
resources: [
|
|
{ name: 'MDN Web Docs', url: 'https://developer.mozilla.org', description: 'Web development reference' },
|
|
{ name: 'React Documentation', url: 'https://react.dev', description: 'Official React docs' },
|
|
{ name: 'TypeScript Handbook', url: 'https://www.typescriptlang.org/docs/', description: 'TypeScript guide' },
|
|
],
|
|
},
|
|
{
|
|
title: 'Development Tools',
|
|
icon: Wrench,
|
|
resources: [
|
|
{ name: 'Neovim', url: 'https://neovim.io', description: 'Hyperextensible Vim-based text editor' },
|
|
{ name: 'GitHub', url: 'https://github.com', description: 'Version control & collaboration' },
|
|
{ name: 'Gitea', url: 'https://gitea.io', description: 'Self-hosted Git service' },
|
|
{ name: 'Figma', url: 'https://figma.com', description: 'Design & prototyping' },
|
|
],
|
|
},
|
|
{
|
|
title: 'Frameworks & Libraries',
|
|
icon: Code,
|
|
resources: [
|
|
{ name: 'Tailwind CSS', url: 'https://tailwindcss.com', description: 'Utility-first CSS framework' },
|
|
{ name: 'Framer Motion', url: 'https://www.framer.com/motion/', description: 'Animation library for React' },
|
|
{ name: 'Vite', url: 'https://vitejs.dev', description: 'Fast build tool' },
|
|
],
|
|
},
|
|
{
|
|
title: 'Self-Hosting & Infrastructure',
|
|
icon: Server,
|
|
resources: [
|
|
{ name: 'Proxmox', url: 'https://www.proxmox.com', description: 'Virtualization platform' },
|
|
{ name: 'Docker', url: 'https://docker.com', description: 'Container platform' },
|
|
{ name: 'Caddy', url: 'https://caddyserver.com', description: 'Web server with automatic HTTPS' },
|
|
],
|
|
},
|
|
];
|
|
|
|
const Resources = () => {
|
|
return (
|
|
<motion.div
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
transition={{ duration: 0.5 }}
|
|
className="space-y-6"
|
|
>
|
|
<h1 className="font-minecraft text-3xl md:text-4xl text-primary text-glow-strong">
|
|
Resources
|
|
</h1>
|
|
|
|
<p className="font-pixel text-foreground/80">
|
|
Tools, documentation, and resources I recommend:
|
|
</p>
|
|
|
|
<div className="space-y-6">
|
|
{resourceCategories.map((category, categoryIndex) => {
|
|
const Icon = category.icon;
|
|
return (
|
|
<motion.div
|
|
key={category.title}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ delay: categoryIndex * 0.1 }}
|
|
className="space-y-3"
|
|
>
|
|
<div className="flex items-center gap-2">
|
|
<Icon className="w-5 h-5 text-primary" />
|
|
<h2 className="font-minecraft text-xl text-primary text-glow">
|
|
{category.title}
|
|
</h2>
|
|
</div>
|
|
|
|
<div className="grid gap-2 pl-7">
|
|
{category.resources.map((resource, index) => (
|
|
<motion.a
|
|
key={resource.name}
|
|
href={resource.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
initial={{ opacity: 0, x: -10 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
transition={{ delay: categoryIndex * 0.1 + index * 0.05 }}
|
|
className="group flex items-center justify-between p-3 border border-primary/20 hover:border-primary/60 transition-all duration-300 hover:bg-primary/5"
|
|
>
|
|
<div className="flex flex-col">
|
|
<span className="font-minecraft text-sm text-primary">
|
|
{resource.name}
|
|
</span>
|
|
<span className="font-pixel text-xs text-foreground/60">
|
|
{resource.description}
|
|
</span>
|
|
</div>
|
|
<ExternalLink className="w-4 h-4 text-primary opacity-0 group-hover:opacity-100 transition-opacity" />
|
|
</motion.a>
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</div>
|
|
</motion.div>
|
|
);
|
|
};
|
|
|
|
export default Resources;
|