Add Font Awesome icons and refactor tech icon handling

- Added Font Awesome dependencies for enhanced icon support.
- Refactored tech icon components to utilize Font Awesome icons instead of custom SVGs.
- Updated skill data files to include icon properties for various technologies.
- Removed obsolete tech icon files to streamline the codebase.
This commit is contained in:
Julien Froidefond
2025-08-20 16:24:07 +02:00
parent e6d4bbe13d
commit f74d4d3e87
27 changed files with 793 additions and 539 deletions

View File

@@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { GeistSans } from "geist/font/sans";
import { GeistMono } from "geist/font/mono";
import "./globals.css";
import "@/lib/fontawesome"; // Configuration Font Awesome
import { ThemeProvider } from "@/components/layout/theme-provider";
import { Toaster } from "@/components/ui/sonner";
import { UserProvider } from "@/hooks/use-user-context";

View File

@@ -15,7 +15,7 @@ import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { generateRadarData } from "@/lib/evaluation-utils";
import { useUser } from "@/hooks/use-user-context";
import { getTechIcon } from "@/components/icons/tech-icons";
import { TechIcon } from "@/components/icons/tech-icon";
import Link from "next/link";
import { Code2, ChevronDown, ChevronRight, ExternalLink } from "lucide-react";
import { getCategoryIcon } from "@/lib/category-icons";
@@ -221,15 +221,17 @@ export default function HomePage() {
const skillEval = categoryEval.skills.find(
(s) => s.skillId === skillId
);
const TechIcon = getTechIcon(skill.id);
return (
<div
key={skillId}
className="flex items-center justify-between p-2 bg-white/5 border border-white/10 rounded-lg"
>
<div className="flex items-center gap-2">
<TechIcon className="w-4 h-4 text-blue-400" />
<TechIcon
iconName={skill.icon}
className="w-4 h-4 text-blue-400"
fallbackText={skill.name}
/>
<span className="text-sm text-white">
{skill.name}
</span>

View File

@@ -5,7 +5,7 @@ import {
TooltipTrigger,
} from "@/components/ui/tooltip";
import { Skill, SkillLevel, SKILL_LEVELS } from "@/lib/types";
import { getTechIcon } from "@/components/icons/tech-icons";
import { TechIcon } from "@/components/icons/tech-icon";
interface SkillEvaluationCardProps {
skill: Skill;
@@ -46,15 +46,17 @@ export function SkillEvaluationCard({
onUpdateSkill,
onRemoveSkill,
}: SkillEvaluationCardProps) {
const TechIcon = getTechIcon(skill.id);
return (
<div className="group relative bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl p-3 hover:bg-white/10 hover:border-white/20 transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/10">
<div className="flex items-center justify-between">
{/* Skill Info */}
<div className="flex items-center gap-3 flex-1 min-w-0">
<div className="w-8 h-8 rounded-lg bg-white/10 border border-white/20 flex items-center justify-center group-hover:bg-white/20 transition-colors flex-shrink-0">
<TechIcon className="w-4 h-4 text-blue-400" />
<TechIcon
iconName={skill.icon}
className="w-4 h-4 text-blue-400"
fallbackText={skill.name}
/>
</div>
<div className="flex items-center gap-2 flex-1 min-w-0">

View File

@@ -1,108 +0,0 @@
"use client";
import { getTechIcon } from "./tech-icons";
interface SmartTechIconProps {
techId: string;
techName: string;
className?: string;
fallbackStyle?: "initial" | "emoji" | "gradient";
}
// Emojis pour certaines technologies populaires
const TECH_EMOJIS: Record<string, string> = {
react: "⚛️",
vue: "💚",
typescript: "🔷",
nextjs: "▲",
nodejs: "🟢",
python: "🐍",
javascript: "💛",
html: "🧡",
css: "💙",
docker: "🐳",
kubernetes: "☸️",
aws: "☁️",
git: "🌿",
github: "🐙",
mongodb: "🍃",
postgresql: "🐘",
redis: "🔴",
mysql: "🐬",
flutter: "💙",
swift: "🦉",
kotlin: "🟣",
java: "☕",
php: "🐘",
ruby: "💎",
go: "🐹",
rust: "🦀",
csharp: "💜",
};
export function SmartTechIcon({
techId,
techName,
className = "w-6 h-6",
fallbackStyle = "initial",
}: SmartTechIconProps) {
// Essayer d'abord l'icône SVG locale
const TechIcon = getTechIcon(techId);
// Si ce n'est pas l'icône par défaut, l'utiliser
if (TechIcon !== getTechIcon("default")) {
return <TechIcon className={className} />;
}
// Sinon, utiliser le style de fallback
switch (fallbackStyle) {
case "emoji":
const emoji = TECH_EMOJIS[techId];
if (emoji) {
return (
<div
className={`${className} flex items-center justify-center text-lg`}
>
{emoji}
</div>
);
}
break;
case "gradient":
const gradientColors = [
"from-blue-500 to-purple-500",
"from-green-500 to-blue-500",
"from-red-500 to-pink-500",
"from-yellow-500 to-orange-500",
"from-purple-500 to-indigo-500",
];
const colorIndex = techId.length % gradientColors.length;
return (
<div
className={`${className} bg-gradient-to-br ${gradientColors[colorIndex]} rounded flex items-center justify-center text-white text-xs font-bold`}
>
{techName.charAt(0).toUpperCase()}
</div>
);
default: // "initial"
return (
<div
className={`${className} bg-muted rounded flex items-center justify-center text-xs font-bold`}
>
{techName.charAt(0).toUpperCase()}
</div>
);
}
// Fallback final
return (
<div
className={`${className} bg-muted rounded flex items-center justify-center text-xs font-bold`}
>
{techName.charAt(0).toUpperCase()}
</div>
);
}

View File

@@ -1,77 +1,263 @@
"use client";
import Image from "next/image";
import { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
import {
faReact,
faVuejs,
faJs,
faNodeJs,
faPython,
faJava,
faPhp,
faGolang,
faRust,
faDocker,
faAws,
faGoogle,
faMicrosoft,
faGitAlt,
faLinux,
faApple,
faWindows,
faAndroid,
faSwift,
faGithub,
faGitlab,
faBitbucket,
faFigma,
faSketch,
faWordpress,
faShopify,
faSlack,
faDiscord,
faDropbox,
faGoogle as faGoogleBrands,
faYarn,
faNpm,
faConfluence,
faJira,
faNotion,
} from "@fortawesome/free-brands-svg-icons";
interface TechIconExternalProps {
techId: string;
techName: string;
import {
faServer,
faDatabase,
faCloud,
faCode,
faCog,
faDesktop,
faMobile,
faShield,
faPalette,
faRocket,
faCube,
faPlug,
faTools,
faNetworkWired,
faLock,
faEye,
faSearch,
faBug,
faFlask,
faLayerGroup,
faSync,
faBolt,
faGlobe,
faHdd,
faMemory,
faSignal,
faTerminal,
faFileCode,
faPuzzlePiece,
faAtom,
faWrench,
faCodeBranch,
faBroadcastTower,
faInfinity,
faChartLine,
faUserShield,
faKey,
faSitemap,
faClipboardCheck,
faUsers,
faComment,
faHeadset,
faBookOpen,
faLightbulb,
faSpinner,
faBoxes,
faStream,
} from "@fortawesome/free-solid-svg-icons";
import {
Monitor,
Smartphone,
Shield,
BarChart3,
Palette,
Server,
} from "lucide-react";
interface TechIconProps {
iconName?: string;
className?: string;
size?: number;
fallbackText?: string;
}
// Service Simple Icons pour récupérer les icônes SVG
export function TechIconExternal({
techId,
techName,
className = "w-6 h-6",
size = 24,
}: TechIconExternalProps) {
const [imageError, setImageError] = useState(false);
// Mapping des icônes par nom
const ICON_MAP: Record<string, IconDefinition | React.ComponentType<any>> = {
// Brands
"fab-react": faReact,
"fab-vue": faVuejs,
"fab-js": faJs,
"fab-node": faNodeJs,
"fab-python": faPython,
"fab-java": faJava,
"fab-php": faPhp,
"fab-golang": faGolang,
"fab-rust": faRust,
"fab-docker": faDocker,
"fab-aws": faAws,
"fab-google": faGoogle,
"fab-microsoft": faMicrosoft,
"fab-git": faGitAlt,
"fab-linux": faLinux,
"fab-apple": faApple,
"fab-windows": faWindows,
"fab-android": faAndroid,
"fab-swift": faSwift,
"fab-github": faGithub,
"fab-gitlab": faGitlab,
"fab-bitbucket": faBitbucket,
"fab-figma": faFigma,
"fab-sketch": faSketch,
// URL pour Simple Icons
const simpleIconUrl = `https://cdn.jsdelivr.net/npm/simple-icons@v9/${techId}.svg`;
"fab-wordpress": faWordpress,
"fab-shopify": faShopify,
"fab-slack": faSlack,
"fab-discord": faDiscord,
"fab-dropbox": faDropbox,
"fab-yarn": faYarn,
"fab-npm": faNpm,
"fab-confluence": faConfluence,
"fab-jira": faJira,
"fab-notion": faNotion,
// URL pour DevIcons
const devIconUrl = `https://cdn.jsdelivr.net/gh/devicons/devicon/icons/${techId}/${techId}-original.svg`;
// Solid icons
"fas-server": faServer,
"fas-database": faDatabase,
"fas-cloud": faCloud,
"fas-code": faCode,
"fas-cog": faCog,
"fas-desktop": faDesktop,
"fas-mobile": faMobile,
"fas-shield": faShield,
if (imageError) {
// Fallback vers initiale si l'icône n'existe pas
"fas-palette": faPalette,
"fas-rocket": faRocket,
"fas-cube": faCube,
"fas-plug": faPlug,
"fas-tools": faTools,
"fas-network": faNetworkWired,
"fas-lock": faLock,
"fas-eye": faEye,
"fas-search": faSearch,
"fas-bug": faBug,
"fas-flask": faFlask,
"fas-layers": faLayerGroup,
"fas-sync": faSync,
"fas-bolt": faBolt,
"fas-globe": faGlobe,
"fas-hdd": faHdd,
"fas-memory": faMemory,
"fas-signal": faSignal,
"fas-terminal": faTerminal,
"fas-file-code": faFileCode,
"fas-puzzle": faPuzzlePiece,
"fas-atom": faAtom,
"fas-wrench": faWrench,
"fas-code-branch": faCodeBranch,
"fas-broadcast": faBroadcastTower,
"fas-infinity": faInfinity,
"fas-chart-line": faChartLine,
"fas-user-shield": faUserShield,
"fas-key": faKey,
"fas-sitemap": faSitemap,
"fas-check": faClipboardCheck,
"fas-users": faUsers,
"fas-comment": faComment,
"fas-headset": faHeadset,
"fas-book": faBookOpen,
"fas-lightbulb": faLightbulb,
"fas-spinner": faSpinner,
"fas-boxes": faBoxes,
"fas-stream": faStream,
// Lucide icons (pour certaines catégories ou icônes spéciales)
"lucide-monitor": Monitor,
"lucide-smartphone": Smartphone,
"lucide-shield": Shield,
"lucide-bar-chart": BarChart3,
"lucide-palette": Palette,
"lucide-server": Server,
};
export const TechIcon: React.FC<TechIconProps> = ({
iconName,
className = "w-5 h-5",
fallbackText,
}) => {
if (!iconName) {
return (
<div
className={`${className} bg-muted rounded flex items-center justify-center text-xs font-bold`}
>
{techName.charAt(0).toUpperCase()}
{fallbackText ? fallbackText.charAt(0).toUpperCase() : "?"}
</div>
);
}
return (
<Image
src={simpleIconUrl}
alt={`${techName} icon`}
width={size}
height={size}
className={className}
onError={() => setImageError(true)}
style={{ filter: "brightness(0) saturate(100%) invert(0.5)" }} // Pour s'adapter au thème
/>
);
}
const IconComponent = ICON_MAP[iconName];
// Mapping des IDs pour Simple Icons (ils utilisent parfois des noms différents)
export const SIMPLE_ICONS_MAPPING: Record<string, string> = {
react: "react",
vue: "vuedotjs",
typescript: "typescript",
nextjs: "nextdotjs",
nodejs: "nodedotjs",
python: "python",
express: "express",
postgresql: "postgresql",
mongodb: "mongodb",
redis: "redis",
docker: "docker",
kubernetes: "kubernetes",
aws: "amazonwebservices",
terraform: "terraform",
jenkins: "jenkins",
githubactions: "githubactions",
reactnative: "react",
flutter: "flutter",
swift: "swift",
kotlin: "kotlin",
expo: "expo",
tailwindcss: "tailwindcss",
webpack: "webpack",
if (!IconComponent) {
return (
<div
className={`${className} bg-muted rounded flex items-center justify-center text-xs font-bold`}
>
{fallbackText
? fallbackText.charAt(0).toUpperCase()
: iconName.charAt(0).toUpperCase()}
</div>
);
}
// Font Awesome icon (IconDefinition has prefix, iconName, and icon properties)
if (typeof IconComponent === "object" && "prefix" in IconComponent && "iconName" in IconComponent) {
return (
<FontAwesomeIcon
icon={IconComponent as IconDefinition}
className={className}
/>
);
}
// Lucide icon (React component)
if (typeof IconComponent === "function") {
const LucideIcon = IconComponent as React.ComponentType<any>;
return <LucideIcon className={className} />;
}
// Fallback if something goes wrong
return (
<div
className={`${className} bg-muted rounded flex items-center justify-center text-xs font-bold`}
>
{fallbackText
? fallbackText.charAt(0).toUpperCase()
: iconName.charAt(0).toUpperCase()}
</div>
);
};
export default TechIcon;

View File

@@ -1,66 +0,0 @@
import React from "react";
interface TechIconProps {
className?: string;
}
export const ReactIcon = ({ className = "w-6 h-6" }: TechIconProps) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M12 10.11c1.03 0 1.87.84 1.87 1.89s-.84 1.89-1.87 1.89c-1.03 0-1.87-.84-1.87-1.89s.84-1.89 1.87-1.89M7.37 20c.63.38 2.01-.2 3.6-1.7-.52-.59-1.03-1.23-1.51-1.9a22.7 22.7 0 0 1-2.4-.36c-.51 2.14-.32 3.61.31 3.96m.71-5.74l-.29-.51c-.11.29-.22.58-.29.86.27.06.57.11.88.16l-.3-.51m6.54-.76l.81-1.5-.81-1.5c-.3-.53-.62-1-.91-1.47C13.17 9 12.6 9 12 9s-1.17 0-1.71.03c-.29.47-.61.94-.91 1.47L8.57 12l.81 1.5c.3.53.62 1 .91 1.47.54.03 1.11.03 1.71.03s1.17 0 1.71-.03c.29-.47.61-.94.91-1.47M12 6.78c-.19.22-.39.45-.59.72h1.18c-.2-.27-.4-.5-.59-.72m0 10.44c.19-.22.39-.45.59-.72h-1.18c.2.27.4.5.59.72M16.62 4c-.62-.38-2 .2-3.59 1.7.52.59 1.03 1.23 1.51 1.9.82.08 1.63.2 2.4.36.51-2.14.32-3.61-.32-3.96m-.7 5.74l.29.51c.11-.29.22-.58.29-.86-.27-.06-.57-.11-.88-.16l.3.51m1.45-7.05c1.47.84 1.63 3.05 1.01 5.63 2.54.75 4.37 1.99 4.37 3.68s-1.83 2.93-4.37 3.68c.62 2.58.46 4.79-1.01 5.63-1.46.84-3.45-.12-5.37-1.95-1.92 1.83-3.91 2.79-5.37 1.95-1.47-.84-1.63-3.05-1.01-5.63-2.54-.75-4.37-1.99-4.37-3.68s1.83-2.93 4.37-3.68c-.62-2.58-.46-4.79 1.01-5.63 1.46-.84 3.45.12 5.37 1.95 1.92-1.83 3.91-2.79 5.37-1.95z" />
</svg>
);
export const VueIcon = ({ className = "w-6 h-6" }: TechIconProps) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M2,3L12,21L22,3H18.5L12,14L5.5,3H2Z" />
</svg>
);
export const TypeScriptIcon = ({ className = "w-6 h-6" }: TechIconProps) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M1.5,5.5V18.5H22.5V5.5H1.5M3,7H21V17H3V7M13.5,8.5V15.5H15.5V8.5H13.5M8.5,8.5V10H11V11.5H8.5V13H12V14.5H7V8.5H8.5Z" />
</svg>
);
export const NextJSIcon = ({ className = "w-6 h-6" }: TechIconProps) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M11.572 0c-.176 0-.31.001-.358.007a19.76 19.76 0 0 1-.364.033C7.443.346 4.25 2.185 2.228 5.012a11.875 11.875 0 0 0-2.119 5.243c-.096.659-.108.854-.108 1.747s.012 1.089.108 1.748c.652 4.506 3.86 8.292 8.209 9.695.779.25 1.6.422 2.534.525.363.04 1.935.04 2.299 0 1.611-.178 2.977-.577 4.323-1.264.207-.106.246-.134.218-.157-.02-.013-.9-1.193-1.955-2.62l-1.919-2.592-2.404-3.558a338.739 338.739 0 0 0-2.422-3.556c-.009-.002-.018 1.579-.023 3.51-.007 3.38-.01 3.515-.052 3.595a.426.426 0 0 1-.206.214c-.075.037-.14.044-.495.044H7.81l-.108-.068a.438.438 0 0 1-.157-.171l-.05-.106.006-4.703.007-4.705.072-.092a.645.645 0 0 1 .174-.143c.096-.047.134-.051.54-.051.478 0 .558.018.682.154.035.038 1.337 1.999 2.895 4.361a10760.433 10760.433 0 0 0 4.735 7.17l1.9 2.879.096-.063a12.317 12.317 0 0 0 2.466-2.163 11.944 11.944 0 0 0 2.824-6.134c.096-.66.108-.854.108-1.748 0-.893-.012-1.088-.108-1.747C19.777 4.249 16.569.346 12.282.033a19.555 19.555 0 0 0-.364-.033C11.87.001 11.736 0 11.572 0zm4.069 7.217c.347 0 .408.005.486.047a.473.473 0 0 1 .237.277c.018.06.023 1.365.018 4.304l-.006 4.218-.744-1.14-.746-1.14v-3.066c0-1.982.01-3.097.023-3.15a.478.478 0 0 1 .233-.296c.096-.05.13-.054.5-.054z" />
</svg>
);
export const NodeJSIcon = ({ className = "w-6 h-6" }: TechIconProps) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M12,1.85C11.73,1.85 11.45,1.92 11.22,2.05L3.78,6.35C3.32,6.61 3.03,7.12 3.03,7.67V16.33C3.03,16.88 3.32,17.39 3.78,17.65L5.73,18.77C6.68,19.23 7.17,19.24 7.17,19.24C8.1,19.24 8.62,18.6 8.62,17.79V9.19C8.62,9.08 8.53,8.99 8.42,8.99H7.6C7.49,8.99 7.4,9.08 7.4,9.19V17.79C7.4,18.05 7.16,18.23 6.94,18.11L4.95,16.96C4.9,16.93 4.87,16.88 4.87,16.82V7.18C4.87,7.12 4.9,7.07 4.95,7.04L12.39,2.74C12.44,2.71 12.53,2.71 12.58,2.74L20.02,7.04C20.07,7.07 20.1,7.12 20.1,7.18V16.82C20.1,16.88 20.07,16.93 20.02,16.96L12.58,21.26C12.53,21.29 12.44,21.29 12.39,21.26L10.57,20.15C10.5,20.11 10.42,20.11 10.35,20.15C9.87,20.41 9.78,20.46 9.26,20.65C9.11,20.71 8.91,20.81 9.18,20.97L11.22,21.95C11.45,22.08 11.73,22.15 12,22.15C12.27,22.15 12.55,22.08 12.78,21.95L20.22,17.65C20.68,17.39 20.97,16.88 20.97,16.33V7.67C20.97,7.12 20.68,6.61 20.22,6.35L12.78,2.05C12.55,1.92 12.27,1.85 12,1.85M14.1,8.14C11.86,8.14 10.95,9.17 10.95,10.45C10.95,11.96 12,12.31 14.05,12.6C16.65,12.96 16.92,13.44 16.92,13.92C16.92,14.7 16.32,15.04 14.91,15.04C12.84,15.04 12.24,14.38 12.1,13.15C12.08,13.05 12,12.97 11.9,12.97H11.05C10.95,12.97 10.86,13.06 10.86,13.16C10.86,14.71 11.69,16.1 14.91,16.1C17.5,16.1 18.78,15.05 18.78,13.92C18.78,12.39 17.78,12.05 15.54,11.7C13.28,11.35 13.09,11.14 13.09,10.64C13.09,10.21 13.29,9.58 14.1,9.58C14.8,9.58 15.21,9.84 15.37,10.76C15.39,10.85 15.47,10.92 15.57,10.92H16.42C16.47,10.92 16.52,10.9 16.55,10.86C16.58,10.82 16.59,10.77 16.58,10.72C16.39,9.05 15.27,8.14 14.1,8.14Z" />
</svg>
);
export const PythonIcon = ({ className = "w-6 h-6" }: TechIconProps) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path d="M19.14,7.5A2.86,2.86 0 0,1 22,10.36V14.14A2.86,2.86 0 0,1 19.14,17H12C12,17.39 12.32,17.96 12.71,17.96H17V19.64A2.86,2.86 0 0,1 14.14,22.5H9.86A2.86,2.86 0 0,1 7,19.64V15.89C7,14.31 8.28,13.04 9.86,13.04H15.11C16.69,13.04 17.96,11.76 17.96,10.18V7.5H19.14M14.86,19.29C14.46,19.29 14.14,19.59 14.14,20S14.46,20.68 14.86,20.68A0.71,0.71 0 0,0 15.57,20C15.57,19.59 15.25,19.29 14.86,19.29M4.86,17H12C12,16.61 11.68,16.04 11.29,16.04H7V14.36A2.86,2.86 0 0,1 9.86,11.5H14.14A2.86,2.86 0 0,1 17,14.36V18.11C17,19.69 15.72,20.96 14.14,20.96H8.89C7.31,20.96 6.04,19.68 6.04,18.1V17H4.86A2.86,2.86 0 0,1 2,14.14V10.36A2.86,2.86 0 0,1 4.86,7.5M9.14,4.71C9.54,4.71 9.86,4.41 9.86,4S9.54,3.32 9.14,3.32A0.71,0.71 0 0,0 8.43,4C8.43,4.41 8.75,4.71 9.14,4.71Z" />
</svg>
);
// Map des icônes par ID de technologie
export const TECH_ICONS: Record<string, React.ComponentType<TechIconProps>> = {
react: ReactIcon,
vue: VueIcon,
typescript: TypeScriptIcon,
nextjs: NextJSIcon,
nodejs: NodeJSIcon,
python: PythonIcon,
// Icône par défaut pour les technologies sans icône spécifique
default: ({ className = "w-6 h-6" }: TechIconProps) => (
<div
className={`${className} bg-muted rounded flex items-center justify-center text-xs font-bold`}
>
?
</div>
),
};
// Fonction utilitaire pour obtenir l'icône d'une technologie
export const getTechIcon = (
techId: string
): React.ComponentType<TechIconProps> => {
return TECH_ICONS[techId] || TECH_ICONS.default;
};

View File

@@ -13,7 +13,7 @@ import {
import { Input } from "@/components/ui/input";
import { Plus, Search } from "lucide-react";
import { SkillCategory, CategoryEvaluation } from "@/lib/types";
import { getTechIcon } from "./icons/tech-icons";
import { TechIcon } from "./icons/tech-icon";
interface SkillSelectorProps {
categories: SkillCategory[];
@@ -108,12 +108,11 @@ export function SkillSelector({
>
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded bg-muted flex items-center justify-center">
{(() => {
const TechIcon = getTechIcon(skill.id);
return (
<TechIcon className="w-5 h-5 text-foreground" />
);
})()}
<TechIcon
iconName={skill.icon}
className="w-5 h-5 text-foreground"
fallbackText={skill.name}
/>
</div>
<div>
<h5 className="font-medium">{skill.name}</h5>

View File

@@ -6,6 +6,7 @@
"id": "nodejs",
"name": "Node.js",
"description": "Runtime JavaScript côté serveur construit sur le moteur V8 de Chrome",
"icon": "fab-node",
"links": [
"https://nodejs.org/",
"https://nodejs.org/en/docs/",
@@ -16,6 +17,7 @@
"id": "python",
"name": "Python",
"description": "Langage de programmation interprété de haut niveau",
"icon": "fab-python",
"links": [
"https://www.python.org/",
"https://docs.python.org/3/",
@@ -26,6 +28,7 @@
"id": "express",
"name": "Express.js",
"description": "Framework web rapide, non-opinionated et minimaliste pour Node.js",
"icon": "fas-server",
"links": [
"https://expressjs.com/",
"https://expressjs.com/en/guide/routing.html",
@@ -36,6 +39,7 @@
"id": "postgresql",
"name": "PostgreSQL",
"description": "Système de gestion de base de données relationnelle open source",
"icon": "fas-database",
"links": [
"https://www.postgresql.org/",
"https://www.postgresql.org/docs/",
@@ -46,6 +50,7 @@
"id": "mongodb",
"name": "MongoDB",
"description": "Base de données NoSQL orientée document",
"icon": "fas-database",
"links": [
"https://www.mongodb.com/",
"https://docs.mongodb.com/",
@@ -56,6 +61,7 @@
"id": "redis",
"name": "Redis",
"description": "Structure de données en mémoire utilisée comme base de données, cache et broker de messages",
"icon": "fas-memory",
"links": [
"https://redis.io/",
"https://redis.io/documentation",
@@ -66,24 +72,28 @@
"id": "golang",
"name": "Go",
"description": "Langage de programmation développé par Google",
"icon": "fab-golang",
"links": ["https://golang.org/", "https://golang.org/doc/"]
},
{
"id": "rust",
"name": "Rust",
"description": "Langage de programmation système sûr et performant",
"icon": "fab-rust",
"links": ["https://www.rust-lang.org/", "https://doc.rust-lang.org/"]
},
{
"id": "java-spring",
"name": "Java Spring",
"description": "Framework Java pour applications d'entreprise",
"icon": "fab-java",
"links": ["https://spring.io/", "https://docs.spring.io/"]
},
{
"id": "csharp-dotnet",
"name": "C# .NET",
"description": "Plateforme de développement Microsoft",
"icon": "fab-microsoft",
"links": [
"https://dotnet.microsoft.com/",
"https://docs.microsoft.com/dotnet/"
@@ -93,48 +103,56 @@
"id": "php-laravel",
"name": "PHP Laravel",
"description": "Framework PHP moderne pour applications web",
"icon": "fab-php",
"links": ["https://laravel.com/", "https://laravel.com/docs"]
},
{
"id": "ruby-rails",
"name": "Ruby on Rails",
"description": "Framework web en Ruby",
"icon": "fas-code",
"links": ["https://rubyonrails.org/", "https://guides.rubyonrails.org/"]
},
{
"id": "graphql",
"name": "GraphQL",
"description": "Langage de requête pour APIs",
"icon": "fas-sitemap",
"links": ["https://graphql.org/", "https://graphql.org/learn/"]
},
{
"id": "prisma",
"name": "Prisma",
"description": "ORM moderne pour Node.js et TypeScript",
"icon": "fas-database",
"links": ["https://www.prisma.io/", "https://www.prisma.io/docs"]
},
{
"id": "trpc",
"name": "tRPC",
"description": "Framework TypeScript pour APIs type-safe",
"icon": "fas-plug",
"links": ["https://trpc.io/", "https://trpc.io/docs"]
},
{
"id": "nest-js",
"name": "NestJS",
"description": "Framework Node.js pour applications scalables",
"icon": "fas-layers",
"links": ["https://nestjs.com/", "https://docs.nestjs.com/"]
},
{
"id": "fastify",
"name": "Fastify",
"description": "Framework web rapide pour Node.js",
"icon": "fas-bolt",
"links": ["https://www.fastify.io/", "https://www.fastify.io/docs/"]
},
{
"id": "rabbitmq",
"name": "RabbitMQ",
"description": "Broker de messages open source",
"icon": "fas-stream",
"links": [
"https://www.rabbitmq.com/",
"https://www.rabbitmq.com/documentation.html"
@@ -144,6 +162,7 @@
"id": "apache-kafka",
"name": "Apache Kafka",
"description": "Plateforme de streaming distribuée",
"icon": "fas-broadcast",
"links": [
"https://kafka.apache.org/",
"https://kafka.apache.org/documentation/"
@@ -153,6 +172,7 @@
"id": "microservices",
"name": "Microservices",
"description": "Architecture en microservices",
"icon": "fas-boxes",
"links": [
"https://microservices.io/",
"https://martinfowler.com/articles/microservices.html"

View File

@@ -6,7 +6,11 @@
"id": "aws",
"name": "Amazon Web Services",
"description": "Plateforme de services cloud d'Amazon",
"links": ["https://aws.amazon.com/", "https://docs.aws.amazon.com/"]
"links": [
"https://aws.amazon.com/",
"https://docs.aws.amazon.com/"
],
"icon": "fab-aws"
},
{
"id": "azure",
@@ -15,13 +19,18 @@
"links": [
"https://azure.microsoft.com/",
"https://docs.microsoft.com/azure/"
]
],
"icon": "fab-microsoft"
},
{
"id": "gcp",
"name": "Google Cloud Platform",
"description": "Services cloud de Google",
"links": ["https://cloud.google.com/", "https://cloud.google.com/docs"]
"links": [
"https://cloud.google.com/",
"https://cloud.google.com/docs"
],
"icon": "fab-google"
},
{
"id": "terraform",
@@ -30,7 +39,8 @@
"links": [
"https://www.terraform.io/",
"https://learn.hashicorp.com/terraform"
]
],
"icon": "fas-tools"
},
{
"id": "serverless",
@@ -39,7 +49,8 @@
"links": [
"https://www.serverless.com/",
"https://www.serverless.com/framework/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "lambda",
@@ -48,7 +59,8 @@
"links": [
"https://aws.amazon.com/lambda/",
"https://docs.aws.amazon.com/lambda/"
]
],
"icon": "fas-bolt"
},
{
"id": "cloudformation",
@@ -57,13 +69,18 @@
"links": [
"https://aws.amazon.com/cloudformation/",
"https://docs.aws.amazon.com/cloudformation/"
]
],
"icon": "fas-layers"
},
{
"id": "s3",
"name": "Amazon S3",
"description": "Service de stockage d'objets d'AWS",
"links": ["https://aws.amazon.com/s3/", "https://docs.aws.amazon.com/s3/"]
"links": [
"https://aws.amazon.com/s3/",
"https://docs.aws.amazon.com/s3/"
],
"icon": "fas-cog"
},
{
"id": "ec2",
@@ -72,7 +89,8 @@
"links": [
"https://aws.amazon.com/ec2/",
"https://docs.aws.amazon.com/ec2/"
]
],
"icon": "fas-cog"
},
{
"id": "cloudfront",
@@ -81,7 +99,8 @@
"links": [
"https://aws.amazon.com/cloudfront/",
"https://docs.aws.amazon.com/cloudfront/"
]
],
"icon": "fas-cog"
}
]
}

View File

@@ -9,7 +9,8 @@
"links": [
"https://www.postgresql.org/docs/",
"https://dev.mysql.com/doc/"
]
],
"icon": "fas-database"
},
{
"id": "postgresql",
@@ -18,7 +19,8 @@
"links": [
"https://www.postgresql.org/",
"https://www.postgresql.org/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "mongodb",
@@ -27,7 +29,8 @@
"links": [
"https://www.mongodb.com/",
"https://docs.mongodb.com/"
]
],
"icon": "fas-cog"
},
{
"id": "redis",
@@ -36,7 +39,8 @@
"links": [
"https://redis.io/",
"https://redis.io/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "elasticsearch",
@@ -45,7 +49,8 @@
"links": [
"https://www.elastic.co/elasticsearch/",
"https://www.elastic.co/guide/"
]
],
"icon": "fas-search"
},
{
"id": "python-data",
@@ -54,7 +59,8 @@
"links": [
"https://pandas.pydata.org/",
"https://scikit-learn.org/"
]
],
"icon": "fas-cog"
},
{
"id": "tableau",
@@ -63,7 +69,8 @@
"links": [
"https://www.tableau.com/",
"https://help.tableau.com/"
]
],
"icon": "fas-chart"
},
{
"id": "powerbi",
@@ -72,7 +79,8 @@
"links": [
"https://powerbi.microsoft.com/",
"https://docs.microsoft.com/power-bi/"
]
],
"icon": "fab-microsoft"
},
{
"id": "spark",
@@ -81,7 +89,8 @@
"links": [
"https://spark.apache.org/",
"https://spark.apache.org/docs/"
]
],
"icon": "fas-bolt"
},
{
"id": "airflow",
@@ -90,7 +99,8 @@
"links": [
"https://airflow.apache.org/",
"https://airflow.apache.org/docs/"
]
],
"icon": "fas-stream"
}
]
}

