feat: enhance skills section
This commit is contained in:
parent
0457420a45
commit
661482c405
6 changed files with 337 additions and 238 deletions
84
app/about/components/skills/icons.jsx
Normal file
84
app/about/components/skills/icons.jsx
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
function ActivityIcon(props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
{...props}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round">
|
||||||
|
<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function CodepenIcon(props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
{...props}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round">
|
||||||
|
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2" />
|
||||||
|
<line x1="12" x2="12" y1="22" y2="15.5" />
|
||||||
|
<polyline points="22 8.5 12 15.5 2 8.5" />
|
||||||
|
<polyline points="2 15.5 12 8.5 22 15.5" />
|
||||||
|
<line x1="12" x2="12" y1="2" y2="8.5" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function WebhookIcon(props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
{...props}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round">
|
||||||
|
<path d="M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2" />
|
||||||
|
<path d="m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06" />
|
||||||
|
<path d="m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function MobileIcon(props) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
{...props}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round">
|
||||||
|
<rect x="5" y="2" width="14" height="20" rx="2" ry="2" />
|
||||||
|
<line x1="12" x2="12" y1="18" y2="18" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
ActivityIcon,
|
||||||
|
CodepenIcon,
|
||||||
|
WebhookIcon,
|
||||||
|
MobileIcon,
|
||||||
|
};
|
||||||
|
|
@ -1,164 +1,249 @@
|
||||||
import { motion } from "framer-motion";
|
"use client";
|
||||||
import Stack from "./stack";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import Tools from "./tools";
|
import { useState } from "react";
|
||||||
|
import { CodepenIcon, WebhookIcon, ActivityIcon, MobileIcon } from "./icons"
|
||||||
|
|
||||||
|
const skillCategories = {
|
||||||
|
web: {
|
||||||
|
title: "Web Development",
|
||||||
|
icon: CodepenIcon,
|
||||||
|
description: "Building modern, responsive web applications",
|
||||||
|
languages: [
|
||||||
|
"HTML",
|
||||||
|
"CSS",
|
||||||
|
"JavaScript",
|
||||||
|
"TypeScript",
|
||||||
|
"PHP",
|
||||||
|
"Python",
|
||||||
|
"React",
|
||||||
|
"NextJS",
|
||||||
|
"TailwindCSS",
|
||||||
|
"Bootstrap",
|
||||||
|
"NodeJS",
|
||||||
|
"ExpressJS",
|
||||||
|
"Laravel",
|
||||||
|
"Flask",
|
||||||
|
"Django",
|
||||||
|
"Firebase"
|
||||||
|
],
|
||||||
|
tools: ["Visual Studio Code", "Git", "Github", "Figma", "Vite", "Docker", "Kubernetes", "Google Cloud", "Postman"],
|
||||||
|
},
|
||||||
|
api: {
|
||||||
|
title: "REST API",
|
||||||
|
icon: WebhookIcon,
|
||||||
|
description: "Creating robust and scalable backend services",
|
||||||
|
languages: [
|
||||||
|
"NodeJS",
|
||||||
|
"ExpressJS",
|
||||||
|
"PHP",
|
||||||
|
"Laravel",
|
||||||
|
"Python",
|
||||||
|
"FastAPI",
|
||||||
|
"Flask",
|
||||||
|
"Django",
|
||||||
|
"MySQL",
|
||||||
|
"PostgreSQL",
|
||||||
|
"MongoDB",
|
||||||
|
"Firebase",
|
||||||
|
],
|
||||||
|
tools: ["Postman", "Docker", "Kubernetes", "Swagger", "Git", "Github", "Google Cloud", "IBM Cloud"],
|
||||||
|
},
|
||||||
|
ai: {
|
||||||
|
title: "AI & Machine Learning",
|
||||||
|
icon: ActivityIcon,
|
||||||
|
description: "Developing intelligent solutions with ML/AI",
|
||||||
|
languages: [
|
||||||
|
"Python",
|
||||||
|
"TensorFlow",
|
||||||
|
"PyTorch",
|
||||||
|
"Scikit-learn",
|
||||||
|
"Pandas",
|
||||||
|
"NumPy",
|
||||||
|
"Jupyter",
|
||||||
|
"OpenAI API",
|
||||||
|
"Gemini API",
|
||||||
|
"LangChain",
|
||||||
|
],
|
||||||
|
tools: [
|
||||||
|
"Jupyter Notebook",
|
||||||
|
"Google Colab",
|
||||||
|
"Google Cloud AI",
|
||||||
|
"AWS SageMaker",
|
||||||
|
"IBM Watson",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
mobile: {
|
||||||
|
title: "Mobile Development",
|
||||||
|
icon: MobileIcon,
|
||||||
|
description: "Cross-platform mobile app development",
|
||||||
|
languages: [
|
||||||
|
"React Native",
|
||||||
|
"JavaScript",
|
||||||
|
"TypeScript",
|
||||||
|
"Dart",
|
||||||
|
"Flutter",
|
||||||
|
],
|
||||||
|
tools: [
|
||||||
|
"Android Studio",
|
||||||
|
"React Native CLI",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function SkillCard({ skill, isSelected, onClick }) {
|
||||||
|
const Icon = skill.icon;
|
||||||
|
|
||||||
function Wrapper({ children }) {
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto container gap-4 p-10 grid grid-cols-1 mt-10">
|
|
||||||
<motion.div
|
<motion.div
|
||||||
className="flex justify-center items-center flex-col mb-5 "
|
onClick={onClick}
|
||||||
initial={{
|
className={`relative cursor-pointer group p-6 rounded-2xl backdrop-blur-lg border transition-all duration-300 ${
|
||||||
opacity: 0,
|
isSelected
|
||||||
x: -200,
|
? "bg-white/20 border-black border-2 shadow-lg"
|
||||||
}}
|
: "bg-white/10 border-gray-300/20 hover:bg-white/20 hover:border-gray-300/30"
|
||||||
whileInView={{
|
}`}
|
||||||
opacity: 1,
|
whileHover={{
|
||||||
x: 0,
|
scale: 1.05,
|
||||||
|
rotateY: 5,
|
||||||
}}
|
}}
|
||||||
|
whileTap={{ scale: 0.95 }}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{
|
transition={{
|
||||||
delay: 0.5,
|
|
||||||
type: "spring",
|
type: "spring",
|
||||||
|
stiffness: 300,
|
||||||
|
damping: 20,
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{/* Glow effect - removed for selected state */}
|
||||||
</motion.div>
|
{!isSelected && (
|
||||||
|
<div className="absolute inset-0 rounded-2xl transition-opacity duration-300 opacity-0 group-hover:opacity-50 bg-gradient-to-r from-gray-400/20 to-gray-600/20 blur-xl" />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="relative z-10 flex flex-col items-center text-center space-y-4">
|
||||||
|
<div
|
||||||
|
className={`p-4 rounded-xl transition-all duration-300 ${
|
||||||
|
isSelected ? "bg-white/30" : "bg-white/10 group-hover:bg-white/20"
|
||||||
|
}`}>
|
||||||
|
<Icon className="w-8 h-8 text-black" />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-black text-lg mb-2">
|
||||||
|
{skill.title}
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-600 text-sm leading-relaxed">
|
||||||
|
{skill.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SkillDetails({ selectedSkill }) {
|
||||||
|
if (!selectedSkill) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: -20 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className="mt-12 space-y-8">
|
||||||
|
{/* Languages & Frameworks */}
|
||||||
|
<motion.div
|
||||||
|
className="backdrop-blur-lg bg-white/20 border border-gray-300/30 rounded-2xl p-8"
|
||||||
|
initial={{ opacity: 0, x: -50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ delay: 0.2 }}>
|
||||||
|
<h3 className="text-2xl font-semibold text-black mb-6 text-center">
|
||||||
|
Languages & Frameworks
|
||||||
|
</h3>
|
||||||
|
<div className="flex flex-wrap justify-center gap-3">
|
||||||
|
{selectedSkill.languages.map((lang, index) => (
|
||||||
|
<motion.span
|
||||||
|
key={lang}
|
||||||
|
initial={{ opacity: 0, scale: 0.8 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
transition={{ delay: 0.3 + index * 0.1 }}
|
||||||
|
className="px-4 py-2 bg-gradient-to-r from-gray-200/60 to-white/40
|
||||||
|
border border-gray-400/40 rounded-full text-black font-medium
|
||||||
|
backdrop-blur-sm hover:scale-105 transition-transform cursor-default
|
||||||
|
hover:bg-gradient-to-r hover:from-gray-300/60 hover:to-white/50">
|
||||||
|
{lang}
|
||||||
|
</motion.span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* Tools */}
|
||||||
|
<motion.div
|
||||||
|
className="backdrop-blur-lg bg-white/20 border border-gray-300/30 rounded-2xl p-8"
|
||||||
|
initial={{ opacity: 0, x: 50 }}
|
||||||
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
transition={{ delay: 0.4 }}>
|
||||||
|
<h3 className="text-2xl font-semibold text-black mb-6 text-center">
|
||||||
|
Tools & Technologies
|
||||||
|
</h3>
|
||||||
|
<div className="flex flex-wrap justify-center gap-3">
|
||||||
|
{selectedSkill.tools.map((tool, index) => (
|
||||||
|
<motion.span
|
||||||
|
key={tool}
|
||||||
|
initial={{ opacity: 0, scale: 0.8 }}
|
||||||
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
transition={{ delay: 0.5 + index * 0.1 }}
|
||||||
|
className="px-4 py-2 bg-gradient-to-r from-gray-300/60 to-gray-100/40
|
||||||
|
border border-gray-500/40 rounded-full text-black font-medium
|
||||||
|
backdrop-blur-sm hover:scale-105 transition-transform cursor-default
|
||||||
|
hover:bg-gradient-to-r hover:from-gray-400/60 hover:to-gray-200/50">
|
||||||
|
{tool}
|
||||||
|
</motion.span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Skills() {
|
export default function Skills() {
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState("web");
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="relative">
|
||||||
<Wrapper>
|
<div className="mx-auto container px-6 py-20">
|
||||||
<section className="grid gap-8 md:gap-12">
|
<motion.div
|
||||||
<div className="text-center space-y-2">
|
initial={{ opacity: 0, y: -20 }}
|
||||||
<h2 className="text-3xl font-bold mt-3 text-black">
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
Skills and Expertise
|
transition={{ duration: 0.6 }}
|
||||||
|
className="text-center space-y-4 mb-16">
|
||||||
|
<h2 className="text-5xl font-bold bg-gradient-to-r from-black to-gray-600 bg-clip-text text-transparent">
|
||||||
|
Skills & Expertise
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-muted-foreground max-w-[800px] mx-auto">
|
<p className="text-gray-600 max-w-2xl mx-auto text-lg leading-relaxed">
|
||||||
Explore some skills I'm proficient in to
|
Explore my technical skills across different domains. Click on any
|
||||||
deliver high-quality solutions.
|
category to see the specific technologies and tools I work with.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</motion.div>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 md:gap-8">
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<CodepenIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">Web Development</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<WebhookIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">REST API</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<ActivityIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">Machine Learning</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<MobileIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">
|
|
||||||
Mobile Development
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/* <div className="flex flex-col items-center gap-2">
|
|
||||||
<CloudIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">Cloud Computing</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<BarChartIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">Data Analysis</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<ComputerIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">Cybersecurity</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
|
||||||
<PackageIcon className="w-12 h-12" />
|
|
||||||
<div className="font-medium">Product Management</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</Wrapper>
|
|
||||||
<div className=" mx-auto container gap-4 p-10 grid grid-cols-1 md:grid-cols-2 mt-10 mb-24">
|
|
||||||
<Stack />
|
|
||||||
<Tools />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ActivityIcon(props) {
|
{/* Skill Categories Grid */}
|
||||||
return (
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||||
<svg
|
{Object.entries(skillCategories).map(([key, skill], index) => (
|
||||||
{...props}
|
<motion.div
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
key={key}
|
||||||
width="24"
|
initial={{ opacity: 0, y: 20 }}
|
||||||
height="24"
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
viewBox="0 0 24 24"
|
transition={{ delay: index * 0.1 }}>
|
||||||
fill="none"
|
<SkillCard
|
||||||
stroke="currentColor"
|
skill={skill}
|
||||||
strokeWidth="2"
|
isSelected={selectedCategory === key}
|
||||||
strokeLinecap="round"
|
onClick={() => setSelectedCategory(key)}
|
||||||
strokeLinejoin="round">
|
/>
|
||||||
<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2" />
|
</motion.div>
|
||||||
</svg>
|
))}
|
||||||
);
|
</div>
|
||||||
}
|
|
||||||
function CodepenIcon(props) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
{...props}
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round">
|
|
||||||
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2" />
|
|
||||||
<line x1="12" x2="12" y1="22" y2="15.5" />
|
|
||||||
<polyline points="22 8.5 12 15.5 2 8.5" />
|
|
||||||
<polyline points="2 15.5 12 8.5 22 15.5" />
|
|
||||||
<line x1="12" x2="12" y1="2" y2="8.5" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function WebhookIcon(props) {
|
{/* Skill Details */}
|
||||||
return (
|
<AnimatePresence mode="wait">
|
||||||
<svg
|
<SkillDetails selectedSkill={skillCategories[selectedCategory]} />
|
||||||
{...props}
|
</AnimatePresence>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
</div>
|
||||||
width="24"
|
</div>
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round">
|
|
||||||
<path d="M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2" />
|
|
||||||
<path d="m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06" />
|
|
||||||
<path d="m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MobileIcon(props) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
{...props}
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round">
|
|
||||||
<rect x="5" y="2" width="14" height="20" rx="2" ry="2" />
|
|
||||||
<line x1="12" x2="12" y1="18" y2="18" />
|
|
||||||
</svg>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import { motion } from "framer-motion";
|
|
||||||
|
|
||||||
export default function Stack() {
|
|
||||||
return (
|
|
||||||
<motion.div
|
|
||||||
className="flex justify-center items-center flex-col mb-5 "
|
|
||||||
initial={{
|
|
||||||
opacity: 0,
|
|
||||||
x: -200,
|
|
||||||
}}
|
|
||||||
whileInView={{
|
|
||||||
opacity: 1,
|
|
||||||
x: 0,
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
delay: 0.5,
|
|
||||||
|
|
||||||
type: "spring",
|
|
||||||
}}>
|
|
||||||
<h2 className="text-2xl md:text-xl font-normal mb-3 md:tracking-[.3rem] lg:tracking-[.5rem] uppercase ">
|
|
||||||
Language & Framework
|
|
||||||
</h2>
|
|
||||||
<p className="text-gray-500 text-center tracking-widest md:px-5">
|
|
||||||
<span className="text-black font-bold">HTML</span> |{" "}
|
|
||||||
<span className="text-black font-bold">CSS</span> |{" "}
|
|
||||||
<span className="text-black font-bold">Javascript</span> |{" "}
|
|
||||||
<span className="text-black font-bold">Typescript</span> |{" "}
|
|
||||||
<span className="text-black font-bold">React</span> |{" "}
|
|
||||||
<span className="text-black font-bold">NextJS</span> |{" "}
|
|
||||||
<span className="text-black font-bold">TailwindCSS</span> |{" "}
|
|
||||||
<span className="text-black font-bold">Bootstrap</span> |{" "}
|
|
||||||
<span className="text-black font-medium">NodeJS</span> |{" "}
|
|
||||||
<span className="text-black font-medium">ExpressJS</span> |{" "}
|
|
||||||
<span className="text-black font-bold">MySQL</span> |{" "}
|
|
||||||
<span className="text-black font-bold">PostgreSQL</span> |{" "}
|
|
||||||
<span className="text-black font-medium">MongoDB</span> |{" "}
|
|
||||||
<span className="text-black font-medium">Firebase</span> |{" "}
|
|
||||||
<span className="text-black font-medium">PHP</span> |{" "}
|
|
||||||
<span className="text-black font-bold">Laravel</span> |{" "}
|
|
||||||
<span className="text-black font-medium">Python</span>
|
|
||||||
</p>
|
|
||||||
</motion.div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
import { motion } from "framer-motion";
|
|
||||||
|
|
||||||
export default function Tools() {
|
|
||||||
return (
|
|
||||||
<motion.div
|
|
||||||
className="flex justify-start items-center flex-col mb-5 "
|
|
||||||
initial={{
|
|
||||||
opacity: 0,
|
|
||||||
x: 200,
|
|
||||||
}}
|
|
||||||
whileInView={{
|
|
||||||
opacity: 1,
|
|
||||||
x: 0,
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
delay: 0.6,
|
|
||||||
|
|
||||||
type: "spring",
|
|
||||||
}}>
|
|
||||||
<h2 className="text-2xl md:text-xl font-normal mb-3 md:tracking-[.3rem] lg:tracking-[.5rem] uppercase">
|
|
||||||
Tools
|
|
||||||
</h2>
|
|
||||||
<p className="text-gray-500 text-center tracking-wider md:px-">
|
|
||||||
<span className="text-black font-bold">Visual Studio Code</span>{" "}
|
|
||||||
| <span className="text-black font-medium">Jet Brains</span> |{" "}
|
|
||||||
<span className="text-black font-bold">Git</span> |{" "}
|
|
||||||
<span className="text-black font-bold">Github</span> |{" "}
|
|
||||||
<span className="text-black font-medium">Figma</span> |{" "}
|
|
||||||
<span className="text-black font-medium">Adobe Photoshop</span>{" "}
|
|
||||||
|{" "}
|
|
||||||
<span className="text-black font-medium">
|
|
||||||
Adobe Premiere Pro
|
|
||||||
</span>{" "}
|
|
||||||
|{" "}
|
|
||||||
<span className="text-black font-medium">
|
|
||||||
Adobe After Effect
|
|
||||||
</span>{" "}
|
|
||||||
|{" "}
|
|
||||||
</p>
|
|
||||||
</motion.div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "15.2.3",
|
"@next/bundle-analyzer": "15.2.3",
|
||||||
|
"@types/react": "19.1.5",
|
||||||
"cross-env": "^7.0.3"
|
"cross-env": "^7.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
|
|
@ -75,6 +75,9 @@ importers:
|
||||||
'@next/bundle-analyzer':
|
'@next/bundle-analyzer':
|
||||||
specifier: 15.2.3
|
specifier: 15.2.3
|
||||||
version: 15.2.3
|
version: 15.2.3
|
||||||
|
'@types/react':
|
||||||
|
specifier: 19.1.5
|
||||||
|
version: 19.1.5
|
||||||
cross-env:
|
cross-env:
|
||||||
specifier: ^7.0.3
|
specifier: ^7.0.3
|
||||||
version: 7.0.3
|
version: 7.0.3
|
||||||
|
|
@ -482,6 +485,9 @@ packages:
|
||||||
'@types/node@17.0.45':
|
'@types/node@17.0.45':
|
||||||
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
|
resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
|
||||||
|
|
||||||
|
'@types/react@19.1.5':
|
||||||
|
resolution: {integrity: sha512-piErsCVVbpMMT2r7wbawdZsq4xMvIAhQuac2gedQHysu1TZYEigE6pnFfgZT+/jQnrRuF5r+SHzuehFjfRjr4g==}
|
||||||
|
|
||||||
'@types/sax@1.2.7':
|
'@types/sax@1.2.7':
|
||||||
resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
|
resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
|
||||||
|
|
||||||
|
|
@ -772,6 +778,9 @@ packages:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
|
csstype@3.1.3:
|
||||||
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
|
|
||||||
damerau-levenshtein@1.0.8:
|
damerau-levenshtein@1.0.8:
|
||||||
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
||||||
|
|
||||||
|
|
@ -2220,6 +2229,10 @@ snapshots:
|
||||||
|
|
||||||
'@types/node@17.0.45': {}
|
'@types/node@17.0.45': {}
|
||||||
|
|
||||||
|
'@types/react@19.1.5':
|
||||||
|
dependencies:
|
||||||
|
csstype: 3.1.3
|
||||||
|
|
||||||
'@types/sax@1.2.7':
|
'@types/sax@1.2.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 17.0.45
|
'@types/node': 17.0.45
|
||||||
|
|
@ -2524,6 +2537,8 @@ snapshots:
|
||||||
shebang-command: 2.0.0
|
shebang-command: 2.0.0
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
|
|
||||||
|
csstype@3.1.3: {}
|
||||||
|
|
||||||
damerau-levenshtein@1.0.8: {}
|
damerau-levenshtein@1.0.8: {}
|
||||||
|
|
||||||
data-view-buffer@1.0.2:
|
data-view-buffer@1.0.2:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue