updated route pathing, skills.tsx for skill card abstraction and header for mobile
This commit is contained in:
82
src/components/SkillCard.tsx
Normal file
82
src/components/SkillCard.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export interface SkillDetail {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface SkillCategory {
|
||||
category: string;
|
||||
skills: SkillDetail[];
|
||||
}
|
||||
|
||||
interface SkillCardProps {
|
||||
category: SkillCategory;
|
||||
isExpanded: boolean;
|
||||
onToggle: () => void;
|
||||
}
|
||||
|
||||
export default function SkillCard({ category, isExpanded, onToggle }: SkillCardProps) {
|
||||
return (
|
||||
<motion.div
|
||||
layout
|
||||
onClick={onToggle}
|
||||
style={{
|
||||
background: isExpanded ? "rgba(255, 255, 255, 0.12)" : "rgba(255, 255, 255, 0.07)",
|
||||
backdropFilter: "blur(10px)",
|
||||
border: isExpanded ? "1px solid rgba(255, 255, 255, 0.3)" : "1px solid rgba(255, 255, 255, 0.15)",
|
||||
borderRadius: "12px",
|
||||
padding: "24px",
|
||||
cursor: "pointer",
|
||||
gridColumn: isExpanded ? "1 / -1" : "auto",
|
||||
zIndex: isExpanded ? 10 : 1
|
||||
}}
|
||||
whileHover={!isExpanded ? { scale: 1.02, backgroundColor: "rgba(255, 255, 255, 0.12)" } : {}}
|
||||
transition={{ duration: 0.3, type: "spring" }}
|
||||
>
|
||||
<motion.h3 layout="position" style={{ color: "white", marginTop: 0, marginBottom: "15px", fontSize: "1.2rem" }}>
|
||||
{category.category} {isExpanded ? <span style={{ fontSize: "0.8em", opacity: 0.7 }}>(Click to collapse)</span> : null}
|
||||
</motion.h3>
|
||||
|
||||
<motion.div layout="position" style={{ display: "flex", flexWrap: "wrap", gap: "10px", marginBottom: isExpanded ? "20px" : "0" }}>
|
||||
{category.skills.map((skill) => (
|
||||
<span
|
||||
key={skill.name}
|
||||
style={{
|
||||
background: "rgba(255, 255, 255, 0.15)",
|
||||
color: "rgba(255, 255, 255, 0.9)",
|
||||
padding: "6px 12px",
|
||||
borderRadius: "20px",
|
||||
fontSize: "0.85rem",
|
||||
fontWeight: 500,
|
||||
border: "1px solid rgba(255, 255, 255, 0.1)"
|
||||
}}
|
||||
>
|
||||
{skill.name}
|
||||
</span>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{isExpanded && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: 10 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
style={{ borderTop: "1px solid rgba(255,255,255,0.2)", paddingTop: "20px" }}
|
||||
>
|
||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))", gap: "15px" }}>
|
||||
{category.skills.map((skill) => (
|
||||
<div key={skill.name} style={{ display: "flex", flexDirection: "column", gap: "5px" }}>
|
||||
<strong style={{ color: "#fff", fontSize: "1rem" }}>{skill.name}</strong>
|
||||
<p style={{ margin: 0, color: "rgba(255,255,255,0.7)", fontSize: "0.9rem" }}>
|
||||
{skill.description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user