View File

@@ -9,7 +9,8 @@
"links": [
"https://www.figma.com/",
"https://help.figma.com/"
]
],
"icon": "fab-figma"
},
{
"id": "sketch",
@@ -18,7 +19,8 @@
"links": [
"https://www.sketch.com/",
"https://www.sketch.com/docs/"
]
],
"icon": "fab-sketch"
},
{
"id": "adobe-xd",
@@ -27,7 +29,8 @@
"links": [
"https://www.adobe.com/products/xd.html",
"https://helpx.adobe.com/xd/"
]
],
"icon": "fas-cog"
},
{
"id": "ux-ui",
@@ -36,7 +39,8 @@
"links": [
"https://www.nngroup.com/",
"https://material.io/design/"
]
],
"icon": "fas-cog"
},
{
"id": "design-system",
@@ -45,7 +49,8 @@
"links": [
"https://designsystemsrepo.com/",
"https://www.designbetter.co/design-systems-handbook"
]
],
"icon": "fas-cog"
},
{
"id": "prototyping",
@@ -54,7 +59,8 @@
"links": [
"https://www.prototypr.io/",
"https://www.invisionapp.com/"
]
],
"icon": "fas-palette"
},
{
"id": "user-research",
@@ -63,7 +69,8 @@
"links": [
"https://www.nngroup.com/articles/",
"https://www.usability.gov/"
]
],
"icon": "fas-users"
},
{
"id": "accessibility",
@@ -72,7 +79,8 @@
"links": [
"https://www.w3.org/WAI/",
"https://webaim.org/"
]
],
"icon": "fas-eye"
},
{
"id": "responsive-design",
@@ -81,7 +89,8 @@
"links": [
"https://developers.google.com/web/fundamentals/design-and-ux/responsive",
"https://responsivedesign.is/"
]
],
"icon": "fas-mobile"
},
{
"id": "motion-design",
@@ -90,7 +99,8 @@
"links": [
"https://material.io/design/motion/",
"https://www.framer.com/"
]
],
"icon": "fas-cog"
}
]
}

View File

@@ -10,7 +10,8 @@
"https://www.docker.com/",
"https://docs.docker.com/",
"https://github.com/docker/docker-ce"
]
],
"icon": "fab-docker"
},
{
"id": "kubernetes",
@@ -20,7 +21,8 @@
"https://kubernetes.io/",
"https://kubernetes.io/docs/",
"https://github.com/kubernetes/kubernetes"
]
],
"icon": "fas-layers"
},
{
"id": "aws",
@@ -30,7 +32,8 @@
"https://aws.amazon.com/",
"https://docs.aws.amazon.com/",
"https://github.com/aws"
]
],
"icon": "fab-aws"
},
{
"id": "terraform",
@@ -40,7 +43,8 @@
"https://www.terraform.io/",
"https://learn.hashicorp.com/terraform",
"https://github.com/hashicorp/terraform"
]
],
"icon": "fas-tools"
},
{
"id": "jenkins",
@@ -50,7 +54,8 @@
"https://www.jenkins.io/",
"https://www.jenkins.io/doc/",
"https://github.com/jenkinsci/jenkins"
]
],
"icon": "fas-cog"
},
{
"id": "githubactions",
@@ -60,19 +65,28 @@
"https://github.com/features/actions",
"https://docs.github.com/en/actions",
"https://github.com/actions"
]
],
"icon": "fas-cog"
},
{
"id": "ansible",
"name": "Ansible",
"description": "Outil d'automatisation IT et de gestion de configuration",
"links": ["https://www.ansible.com/", "https://docs.ansible.com/"]
"links": [
"https://www.ansible.com/",
"https://docs.ansible.com/"
],
"icon": "fas-cog"
},
{
"id": "jenkins",
"name": "Jenkins",
"description": "Serveur d'automatisation open source",
"links": ["https://www.jenkins.io/", "https://www.jenkins.io/doc/"]
"links": [
"https://www.jenkins.io/",
"https://www.jenkins.io/doc/"
],
"icon": "fas-cog"
},
{
"id": "gitlab-ci",
@@ -81,19 +95,28 @@
"links": [
"https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/",
"https://docs.gitlab.com/ee/ci/"
]
],
"icon": "fab-gitlab"
},
{
"id": "prometheus",
"name": "Prometheus",
"description": "Système de monitoring et d'alerting",
"links": ["https://prometheus.io/", "https://prometheus.io/docs/"]
"links": [
"https://prometheus.io/",
"https://prometheus.io/docs/"
],
"icon": "fas-chart-line"
},
{
"id": "grafana",
"name": "Grafana",
"description": "Plateforme de visualisation et monitoring",
"links": ["https://grafana.com/", "https://grafana.com/docs/"]
"links": [
"https://grafana.com/",
"https://grafana.com/docs/"
],
"icon": "fas-chart-line"
},
{
"id": "elk-stack",
@@ -102,37 +125,58 @@
"links": [
"https://www.elastic.co/what-is/elk-stack",
"https://www.elastic.co/guide/"
]
],
"icon": "fas-search"
},
{
"id": "nginx",
"name": "Nginx",
"description": "Serveur web et proxy inverse",
"links": ["https://nginx.org/", "https://nginx.org/en/docs/"]
"links": [
"https://nginx.org/",
"https://nginx.org/en/docs/"
],
"icon": "fas-server"
},
{
"id": "apache",
"name": "Apache HTTP Server",
"description": "Serveur web open source",
"links": ["https://httpd.apache.org/", "https://httpd.apache.org/docs/"]
"links": [
"https://httpd.apache.org/",
"https://httpd.apache.org/docs/"
],
"icon": "fas-server"
},
{
"id": "traefik",
"name": "Traefik",
"description": "Proxy inverse moderne et load balancer",
"links": ["https://traefik.io/", "https://doc.traefik.io/"]
"links": [
"https://traefik.io/",
"https://doc.traefik.io/"
],
"icon": "fas-cog"
},
{
"id": "helm",
"name": "Helm",
"description": "Gestionnaire de packages pour Kubernetes",
"links": ["https://helm.sh/", "https://helm.sh/docs/"]
"links": [
"https://helm.sh/",
"https://helm.sh/docs/"
],
"icon": "fas-cog"
},
{
"id": "istio",
"name": "Istio",
"description": "Service mesh pour microservices",
"links": ["https://istio.io/", "https://istio.io/latest/docs/"]
"links": [
"https://istio.io/",
"https://istio.io/latest/docs/"
],
"icon": "fas-cog"
},
{
"id": "vault",
@@ -141,13 +185,18 @@
"links": [
"https://www.vaultproject.io/",
"https://learn.hashicorp.com/vault"
]
],
"icon": "fas-cog"
},
{
"id": "consul",
"name": "HashiCorp Consul",
"description": "Service discovery et configuration",
"links": ["https://www.consul.io/", "https://learn.hashicorp.com/consul"]
"links": [
"https://www.consul.io/",
"https://learn.hashicorp.com/consul"
],
"icon": "fas-cog"
},
{
"id": "nomad",
@@ -156,7 +205,8 @@
"links": [
"https://www.nomadproject.io/",
"https://learn.hashicorp.com/nomad"
]
],
"icon": "fas-cog"
}
]
}

View File

@@ -6,6 +6,7 @@
"id": "react",
"name": "React",
"description": "Bibliothèque JavaScript pour créer des interfaces utilisateur",
"icon": "fab-react",
"links": [
"https://react.dev/",
"https://react.dev/learn",
@@ -16,6 +17,7 @@
"id": "vue",
"name": "Vue.js",
"description": "Framework JavaScript progressif pour construire des interfaces utilisateur",
"icon": "fab-vue",
"links": [
"https://vuejs.org/",
"https://vuejs.org/guide/",
@@ -26,6 +28,7 @@
"id": "typescript",
"name": "TypeScript",
"description": "Superset typé de JavaScript qui compile en JavaScript plain",
"icon": "fab-js",
"links": [
"https://www.typescriptlang.org/",
"https://www.typescriptlang.org/docs/",
@@ -36,6 +39,7 @@
"id": "nextjs",
"name": "Next.js",
"description": "Framework React pour la production avec SSR, SSG et plus",
"icon": "fab-react",
"links": [
"https://nextjs.org/",
"https://nextjs.org/docs",
@@ -46,6 +50,7 @@
"id": "tailwindcss",
"name": "Tailwind CSS",
"description": "Framework CSS utility-first pour créer rapidement des designs personnalisés",
"icon": "fas-palette",
"links": [
"https://tailwindcss.com/",
"https://tailwindcss.com/docs",
@@ -56,6 +61,7 @@
"id": "webpack",
"name": "Webpack",
"description": "Bundler de modules pour les applications JavaScript modernes",
"icon": "fas-cube",
"links": [
"https://webpack.js.org/",
"https://webpack.js.org/concepts/",
@@ -66,105 +72,84 @@
"id": "vite",
"name": "Vite",
"description": "Outil de build rapide pour applications modernes",
"links": [
"https://vitejs.dev/",
"https://vitejs.dev/guide/"
]
"icon": "fas-bolt",
"links": ["https://vitejs.dev/", "https://vitejs.dev/guide/"]
},
{
"id": "svelte",
"name": "Svelte",
"description": "Framework de compilation pour interfaces utilisateur",
"links": [
"https://svelte.dev/",
"https://svelte.dev/docs"
]
"icon": "fas-code",
"links": ["https://svelte.dev/", "https://svelte.dev/docs"]
},
{
"id": "solidjs",
"name": "SolidJS",
"description": "Framework JavaScript réactif et performant",
"links": [
"https://www.solidjs.com/",
"https://www.solidjs.com/docs"
]
"icon": "fas-atom",
"links": ["https://www.solidjs.com/", "https://www.solidjs.com/docs"]
},
{
"id": "astro",
"name": "Astro",
"description": "Framework statique multi-framework",
"links": [
"https://astro.build/",
"https://docs.astro.build/"
]
"icon": "fas-rocket",
"links": ["https://astro.build/", "https://docs.astro.build/"]
},
{
"id": "remix",
"name": "Remix",
"description": "Framework full-stack centré sur les standards web",
"links": [
"https://remix.run/",
"https://remix.run/docs"
]
"icon": "fas-sync",
"links": ["https://remix.run/", "https://remix.run/docs"]
},
{
"id": "storybook",
"name": "Storybook",
"description": "Outil de développement pour composants UI",
"links": [
"https://storybook.js.org/",
"https://storybook.js.org/docs"
]
"icon": "fas-book",
"links": ["https://storybook.js.org/", "https://storybook.js.org/docs"]
},
{
"id": "cypress",
"name": "Cypress",
"description": "Framework de tests end-to-end",
"links": [
"https://www.cypress.io/",
"https://docs.cypress.io/"
]
"icon": "fas-bug",
"links": ["https://www.cypress.io/", "https://docs.cypress.io/"]
},
{
"id": "playwright",
"name": "Playwright",
"description": "Framework de tests pour applications web",
"links": [
"https://playwright.dev/",
"https://playwright.dev/docs/"
]
"icon": "fas-flask",
"links": ["https://playwright.dev/", "https://playwright.dev/docs/"]
},
{
"id": "three-js",
"name": "Three.js",
"description": "Bibliothèque JavaScript pour 3D dans le navigateur",
"links": [
"https://threejs.org/",
"https://threejs.org/docs/"
]
"icon": "fas-cube",
"links": ["https://threejs.org/", "https://threejs.org/docs/"]
},
{
"id": "d3",
"name": "D3.js",
"description": "Bibliothèque de visualisation de données",
"links": [
"https://d3js.org/",
"https://github.com/d3/d3/wiki"
]
"icon": "fas-chart-line",
"links": ["https://d3js.org/", "https://github.com/d3/d3/wiki"]
},
{
"id": "gsap",
"name": "GSAP",
"description": "Bibliothèque d'animations web performantes",
"links": [
"https://greensock.com/gsap/",
"https://greensock.com/docs/"
]
"icon": "fas-bolt",
"links": ["https://greensock.com/gsap/", "https://greensock.com/docs/"]
},
{
"id": "web-components",
"name": "Web Components",
"description": "Standards natifs pour composants réutilisables",
"icon": "fas-puzzle",
"links": [
"https://developer.mozilla.org/en-US/docs/Web/Web_Components",
"https://web.dev/web-components/"
@@ -174,6 +159,7 @@
"id": "pwa",
"name": "Progressive Web Apps",
"description": "Applications web progressives",
"icon": "fas-mobile",
"links": [
"https://web.dev/progressive-web-apps/",
"https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps"

View File

@@ -10,7 +10,8 @@
"https://reactnative.dev/",
"https://reactnative.dev/docs/getting-started",
"https://github.com/facebook/react-native"
]
],
"icon": "fab-react"
},
{
"id": "flutter",
@@ -20,7 +21,8 @@
"https://flutter.dev/",
"https://docs.flutter.dev/",
"https://github.com/flutter/flutter"
]
],
"icon": "fas-mobile"
},
{
"id": "swift",
@@ -30,7 +32,8 @@
"https://developer.apple.com/swift/",
"https://docs.swift.org/swift-book/",
"https://github.com/apple/swift"
]
],
"icon": "fab-swift"
},
{
"id": "kotlin",
@@ -40,7 +43,8 @@
"https://kotlinlang.org/",
"https://kotlinlang.org/docs/",
"https://github.com/JetBrains/kotlin"
]
],
"icon": "fab-android"
},
{
"id": "expo",
@@ -50,7 +54,8 @@
"https://expo.dev/",
"https://docs.expo.dev/",
"https://github.com/expo/expo"
]
],
"icon": "fab-react"
},
{
"id": "ionic",
@@ -59,7 +64,8 @@
"links": [
"https://ionicframework.com/",
"https://ionicframework.com/docs"
]
],
"icon": "fas-mobile"
},
{
"id": "xamarin",
@@ -68,7 +74,8 @@
"links": [
"https://dotnet.microsoft.com/apps/xamarin",
"https://docs.microsoft.com/xamarin/"
]
],
"icon": "fab-microsoft"
},
{
"id": "unity",
@@ -77,7 +84,8 @@
"links": [
"https://unity.com/",
"https://docs.unity3d.com/"
]
],
"icon": "fas-cube"
},
{
"id": "cordova",
@@ -86,7 +94,8 @@
"links": [
"https://cordova.apache.org/",
"https://cordova.apache.org/docs/"
]
],
"icon": "fas-mobile"
},
{
"id": "capacitor",
@@ -95,7 +104,8 @@
"links": [
"https://capacitorjs.com/",
"https://capacitorjs.com/docs"
]
],
"icon": "fas-cog"
},
{
"id": "fastlane",
@@ -104,7 +114,8 @@
"links": [
"https://fastlane.tools/",
"https://docs.fastlane.tools/"
]
],
"icon": "fas-cog"
},
{
"id": "firebase",
@@ -113,7 +124,8 @@
"links": [
"https://firebase.google.com/",
"https://firebase.google.com/docs"
]
],
"icon": "fab-google"
},
{
"id": "app-store-optimization",
@@ -122,7 +134,8 @@
"links": [
"https://developer.apple.com/app-store/",
"https://play.google.com/console/"
]
],
"icon": "fas-cog"
},
{
"id": "mobile-testing",
@@ -131,7 +144,8 @@
"links": [
"https://appium.io/",
"https://detox.js.org/"
]
],
"icon": "fas-bug"
},
{
"id": "mobile-performance",
@@ -140,7 +154,8 @@
"links": [
"https://developers.google.com/web/tools/lighthouse",
"https://developer.android.com/topic/performance"
]
],
"icon": "fas-cog"
},
{
"id": "push-notifications",
@@ -149,7 +164,8 @@
"links": [
"https://firebase.google.com/docs/cloud-messaging",
"https://developer.apple.com/notifications/"
]
],
"icon": "fas-bell"
}
]
}

View File

@@ -9,7 +9,8 @@
"links": [
"https://oauth.net/2/",
"https://tools.ietf.org/html/rfc6749"
]
],
"icon": "fas-key"
},
{
"id": "jwt",
@@ -18,7 +19,8 @@
"links": [
"https://jwt.io/",
"https://tools.ietf.org/html/rfc7519"
]
],
"icon": "fas-shield"
},
{
"id": "https-ssl",
@@ -27,7 +29,8 @@
"links": [
"https://developer.mozilla.org/en-US/docs/Web/Security",
"https://letsencrypt.org/"
]
],
"icon": "fas-cog"
},
{
"id": "owasp",
@@ -36,7 +39,8 @@
"links": [
"https://owasp.org/",
"https://owasp.org/www-project-top-ten/"
]
],
"icon": "fas-cog"
},
{
"id": "csrf-xss",
@@ -45,7 +49,8 @@
"links": [
"https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html",
"https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html"
]
],
"icon": "fas-cog"
},
{
"id": "penetration-testing",
@@ -54,7 +59,8 @@
"links": [
"https://owasp.org/www-community/Penetration_Testing_Methodologies",
"https://www.kali.org/"
]
],
"icon": "fas-user-shield"
},
{
"id": "cryptography",
@@ -63,7 +69,8 @@
"links": [
"https://cryptography.io/",
"https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API"
]
],
"icon": "fas-cog"
},
{
"id": "auth0",
@@ -72,7 +79,8 @@
"links": [
"https://auth0.com/",
"https://auth0.com/docs"
]
],
"icon": "fas-cog"
},
{
"id": "keycloak",
@@ -81,7 +89,8 @@
"links": [
"https://www.keycloak.org/",
"https://www.keycloak.org/documentation"
]
],
"icon": "fas-cog"
},
{
"id": "vault",
@@ -90,7 +99,8 @@
"links": [
"https://www.vaultproject.io/",
"https://learn.hashicorp.com/vault"
]
],
"icon": "fas-cog"
}
]
}

