diff --git a/app/about/components/skills/icons.jsx b/app/about/components/skills/icons.jsx new file mode 100644 index 0000000..3b31c97 --- /dev/null +++ b/app/about/components/skills/icons.jsx @@ -0,0 +1,84 @@ +function ActivityIcon(props) { + return ( + + + + ); +} +function CodepenIcon(props) { + return ( + + + + + + + + ); +} + +function WebhookIcon(props) { + return ( + + + + + + ); +} + +function MobileIcon(props) { + return ( + + + + + ); +} + +export { + ActivityIcon, + CodepenIcon, + WebhookIcon, + MobileIcon, +}; \ No newline at end of file diff --git a/app/about/components/skills/skills.jsx b/app/about/components/skills/skills.jsx index cd1dea2..bf65f58 100644 --- a/app/about/components/skills/skills.jsx +++ b/app/about/components/skills/skills.jsx @@ -1,164 +1,249 @@ -import { motion } from "framer-motion"; -import Stack from "./stack"; -import Tools from "./tools"; +"use client"; +import { motion, AnimatePresence } from "framer-motion"; +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 ( -
+ + {/* Glow effect - removed for selected state */} + {!isSelected && ( +
+ )} + +
+
+ +
+
+

+ {skill.title} +

+

+ {skill.description} +

+
+
+ + ); +} + +function SkillDetails({ selectedSkill }) { + if (!selectedSkill) return null; + + return ( + + {/* Languages & Frameworks */} - {children} + 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 }}> +

+ Languages & Frameworks +

+
+ {selectedSkill.languages.map((lang, index) => ( + + {lang} + + ))} +
-
+ + {/* Tools */} + +

+ Tools & Technologies +

+
+ {selectedSkill.tools.map((tool, index) => ( + + {tool} + + ))} +
+
+
); } export default function Skills() { + const [selectedCategory, setSelectedCategory] = useState("web"); return ( - <> - -
-
-

- Skills and Expertise -

-

- Explore some skills I'm proficient in to - deliver high-quality solutions. -

-
-
-
- -
Web Development
-
-
- -
REST API
-
-
- -
Machine Learning
-
-
- -
- Mobile Development -
-
- {/*
- -
Cloud Computing
+
+
+ +

+ Skills & Expertise +

+

+ Explore my technical skills across different domains. Click on any + category to see the specific technologies and tools I work with. +

+
+ + {/* Skill Categories Grid */} +
+ {Object.entries(skillCategories).map(([key, skill], index) => ( + + setSelectedCategory(key)} + /> + + ))}
-
- -
Data Analysis
-
-
- -
Cybersecurity
-
-
- -
Product Management
-
*/} -
-
-
-
- - + + {/* Skill Details */} + + +
- - ); -} - -function ActivityIcon(props) { - return ( - - - - ); -} -function CodepenIcon(props) { - return ( - - - - - - - - ); -} - -function WebhookIcon(props) { - return ( - - - - - - ); -} - -function MobileIcon(props) { - return ( - - - - +
); } diff --git a/app/about/components/skills/stack.jsx b/app/about/components/skills/stack.jsx deleted file mode 100644 index fb9232c..0000000 --- a/app/about/components/skills/stack.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import { motion } from "framer-motion"; - -export default function Stack() { - return ( - -

- Language & Framework -

-

- HTML |{" "} - CSS |{" "} - Javascript |{" "} - Typescript |{" "} - React |{" "} - NextJS |{" "} - TailwindCSS |{" "} - Bootstrap |{" "} - NodeJS |{" "} - ExpressJS |{" "} - MySQL |{" "} - PostgreSQL |{" "} - MongoDB |{" "} - Firebase |{" "} - PHP |{" "} - Laravel |{" "} - Python -

-
- ); -} \ No newline at end of file diff --git a/app/about/components/skills/tools.jsx b/app/about/components/skills/tools.jsx deleted file mode 100644 index 16121e6..0000000 --- a/app/about/components/skills/tools.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import { motion } from "framer-motion"; - -export default function Tools() { - return ( - -

- Tools -

-

- Visual Studio Code{" "} - | Jet Brains |{" "} - Git |{" "} - Github |{" "} - Figma |{" "} - Adobe Photoshop{" "} - |{" "} - - Adobe Premiere Pro - {" "} - |{" "} - - Adobe After Effect - {" "} - |{" "} -

-
- ); -} diff --git a/package.json b/package.json index 8cabc97..8226525 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "author": { "name": "Alvalen Shafelbilyunazra", "email": "alvalen.shafel04@gmail.com", - "url": "https://alvalens.my.id" + "url": "https://alvalens.my.id" }, "license": "GPL-3.0", "copyright": "Copyright (C) 2025 Alvalen Shafelbilyunazra", @@ -41,6 +41,7 @@ }, "devDependencies": { "@next/bundle-analyzer": "15.2.3", + "@types/react": "19.1.5", "cross-env": "^7.0.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7dd916..ce93c4b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,6 +75,9 @@ importers: '@next/bundle-analyzer': specifier: 15.2.3 version: 15.2.3 + '@types/react': + specifier: 19.1.5 + version: 19.1.5 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -482,6 +485,9 @@ packages: '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + '@types/react@19.1.5': + resolution: {integrity: sha512-piErsCVVbpMMT2r7wbawdZsq4xMvIAhQuac2gedQHysu1TZYEigE6pnFfgZT+/jQnrRuF5r+SHzuehFjfRjr4g==} + '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} @@ -772,6 +778,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -2220,6 +2229,10 @@ snapshots: '@types/node@17.0.45': {} + '@types/react@19.1.5': + dependencies: + csstype: 3.1.3 + '@types/sax@1.2.7': dependencies: '@types/node': 17.0.45 @@ -2524,6 +2537,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + csstype@3.1.3: {} + damerau-levenshtein@1.0.8: {} data-view-buffer@1.0.2: