Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | "use client"; import { techStack } from "@/data/apps"; import styles from "@/components/windows/WindowContent.module.css"; import { Code, Database, Laptop, Users, Brain, Wrench, Server, GitBranch, CreditCard, Map, Trello, MessageSquare, Feather, BookOpen, Lightbulb, Smile, } from "lucide-react"; import type { JSX } from "react"; // π§ Debug toggle const DEBUG = (typeof process !== "undefined" && process.env.NODE_ENV !== "production") || (typeof process !== "undefined" && process.env.NEXT_PUBLIC_DEBUG === "true"); const dlog = (...args: any[]) => { if (DEBUG) console.log("[SkillsContent]", ...args); }; // π Emoji β Icon mapping const iconMap: { [key: string]: JSX.Element } = { "π§": <Wrench size={18} />, "π": <Feather size={18} />, "ποΈ": <Database size={18} />, "π": <Server size={18} />, "π": <Code size={18} />, "ποΈ": <Lightbulb size={18} />, "βοΈ": <Laptop size={18} />, "π": <Laptop size={18} />, "π": <Code size={18} />, "π¨": <Laptop size={18} />, "βοΈ": <Code size={18} />, "π ±οΈ": <Laptop size={18} />, "π": <GitBranch size={18} />, "πͺ£": <GitBranch size={18} />, "πͺ": <GitBranch size={18} />, "π₯οΈ": <Server size={18} />, "π": <Server size={18} />, "π³": <CreditCard size={18} />, "π°": <CreditCard size={18} />, "πΊοΈ": <Map size={18} />, "π": <Trello size={18} />, "π±": <MessageSquare size={18} />, "π": <Users size={18} />, "π": <Users size={18} />, "π₯": <Users size={18} />, "π": <Users size={18} />, "π": <BookOpen size={18} />, "ποΈ": <Brain size={18} />, "π€": <Brain size={18} />, "π§ ": <Brain size={18} />, "π§": <Smile size={18} />, }; export default function SkillsContent() { const safeTechStack = techStack && typeof techStack === "object" ? techStack : {}; const categories = Object.entries(safeTechStack); dlog(`π§± Rendering ${categories.length} skill categories`); if (categories.length === 0) { dlog("β οΈ No techStack data found."); return ( <div className={styles.windowContent}> <section className={styles.contentSection}> <h2>Technical Skills & Expertise</h2> <p>No technical skills data available at the moment.</p> </section> </div> ); } return ( <div className={styles.windowContent}> <section className={styles.contentSection}> <h2>Technical Skills & Expertise</h2> <div className={styles.skillsGrid}> {categories.map(([category, skills]) => { if (!Array.isArray(skills)) return null; dlog(`π ${category}: ${skills.length} skills`); return ( <div key={category} className={styles.skillCategory}> <h3>{category.charAt(0).toUpperCase() + category.slice(1)}</h3> <ul className={styles.skillList}> {skills.map((skill, index) => { const safeIcon = iconMap[skill.icon] || <Code size={18} />; const name = skill.name || "Unnamed Skill"; const level = skill.level || "N/A"; const years = skill.years || "β"; return ( <li key={index} className={styles.skillItem}> {safeIcon} {name} ({level} - {years}) </li> ); })} </ul> </div> ); })} </div> </section> </div> ); } |