6
lib/fontawesome.ts Normal file
View File

@@ -0,0 +1,6 @@
// Configuration Font Awesome
import { config } from '@fortawesome/fontawesome-svg-core';
import '@fortawesome/fontawesome-svg-core/styles.css';
// Empêche Font Awesome d'ajouter automatiquement du CSS (Next.js le gère)
config.autoAddCss = false;

View File

@@ -23,6 +23,7 @@ export interface Skill {
id: string;
name: string;
description: string;
icon?: string;
links: string[];
}

View File

@@ -9,6 +9,10 @@
"start": "next start"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^7.0.0",
"@fortawesome/free-brands-svg-icons": "^7.0.0",
"@fortawesome/free-solid-svg-icons": "^7.0.0",
"@fortawesome/react-fontawesome": "^0.2.5",
"@hookform/resolvers": "^3.10.0",
"@radix-ui/react-accordion": "1.2.2",
"@radix-ui/react-alert-dialog": "1.1.4",

54
pnpm-lock.yaml generated
View File

@@ -8,6 +8,18 @@ importers:
.:
dependencies:
'@fortawesome/fontawesome-svg-core':
specifier: ^7.0.0
version: 7.0.0
'@fortawesome/free-brands-svg-icons':
specifier: ^7.0.0
version: 7.0.0
'@fortawesome/free-solid-svg-icons':
specifier: ^7.0.0
version: 7.0.0
'@fortawesome/react-fontawesome':
specifier: ^0.2.5
version: 0.2.5(@fortawesome/fontawesome-svg-core@7.0.0)(react@19.1.1)
'@hookform/resolvers':
specifier: ^3.10.0
version: 3.10.0(react-hook-form@7.62.0(react@19.1.1))
@@ -215,6 +227,28 @@ packages:
'@floating-ui/utils@0.2.10':
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
'@fortawesome/fontawesome-common-types@7.0.0':
resolution: {integrity: sha512-PGMrIYXLGA5K8RWy8zwBkd4vFi4z7ubxtet6Yn13Plf6krRTwPbdlCwlcfmoX0R7B4Z643QvrtHmdQ5fNtfFCg==}
engines: {node: '>=6'}
'@fortawesome/fontawesome-svg-core@7.0.0':
resolution: {integrity: sha512-obBEF+zd98r/KtKVW6A+8UGWeaOoyMpl6Q9P3FzHsOnsg742aXsl8v+H/zp09qSSu/a/Hxe9LNKzbBaQq1CEbA==}
engines: {node: '>=6'}
'@fortawesome/free-brands-svg-icons@7.0.0':
resolution: {integrity: sha512-C8oY28gq/Qx/cHReJa2AunKJUHvUZDVoPlSTHtAvjriaNfi+5nugW4cx7yA/xN3f/nYkElw11gFBoJ2xUDDFgg==}
engines: {node: '>=6'}
'@fortawesome/free-solid-svg-icons@7.0.0':
resolution: {integrity: sha512-njSLAllkOddYDCXgTFboXn54Oe5FcvpkWq+FoetOHR64PbN0608kM02Lze0xtISGpXgP+i26VyXRQA0Irh3Obw==}
engines: {node: '>=6'}
'@fortawesome/react-fontawesome@0.2.5':
resolution: {integrity: sha512-55xAmidU/xWPVUK2IlG0c4LK+7pk75Qnwh7PcmjxlUTUibbI0+txjAB2ucF3TQZOXHOcjBcpoF8R75b59OxNmg==}
peerDependencies:
'@fortawesome/fontawesome-svg-core': ~1 || ~6 || ~7
react: ^16.3 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@hookform/resolvers@3.10.0':
resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==}
peerDependencies:
@@ -1765,6 +1799,26 @@ snapshots:
'@floating-ui/utils@0.2.10': {}
'@fortawesome/fontawesome-common-types@7.0.0': {}
'@fortawesome/fontawesome-svg-core@7.0.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.0.0
'@fortawesome/free-brands-svg-icons@7.0.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.0.0
'@fortawesome/free-solid-svg-icons@7.0.0':
dependencies:
'@fortawesome/fontawesome-common-types': 7.0.0
'@fortawesome/react-fontawesome@0.2.5(@fortawesome/fontawesome-svg-core@7.0.0)(react@19.1.1)':
dependencies:
'@fortawesome/fontawesome-svg-core': 7.0.0
prop-types: 15.8.1
react: 19.1.1
'@hookform/resolvers@3.10.0(react-hook-form@7.62.0(react@19.1.1))':
dependencies:
react-hook-form: 7.62.0(react@19.1.1)

View File

@@ -6,6 +6,7 @@
"id": "nodejs",
"name": "Node.js",
"description": "Runtime JavaScript côté serveur construit sur le moteur V8 de Chrome",
"icon": "fab-node",
"links": [
"https://nodejs.org/",
"https://nodejs.org/en/docs/",
@@ -16,6 +17,7 @@
"id": "python",
"name": "Python",
"description": "Langage de programmation interprété de haut niveau",
"icon": "fab-python",
"links": [
"https://www.python.org/",
"https://docs.python.org/3/",
@@ -26,6 +28,7 @@
"id": "express",
"name": "Express.js",
"description": "Framework web rapide, non-opinionated et minimaliste pour Node.js",
"icon": "fas-server",
"links": [
"https://expressjs.com/",
"https://expressjs.com/en/guide/routing.html",
@@ -36,6 +39,7 @@
"id": "postgresql",
"name": "PostgreSQL",
"description": "Système de gestion de base de données relationnelle open source",
"icon": "fas-database",
"links": [
"https://www.postgresql.org/",
"https://www.postgresql.org/docs/",
@@ -46,6 +50,7 @@
"id": "mongodb",
"name": "MongoDB",
"description": "Base de données NoSQL orientée document",
"icon": "fas-database",
"links": [
"https://www.mongodb.com/",
"https://docs.mongodb.com/",
@@ -56,6 +61,7 @@
"id": "redis",
"name": "Redis",
"description": "Structure de données en mémoire utilisée comme base de données, cache et broker de messages",
"icon": "fas-memory",
"links": [
"https://redis.io/",
"https://redis.io/documentation",
@@ -66,33 +72,28 @@
"id": "golang",
"name": "Go",
"description": "Langage de programmation développé par Google",
"links": [
"https://golang.org/",
"https://golang.org/doc/"
]
"icon": "fab-golang",
"links": ["https://golang.org/", "https://golang.org/doc/"]
},
{
"id": "rust",
"name": "Rust",
"description": "Langage de programmation système sûr et performant",
"links": [
"https://www.rust-lang.org/",
"https://doc.rust-lang.org/"
]
"icon": "fab-rust",
"links": ["https://www.rust-lang.org/", "https://doc.rust-lang.org/"]
},
{
"id": "java-spring",
"name": "Java Spring",
"description": "Framework Java pour applications d'entreprise",
"links": [
"https://spring.io/",
"https://docs.spring.io/"
]
"icon": "fab-java",
"links": ["https://spring.io/", "https://docs.spring.io/"]
},
{
"id": "csharp-dotnet",
"name": "C# .NET",
"description": "Plateforme de développement Microsoft",
"icon": "fab-microsoft",
"links": [
"https://dotnet.microsoft.com/",
"https://docs.microsoft.com/dotnet/"
@@ -102,69 +103,56 @@
"id": "php-laravel",
"name": "PHP Laravel",
"description": "Framework PHP moderne pour applications web",
"links": [
"https://laravel.com/",
"https://laravel.com/docs"
]
"icon": "fab-php",
"links": ["https://laravel.com/", "https://laravel.com/docs"]
},
{
"id": "ruby-rails",
"name": "Ruby on Rails",
"description": "Framework web en Ruby",
"links": [
"https://rubyonrails.org/",
"https://guides.rubyonrails.org/"
]
"icon": "fas-code",
"links": ["https://rubyonrails.org/", "https://guides.rubyonrails.org/"]
},
{
"id": "graphql",
"name": "GraphQL",
"description": "Langage de requête pour APIs",
"links": [
"https://graphql.org/",
"https://graphql.org/learn/"
]
"icon": "fas-sitemap",
"links": ["https://graphql.org/", "https://graphql.org/learn/"]
},
{
"id": "prisma",
"name": "Prisma",
"description": "ORM moderne pour Node.js et TypeScript",
"links": [
"https://www.prisma.io/",
"https://www.prisma.io/docs"
]
"icon": "fas-database",
"links": ["https://www.prisma.io/", "https://www.prisma.io/docs"]
},
{
"id": "trpc",
"name": "tRPC",
"description": "Framework TypeScript pour APIs type-safe",
"links": [
"https://trpc.io/",
"https://trpc.io/docs"
]
"icon": "fas-plug",
"links": ["https://trpc.io/", "https://trpc.io/docs"]
},
{
"id": "nest-js",
"name": "NestJS",
"description": "Framework Node.js pour applications scalables",
"links": [
"https://nestjs.com/",
"https://docs.nestjs.com/"
]
"icon": "fas-layers",
"links": ["https://nestjs.com/", "https://docs.nestjs.com/"]
},
{
"id": "fastify",
"name": "Fastify",
"description": "Framework web rapide pour Node.js",
"links": [
"https://www.fastify.io/",
"https://www.fastify.io/docs/"
]
"icon": "fas-bolt",
"links": ["https://www.fastify.io/", "https://www.fastify.io/docs/"]
},
{
"id": "rabbitmq",
"name": "RabbitMQ",
"description": "Broker de messages open source",
"icon": "fas-stream",
"links": [
"https://www.rabbitmq.com/",
"https://www.rabbitmq.com/documentation.html"
@@ -174,6 +162,7 @@
"id": "apache-kafka",
"name": "Apache Kafka",
"description": "Plateforme de streaming distribuée",
"icon": "fas-broadcast",
"links": [
"https://kafka.apache.org/",
"https://kafka.apache.org/documentation/"
@@ -183,6 +172,7 @@
"id": "microservices",
"name": "Microservices",
"description": "Architecture en microservices",
"icon": "fas-boxes",
"links": [
"https://microservices.io/",
"https://martinfowler.com/articles/microservices.html"

View File

@@ -9,7 +9,8 @@
"links": [
"https://aws.amazon.com/",
"https://docs.aws.amazon.com/"
]
],
"icon": "fab-aws"
},
{
"id": "azure",
@@ -18,7 +19,8 @@
"links": [
"https://azure.microsoft.com/",
"https://docs.microsoft.com/azure/"
]
],
"icon": "fab-microsoft"
},
{
"id": "gcp",
@@ -27,7 +29,8 @@
"links": [
"https://cloud.google.com/",
"https://cloud.google.com/docs"
]
],
"icon": "fab-google"
},
{
"id": "terraform",
@@ -36,7 +39,8 @@
"links": [
"https://www.terraform.io/",
"https://learn.hashicorp.com/terraform"
]
],
"icon": "fas-tools"
},
{
"id": "serverless",
@@ -45,7 +49,8 @@
"links": [
"https://www.serverless.com/",
"https://www.serverless.com/framework/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "lambda",
@@ -54,7 +59,8 @@
"links": [
"https://aws.amazon.com/lambda/",
"https://docs.aws.amazon.com/lambda/"
]
],
"icon": "fas-bolt"
},
{
"id": "cloudformation",
@@ -63,7 +69,8 @@
"links": [
"https://aws.amazon.com/cloudformation/",
"https://docs.aws.amazon.com/cloudformation/"
]
],
"icon": "fas-layers"
},
{
"id": "s3",
@@ -72,7 +79,8 @@
"links": [
"https://aws.amazon.com/s3/",
"https://docs.aws.amazon.com/s3/"
]
],
"icon": "fas-cog"
},
{
"id": "ec2",
@@ -81,7 +89,8 @@
"links": [
"https://aws.amazon.com/ec2/",
"https://docs.aws.amazon.com/ec2/"
]
],
"icon": "fas-cog"
},
{
"id": "cloudfront",
@@ -90,7 +99,8 @@
"links": [
"https://aws.amazon.com/cloudfront/",
"https://docs.aws.amazon.com/cloudfront/"
]
],
"icon": "fas-cog"
}
]
}

