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.
-
-
-
-
-
-
-
-
-
- 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)}
+ />
+
+ ))}
-
-
-
*/}
-
-
-
-
-
-
+
+ {/* 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: