added tech logo

This commit is contained in:
kinou-p 2025-10-02 14:12:10 +02:00
parent 8bb93301b9
commit ea9ba687a8
6 changed files with 140 additions and 49 deletions

View File

@ -7,11 +7,12 @@ interface ProjectCardProps {
description: string;
icon: React.ReactNode;
image?: string;
technologies?: { name: string; iconUrl?: string }[];
delay?: number;
projectId?: string;
}
export const ProjectCard = ({ title, description, icon, image, delay = 0, projectId }: ProjectCardProps) => {
export const ProjectCard = ({ title, description, icon, image, technologies, delay = 0, projectId }: ProjectCardProps) => {
const navigate = useNavigate();
const handleClick = () => {
@ -47,9 +48,35 @@ export const ProjectCard = ({ title, description, icon, image, delay = 0, projec
<CardTitle className="text-xl pr-20">{title}</CardTitle>
</CardHeader>
<CardContent>
<CardDescription className="text-base leading-relaxed">
<CardDescription className="text-base leading-relaxed mb-4">
{description}
</CardDescription>
{technologies && technologies.length > 0 && (
<div className="flex flex-wrap gap-2">
{technologies.slice(0, 6).map((tech, index) => (
<div
key={tech.name}
className="w-8 h-8 rounded bg-background/50 p-1.5 flex items-center justify-center"
title={tech.name}
>
{tech.iconUrl ? (
<img
src={tech.iconUrl}
alt={tech.name}
className="w-full h-full object-contain"
/>
) : (
<span className="text-xs">?</span>
)}
</div>
))}
{technologies.length > 6 && (
<div className="w-8 h-8 rounded bg-background/50 flex items-center justify-center text-xs text-muted-foreground">
+{technologies.length - 6}
</div>
)}
</div>
)}
</CardContent>
</Card>
</motion.div>

View File

@ -4,11 +4,12 @@ import { Badge } from "@/components/ui/badge";
interface SkillBadgeProps {
name: string;
icon?: string;
iconUrl?: string;
color?: string;
delay?: number;
}
export const SkillBadge = ({ name, icon, color = "default", delay = 0 }: SkillBadgeProps) => {
export const SkillBadge = ({ name, icon, iconUrl, color = "default", delay = 0 }: SkillBadgeProps) => {
return (
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
@ -21,7 +22,11 @@ export const SkillBadge = ({ name, icon, color = "default", delay = 0 }: SkillBa
variant="secondary"
className="text-base py-2 px-4 font-medium hover:bg-primary hover:text-primary-foreground transition-colors"
>
{icon && <span className="mr-2">{icon}</span>}
{iconUrl ? (
<img src={iconUrl} alt={`${name} logo`} className="mr-2 w-5 h-5" />
) : icon ? (
<span className="mr-2">{icon}</span>
) : null}
{name}
</Badge>
</motion.div>

View File

@ -1,6 +1,7 @@
import { motion } from "framer-motion";
import { useLanguage } from "@/contexts/LanguageContext";
import { ProjectCard } from "@/components/ProjectCard";
import { projectsData } from "@/data/projects";
import { Server, Gamepad2, Cloud, Terminal, Box, Globe, Scale } from "lucide-react";
export const ProjectsSection = () => {
@ -70,6 +71,7 @@ export const ProjectsSection = () => {
description={t(`projects.items.${project.key}.description`)}
icon={project.icon}
image={project.image}
technologies={projectsData[project.key]?.technologies}
delay={index * 0.1}
projectId={project.key}
/>

View File

@ -6,17 +6,73 @@ export const SkillsSection = () => {
const { t } = useLanguage();
const languages = [
{ name: "JavaScript", icon: "📜" },
{ name: "TypeScript", icon: "📘" },
{ name: "Python", icon: "🐍" },
{ name: "C/C++", icon: "⚙️" },
{
name: "JavaScript",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg"
},
{
name: "TypeScript",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg"
},
{
name: "Python",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg"
},
{
name: "C/C++",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cplusplus/cplusplus-original.svg"
},
{
name: "HTML5",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/html5/html5-original.svg"
},
{
name: "CSS3",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/css3/css3-original.svg"
},
];
const frameworks = [
{ name: "React", icon: "⚛️" },
{ name: "Node.js", icon: "📗" },
{ name: "Docker", icon: "🐳" },
{ name: "Linux", icon: "🐧" },
{
name: "React",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/react/react-original.svg"
},
{
name: "Node.js",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/nodejs/nodejs-original.svg"
},
{
name: "NestJS",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/nestjs/nestjs-original.svg"
},
{
name: "Docker",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/docker/docker-original.svg"
},
{
name: "Linux",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/linux/linux-original.svg"
},
{
name: "PostgreSQL",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/postgresql/postgresql-original.svg"
},
{
name: "MongoDB",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/mongodb/mongodb-original.svg"
},
{
name: "MySQL",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/mysql/mysql-original.svg"
},
{
name: "Ansible",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/ansible/ansible-original.svg"
},
{
name: "WordPress",
iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/wordpress/wordpress-original.svg"
},
];
return (
@ -52,7 +108,7 @@ export const SkillsSection = () => {
<SkillBadge
key={skill.name}
name={skill.name}
icon={skill.icon}
iconUrl={skill.iconUrl}
delay={index * 0.1}
/>
))}
@ -73,7 +129,7 @@ export const SkillsSection = () => {
<SkillBadge
key={skill.name}
name={skill.name}
icon={skill.icon}
iconUrl={skill.iconUrl}
delay={index * 0.1}
/>
))}

View File

@ -10,7 +10,7 @@ export interface ProjectData {
solution: { fr: string; en: string };
images: string[];
mainImage: string;
technologies: { name: string; color?: string; icon?: string }[];
technologies: { name: string; color?: string; icon?: string; iconUrl?: string }[];
githubUrl?: string;
demoUrl?: string;
}
@ -62,12 +62,12 @@ export const projectsData: Record<string, ProjectData> = {
mainImage: "/images/projects/homemade_nas.png",
images: ["/images/projects/homemade_nas.png"],
technologies: [
{ name: "OpenMediaVault" },
{ name: "Docker" },
{ name: "Traefik" },
{ name: "Linux" },
{ name: "Home Assistant" },
{ name: "Portainer" },
{ name: "OpenMediaVault", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/debian/debian-original.svg" },
{ name: "Docker", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/docker/docker-original.svg" },
{ name: "Traefik", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/kubernetes/kubernetes-plain.svg" },
{ name: "Linux", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/linux/linux-original.svg" },
{ name: "Home Assistant", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg" },
{ name: "Portainer", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/docker/docker-original.svg" },
],
},
transcendence: {
@ -116,12 +116,12 @@ export const projectsData: Record<string, ProjectData> = {
mainImage: "/images/projects/pong.png",
images: ["/images/projects/pong.png"],
technologies: [
{ name: "React", icon: "⚛️" },
{ name: "TypeScript" },
{ name: "NestJS" },
{ name: "PostgreSQL" },
{ name: "WebSocket" },
{ name: "Docker" },
{ name: "React", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/react/react-original.svg" },
{ name: "TypeScript", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg" },
{ name: "NestJS", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/nestjs/nestjs-original.svg" },
{ name: "PostgreSQL", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/postgresql/postgresql-original.svg" },
{ name: "WebSocket", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg" },
{ name: "Docker", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/docker/docker-original.svg" },
],
},
cloud: {
@ -170,11 +170,11 @@ export const projectsData: Record<string, ProjectData> = {
mainImage: "/images/projects/cloud_1.png",
images: ["/images/projects/cloud_1.png"],
technologies: [
{ name: "Docker", icon: "🐳" },
{ name: "Ansible" },
{ name: "WordPress" },
{ name: "MySQL" },
{ name: "Linux" },
{ name: "Docker", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/docker/docker-original.svg" },
{ name: "Ansible", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/ansible/ansible-original.svg" },
{ name: "WordPress", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/wordpress/wordpress-original.svg" },
{ name: "MySQL", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/mysql/mysql-original.svg" },
{ name: "Linux", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/linux/linux-original.svg" },
],
},
minishell: {
@ -223,10 +223,10 @@ export const projectsData: Record<string, ProjectData> = {
mainImage: "/images/projects/minishell.png",
images: ["/images/projects/minishell.png"],
technologies: [
{ name: "C" },
{ name: "Linux" },
{ name: "POSIX" },
{ name: "Make" },
{ name: "C", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/c/c-original.svg" },
{ name: "Linux", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/linux/linux-original.svg" },
{ name: "POSIX", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/unix/unix-original.svg" },
{ name: "Make", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cmake/cmake-original.svg" },
],
},
cube3d: {
@ -275,10 +275,10 @@ export const projectsData: Record<string, ProjectData> = {
mainImage: "/images/projects/cub3d.png",
images: ["/images/projects/cub3d.png"],
technologies: [
{ name: "C" },
{ name: "MiniLibX" },
{ name: "Raycasting" },
{ name: "Make" },
{ name: "C", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/c/c-original.svg" },
{ name: "MiniLibX", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/c/c-original.svg" },
{ name: "Raycasting", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cplusplus/cplusplus-original.svg" },
{ name: "Make", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cmake/cmake-original.svg" },
],
},
etsidemain: {
@ -336,10 +336,10 @@ export const projectsData: Record<string, ProjectData> = {
"/images/sites/etsidemain/tel.png"
],
technologies: [
{ name: "HTML5" },
{ name: "CSS3" },
{ name: "JavaScript" },
{ name: "SEO" },
{ name: "HTML5", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/html5/html5-original.svg" },
{ name: "CSS3", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/css3/css3-original.svg" },
{ name: "JavaScript", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg" },
{ name: "SEO", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/google/google-original.svg" },
],
demoUrl: "https://etsidemain.com",
},
@ -398,11 +398,11 @@ export const projectsData: Record<string, ProjectData> = {
"/images/sites/avopieces/tel.png"
],
technologies: [
{ name: "React", icon: "⚛️" },
{ name: "Node.js", icon: "📗" },
{ name: "MongoDB" },
{ name: "OpenAI" },
{ name: "TypeScript" },
{ name: "React", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/react/react-original.svg" },
{ name: "Node.js", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/nodejs/nodejs-original.svg" },
{ name: "MongoDB", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/mongodb/mongodb-original.svg" },
{ name: "OpenAI", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg" },
{ name: "TypeScript", iconUrl: "https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/typescript/typescript-original.svg" },
],
demoUrl: "https://avopieces.fr",
},

View File

@ -69,6 +69,7 @@ const ProjectPageContent = () => {
key={tech.name}
name={tech.name}
icon={tech.icon}
iconUrl={tech.iconUrl}
delay={index * 0.05}
/>
))}