View File

@@ -9,7 +9,8 @@
"links": [
"https://www.postgresql.org/docs/",
"https://dev.mysql.com/doc/"
]
],
"icon": "fas-database"
},
{
"id": "postgresql",
@@ -18,7 +19,8 @@
"links": [
"https://www.postgresql.org/",
"https://www.postgresql.org/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "mongodb",
@@ -27,7 +29,8 @@
"links": [
"https://www.mongodb.com/",
"https://docs.mongodb.com/"
]
],
"icon": "fas-cog"
},
{
"id": "redis",
@@ -36,7 +39,8 @@
"links": [
"https://redis.io/",
"https://redis.io/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "elasticsearch",
@@ -45,7 +49,8 @@
"links": [
"https://www.elastic.co/elasticsearch/",
"https://www.elastic.co/guide/"
]
],
"icon": "fas-search"
},
{
"id": "python-data",
@@ -54,7 +59,8 @@
"links": [
"https://pandas.pydata.org/",
"https://scikit-learn.org/"
]
],
"icon": "fas-cog"
},
{
"id": "tableau",
@@ -63,7 +69,8 @@
"links": [
"https://www.tableau.com/",
"https://help.tableau.com/"
]
],
"icon": "fas-chart"
},
{
"id": "powerbi",
@@ -72,7 +79,8 @@
"links": [
"https://powerbi.microsoft.com/",
"https://docs.microsoft.com/power-bi/"
]
],
"icon": "fab-microsoft"
},
{
"id": "spark",
@@ -81,7 +89,8 @@
"links": [
"https://spark.apache.org/",
"https://spark.apache.org/docs/"
]
],
"icon": "fas-bolt"
},
{
"id": "airflow",
@@ -90,7 +99,8 @@
"links": [
"https://airflow.apache.org/",
"https://airflow.apache.org/docs/"
]
],
"icon": "fas-stream"
}
]
}

View File

@@ -9,7 +9,8 @@
"links": [
"https://www.figma.com/",
"https://help.figma.com/"
]
],
"icon": "fab-figma"
},
{
"id": "sketch",
@@ -18,7 +19,8 @@
"links": [
"https://www.sketch.com/",
"https://www.sketch.com/docs/"
]
],
"icon": "fab-sketch"
},
{
"id": "adobe-xd",
@@ -27,7 +29,8 @@
"links": [
"https://www.adobe.com/products/xd.html",
"https://helpx.adobe.com/xd/"
]
],
"icon": "fas-cog"
},
{
"id": "ux-ui",
@@ -36,7 +39,8 @@
"links": [
"https://www.nngroup.com/",
"https://material.io/design/"
]
],
"icon": "fas-cog"
},
{
"id": "design-system",
@@ -45,7 +49,8 @@
"links": [
"https://designsystemsrepo.com/",
"https://www.designbetter.co/design-systems-handbook"
]
],
"icon": "fas-cog"
},
{
"id": "prototyping",
@@ -54,7 +59,8 @@
"links": [
"https://www.prototypr.io/",
"https://www.invisionapp.com/"
]
],
"icon": "fas-palette"
},
{
"id": "user-research",
@@ -63,7 +69,8 @@
"links": [
"https://www.nngroup.com/articles/",
"https://www.usability.gov/"
]
],
"icon": "fas-users"
},
{
"id": "accessibility",
@@ -72,7 +79,8 @@
"links": [
"https://www.w3.org/WAI/",
"https://webaim.org/"
]
],
"icon": "fas-eye"
},
{
"id": "responsive-design",
@@ -81,7 +89,8 @@
"links": [
"https://developers.google.com/web/fundamentals/design-and-ux/responsive",
"https://responsivedesign.is/"
]
],
"icon": "fas-mobile"
},
{
"id": "motion-design",
@@ -90,7 +99,8 @@
"links": [
"https://material.io/design/motion/",
"https://www.framer.com/"
]
],
"icon": "fas-cog"
}
]
}

View File

@@ -10,7 +10,8 @@
"https://www.docker.com/",
"https://docs.docker.com/",
"https://github.com/docker/docker-ce"
]
],
"icon": "fab-docker"
},
{
"id": "kubernetes",
@@ -20,7 +21,8 @@
"https://kubernetes.io/",
"https://kubernetes.io/docs/",
"https://github.com/kubernetes/kubernetes"
]
],
"icon": "fas-layers"
},
{
"id": "aws",
@@ -30,7 +32,8 @@
"https://aws.amazon.com/",
"https://docs.aws.amazon.com/",
"https://github.com/aws"
]
],
"icon": "fab-aws"
},
{
"id": "terraform",
@@ -40,7 +43,8 @@
"https://www.terraform.io/",
"https://learn.hashicorp.com/terraform",
"https://github.com/hashicorp/terraform"
]
],
"icon": "fas-tools"
},
{
"id": "jenkins",
@@ -50,7 +54,8 @@
"https://www.jenkins.io/",
"https://www.jenkins.io/doc/",
"https://github.com/jenkinsci/jenkins"
]
],
"icon": "fas-cog"
},
{
"id": "githubactions",
@@ -60,7 +65,8 @@
"https://github.com/features/actions",
"https://docs.github.com/en/actions",
"https://github.com/actions"
]
],
"icon": "fas-cog"
},
{
"id": "ansible",
@@ -69,7 +75,8 @@
"links": [
"https://www.ansible.com/",
"https://docs.ansible.com/"
]
],
"icon": "fas-cog"
},
{
"id": "jenkins",
@@ -78,7 +85,8 @@
"links": [
"https://www.jenkins.io/",
"https://www.jenkins.io/doc/"
]
],
"icon": "fas-cog"
},
{
"id": "gitlab-ci",
@@ -87,7 +95,8 @@
"links": [
"https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/",
"https://docs.gitlab.com/ee/ci/"
]
],
"icon": "fab-gitlab"
},
{
"id": "prometheus",
@@ -96,7 +105,8 @@
"links": [
"https://prometheus.io/",
"https://prometheus.io/docs/"
]
],
"icon": "fas-chart-line"
},
{
"id": "grafana",
@@ -105,7 +115,8 @@
"links": [
"https://grafana.com/",
"https://grafana.com/docs/"
]
],
"icon": "fas-chart-line"
},
{
"id": "elk-stack",
@@ -114,7 +125,8 @@
"links": [
"https://www.elastic.co/what-is/elk-stack",
"https://www.elastic.co/guide/"
]
],
"icon": "fas-search"
},
{
"id": "nginx",
@@ -123,7 +135,8 @@
"links": [
"https://nginx.org/",
"https://nginx.org/en/docs/"
]
],
"icon": "fas-server"
},
{
"id": "apache",
@@ -132,7 +145,8 @@
"links": [
"https://httpd.apache.org/",
"https://httpd.apache.org/docs/"
]
],
"icon": "fas-server"
},
{
"id": "traefik",
@@ -141,7 +155,8 @@
"links": [
"https://traefik.io/",
"https://doc.traefik.io/"
]
],
"icon": "fas-cog"
},
{
"id": "helm",
@@ -150,7 +165,8 @@
"links": [
"https://helm.sh/",
"https://helm.sh/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "istio",
@@ -159,7 +175,8 @@
"links": [
"https://istio.io/",
"https://istio.io/latest/docs/"
]
],
"icon": "fas-cog"
},
{
"id": "vault",
@@ -168,7 +185,8 @@
"links": [
"https://www.vaultproject.io/",
"https://learn.hashicorp.com/vault"
]
],
"icon": "fas-cog"
},
{
"id": "consul",
@@ -177,7 +195,8 @@
"links": [
"https://www.consul.io/",
"https://learn.hashicorp.com/consul"
]
],
"icon": "fas-cog"
},
{
"id": "nomad",
@@ -186,7 +205,8 @@
"links": [
"https://www.nomadproject.io/",
"https://learn.hashicorp.com/nomad"
]
],
"icon": "fas-cog"
}
]
}

View File

@@ -6,6 +6,7 @@
"id": "react",
"name": "React",
"description": "Bibliothèque JavaScript pour créer des interfaces utilisateur",
"icon": "fab-react",
"links": [
"https://react.dev/",
"https://react.dev/learn",
@@ -16,6 +17,7 @@
"id": "vue",
"name": "Vue.js",
"description": "Framework JavaScript progressif pour construire des interfaces utilisateur",
"icon": "fab-vue",
"links": [
"https://vuejs.org/",
"https://vuejs.org/guide/",
@@ -26,6 +28,7 @@
"id": "typescript",
"name": "TypeScript",
"description": "Superset typé de JavaScript qui compile en JavaScript plain",
"icon": "fab-js",
"links": [
"https://www.typescriptlang.org/",
"https://www.typescriptlang.org/docs/",
@@ -36,6 +39,7 @@
"id": "nextjs",
"name": "Next.js",
"description": "Framework React pour la production avec SSR, SSG et plus",
"icon": "fab-react",
"links": [
"https://nextjs.org/",
"https://nextjs.org/docs",
@@ -46,6 +50,7 @@
"id": "tailwindcss",
"name": "Tailwind CSS",
"description": "Framework CSS utility-first pour créer rapidement des designs personnalisés",
"icon": "fas-palette",
"links": [
"https://tailwindcss.com/",
"https://tailwindcss.com/docs",
@@ -56,6 +61,7 @@
"id": "webpack",
"name": "Webpack",
"description": "Bundler de modules pour les applications JavaScript modernes",
"icon": "fas-cube",
"links": [
"https://webpack.js.org/",
"https://webpack.js.org/concepts/",
@@ -66,105 +72,84 @@
"id": "vite",
"name": "Vite",
"description": "Outil de build rapide pour applications modernes",
"links": [
"https://vitejs.dev/",
"https://vitejs.dev/guide/"
]
"icon": "fas-bolt",
"links": ["https://vitejs.dev/", "https://vitejs.dev/guide/"]
},
{
"id": "svelte",
"name": "Svelte",
"description": "Framework de compilation pour interfaces utilisateur",
"links": [
"https://svelte.dev/",
"https://svelte.dev/docs"
]
"icon": "fas-code",
"links": ["https://svelte.dev/", "https://svelte.dev/docs"]
},
{
"id": "solidjs",
"name": "SolidJS",
"description": "Framework JavaScript réactif et performant",
"links": [
"https://www.solidjs.com/",
"https://www.solidjs.com/docs"
]
"icon": "fas-atom",
"links": ["https://www.solidjs.com/", "https://www.solidjs.com/docs"]
},
{
"id": "astro",
"name": "Astro",
"description": "Framework statique multi-framework",
"links": [
"https://astro.build/",
"https://docs.astro.build/"
]
"icon": "fas-rocket",
"links": ["https://astro.build/", "https://docs.astro.build/"]
},
{
"id": "remix",
"name": "Remix",
"description": "Framework full-stack centré sur les standards web",
"links": [
"https://remix.run/",
"https://remix.run/docs"
]
"icon": "fas-sync",
"links": ["https://remix.run/", "https://remix.run/docs"]
},
{
"id": "storybook",
"name": "Storybook",
"description": "Outil de développement pour composants UI",
"links": [
"https://storybook.js.org/",
"https://storybook.js.org/docs"
]
"icon": "fas-book",
"links": ["https://storybook.js.org/", "https://storybook.js.org/docs"]
},
{
"id": "cypress",
"name": "Cypress",
"description": "Framework de tests end-to-end",
"links": [
"https://www.cypress.io/",
"https://docs.cypress.io/"
]
"icon": "fas-bug",
"links": ["https://www.cypress.io/", "https://docs.cypress.io/"]
},
{
"id": "playwright",
"name": "Playwright",
"description": "Framework de tests pour applications web",
"links": [
"https://playwright.dev/",
"https://playwright.dev/docs/"
]
"icon": "fas-flask",
"links": ["https://playwright.dev/", "https://playwright.dev/docs/"]
},
{
"id": "three-js",
"name": "Three.js",
"description": "Bibliothèque JavaScript pour 3D dans le navigateur",
"links": [
"https://threejs.org/",
"https://threejs.org/docs/"
]
"icon": "fas-cube",
"links": ["https://threejs.org/", "https://threejs.org/docs/"]
},
{
"id": "d3",
"name": "D3.js",
"description": "Bibliothèque de visualisation de données",
"links": [
"https://d3js.org/",
"https://github.com/d3/d3/wiki"
]
"icon": "fas-chart-line",
"links": ["https://d3js.org/", "https://github.com/d3/d3/wiki"]
},
{
"id": "gsap",
"name": "GSAP",
"description": "Bibliothèque d'animations web performantes",
"links": [
"https://greensock.com/gsap/",
"https://greensock.com/docs/"
]
"icon": "fas-bolt",
"links": ["https://greensock.com/gsap/", "https://greensock.com/docs/"]
},
{
"id": "web-components",
"name": "Web Components",
"description": "Standards natifs pour composants réutilisables",
"icon": "fas-puzzle",
"links": [
"https://developer.mozilla.org/en-US/docs/Web/Web_Components",
"https://web.dev/web-components/"
@@ -174,6 +159,7 @@
"id": "pwa",
"name": "Progressive Web Apps",
"description": "Applications web progressives",
"icon": "fas-mobile",
"links": [
"https://web.dev/progressive-web-apps/",
"https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps"

View File

@@ -10,7 +10,8 @@
"https://reactnative.dev/",
"https://reactnative.dev/docs/getting-started",
"https://github.com/facebook/react-native"
]
],
"icon": "fab-react"
},
{
"id": "flutter",
@@ -20,7 +21,8 @@
"https://flutter.dev/",
"https://docs.flutter.dev/",
"https://github.com/flutter/flutter"
]
],
"icon": "fas-mobile"
},
{
"id": "swift",
@@ -30,7 +32,8 @@
"https://developer.apple.com/swift/",
"https://docs.swift.org/swift-book/",
"https://github.com/apple/swift"
]
],
"icon": "fab-swift"
},
{
"id": "kotlin",
@@ -40,7 +43,8 @@
"https://kotlinlang.org/",
"https://kotlinlang.org/docs/",
"https://github.com/JetBrains/kotlin"
]
],
"icon": "fab-android"
},
{
"id": "expo",
@@ -50,7 +54,8 @@
"https://expo.dev/",
"https://docs.expo.dev/",
"https://github.com/expo/expo"
]
],
"icon": "fab-react"
},
{
"id": "ionic",
@@ -59,7 +64,8 @@
"links": [
"https://ionicframework.com/",
"https://ionicframework.com/docs"
]
],
"icon": "fas-mobile"
},
{
"id": "xamarin",
@@ -68,7 +74,8 @@
"links": [
"https://dotnet.microsoft.com/apps/xamarin",
"https://docs.microsoft.com/xamarin/"
]
],
"icon": "fab-microsoft"
},
{
"id": "unity",
@@ -77,7 +84,8 @@
"links": [
"https://unity.com/",
"https://docs.unity3d.com/"
]
],
"icon": "fas-cube"
},
{
"id": "cordova",
@@ -86,7 +94,8 @@
"links": [
"https://cordova.apache.org/",
"https://cordova.apache.org/docs/"
]
],
"icon": "fas-mobile"
},
{
"id": "capacitor",
@@ -95,7 +104,8 @@
"links": [
"https://capacitorjs.com/",
"https://capacitorjs.com/docs"
]
],
"icon": "fas-cog"
},
{
"id": "fastlane",
@@ -104,7 +114,8 @@
"links": [
"https://fastlane.tools/",
"https://docs.fastlane.tools/"
]
],
"icon": "fas-cog"
},
{
"id": "firebase",
@@ -113,7 +124,8 @@
"links": [
"https://firebase.google.com/",
"https://firebase.google.com/docs"
]
],
"icon": "fab-google"
},
{
"id": "app-store-optimization",
@@ -122,7 +134,8 @@
"links": [
"https://developer.apple.com/app-store/",
"https://play.google.com/console/"
]
],
"icon": "fas-cog"
},
{
"id": "mobile-testing",
@@ -131,7 +144,8 @@
"links": [
"https://appium.io/",
"https://detox.js.org/"
]
],
"icon": "fas-bug"
},
{
"id": "mobile-performance",
@@ -140,7 +154,8 @@
"links": [
"https://developers.google.com/web/tools/lighthouse",
"https://developer.android.com/topic/performance"
]
],
"icon": "fas-cog"
},
{
"id": "push-notifications",
@@ -149,7 +164,8 @@
"links": [
"https://firebase.google.com/docs/cloud-messaging",
"https://developer.apple.com/notifications/"
]
],
"icon": "fas-bell"
}
]
}

View File

@@ -9,7 +9,8 @@
"links": [
"https://oauth.net/2/",
"https://tools.ietf.org/html/rfc6749"
]
],
"icon": "fas-key"
},
{
"id": "jwt",
@@ -18,7 +19,8 @@
"links": [
"https://jwt.io/",
"https://tools.ietf.org/html/rfc7519"
]
],
"icon": "fas-shield"
},
{
"id": "https-ssl",
@@ -27,7 +29,8 @@
"links": [
"https://developer.mozilla.org/en-US/docs/Web/Security",
"https://letsencrypt.org/"
]
],
"icon": "fas-cog"
},
{
"id": "owasp",
@@ -36,7 +39,8 @@
"links": [
"https://owasp.org/",
"https://owasp.org/www-project-top-ten/"
]
],
"icon": "fas-cog"
},
{
"id": "csrf-xss",
@@ -45,7 +49,8 @@
"links": [
"https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html",
"https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html"
]
],
"icon": "fas-cog"
},
{
"id": "penetration-testing",
@@ -54,7 +59,8 @@
"links": [
"https://owasp.org/www-community/Penetration_Testing_Methodologies",
"https://www.kali.org/"
]
],
"icon": "fas-user-shield"
},
{
"id": "cryptography",
@@ -63,7 +69,8 @@
"links": [
"https://cryptography.io/",
"https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API"
]
],
"icon": "fas-cog"
},
{
"id": "auth0",
@@ -72,7 +79,8 @@
"links": [
"https://auth0.com/",
"https://auth0.com/docs"
]
],
"icon": "fas-cog"
},
{
"id": "keycloak",
@@ -81,7 +89,8 @@
"links": [
"https://www.keycloak.org/",
"https://www.keycloak.org/documentation"
]
],
"icon": "fas-cog"
},
{
"id": "vault",
@@ -90,7 +99,8 @@
"links": [
"https://www.vaultproject.io/",
"https://learn.hashicorp.com/vault"
]
],
"icon": "fas-cog"
}
]
}