formatted with prettier
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export const BlogCard = ({ title, description, slug, date }) => {
|
||||
return (
|
||||
<Link to={`/blog/${slug}`} className="no-underline">
|
||||
<div className="rounded-lg border border-gray-200 bg-white p-6 shadow-sm hover:shadow-lg transition-shadow duration-200">
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-2xl font-semibold tracking-tight">{title}</h3>
|
||||
<div>
|
||||
<p className="text-sm text-gray-500">{date}</p>
|
||||
<p className="mt-2 text-gray-600">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
import { BlogCard } from "./BlogCard";
|
||||
|
||||
export const BlogList = ({ posts }) => {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-4">
|
||||
{posts.map((post) => (
|
||||
<BlogCard
|
||||
key={post.slug}
|
||||
title={post.title}
|
||||
description={post.description}
|
||||
slug={post.slug}
|
||||
date={post.date}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
|
||||
export const BlogPost = () => {
|
||||
const { slug } = useParams();
|
||||
const [content, setContent] = useState("");
|
||||
const [metadata, setMetadata] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchPost = async () => {
|
||||
try {
|
||||
const post = await import(`../assets/blogs/${slug}.md`);
|
||||
const response = await fetch(post.default);
|
||||
const text = await response.text();
|
||||
setContent(text);
|
||||
|
||||
// const meta = await import(`../content/metadata/${slug}.json`);
|
||||
// setMetadata(meta.default);
|
||||
} catch (error) {
|
||||
console.error("Error loading blog post:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchPost();
|
||||
}, [slug]);
|
||||
|
||||
if (!content) {
|
||||
return (
|
||||
<div className="flex justify-center items-center min-h-screen">
|
||||
<p className="text-gray-600">Loading...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<article className="max-w-3xl mx-auto p-6">
|
||||
{/* <h1 className="text-4xl font-bold mb-4">{metadata.title}</h1>
|
||||
<div className="text-gray-500 mb-8">{metadata.date}</div> */}
|
||||
<div className="prose prose-lg">
|
||||
<ReactMarkdown>{content}</ReactMarkdown>
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Server, Coffee } from "lucide-react";
|
||||
import { Server, Coffee } from 'lucide-react'
|
||||
|
||||
const Footer = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
return (
|
||||
<footer className="mt-16 py-6 border-t border-gray-200 dark:border-gray-800">
|
||||
@@ -11,15 +11,15 @@ const Footer = () => {
|
||||
<Server size={16} className="inline-block" />
|
||||
<span>Self-hosted on my homelab Kubernetes cluster</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex flex-wrap justify-center gap-x-4 gap-y-2 text-center">
|
||||
<span>© {currentYear} Taqi Tahmid</span>
|
||||
<span>•</span>
|
||||
<span>Built with React & Tailwind CSS</span>
|
||||
<span>•</span>
|
||||
<a
|
||||
href="https://github.com/TheTaqiTahmid/my-portfolio.git"
|
||||
target="_blank"
|
||||
<a
|
||||
href="https://github.com/TheTaqiTahmid/my-portfolio.git"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
|
||||
>
|
||||
@@ -29,14 +29,12 @@ const Footer = () => {
|
||||
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<Coffee size={14} className="inline-block" />
|
||||
<span>
|
||||
Powered by coffee and countless hours of debugging
|
||||
</span>
|
||||
<span>Powered by coffee and countless hours of debugging</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
export default Footer
|
||||
|
||||
@@ -1,75 +1,79 @@
|
||||
import { Linkedin, Github, Award } from "lucide-react";
|
||||
import { COLORS } from "../constants";
|
||||
import { Linkedin, Github, Award } from 'lucide-react'
|
||||
import { COLORS } from '../constants'
|
||||
|
||||
const Introduction = () => {
|
||||
const BoldStyle = "text-blue-900 dark:text-blue-300 font-semibold";
|
||||
|
||||
const BoldStyle = 'text-blue-900 dark:text-blue-300 font-semibold'
|
||||
|
||||
const socialLinks = [
|
||||
{
|
||||
icon: <Linkedin size={32} />,
|
||||
href: "https://www.linkedin.com/in/taqi-tahmid/",
|
||||
label: "LinkedIn"
|
||||
href: 'https://www.linkedin.com/in/taqi-tahmid/',
|
||||
label: 'LinkedIn',
|
||||
},
|
||||
{
|
||||
icon: <Github size={32} />,
|
||||
href: "https://github.com/TheTaqiTahmid",
|
||||
label: "GitHub"
|
||||
href: 'https://github.com/TheTaqiTahmid',
|
||||
label: 'GitHub',
|
||||
},
|
||||
{
|
||||
icon: <Award size={32} />,
|
||||
href: "https://ti-user-certificates.s3.amazonaws.com/e0df7fbf-a057-42af-8a1f-590912be5460/3da54db2-f994-4148-a0ca-705ae1d748cd-mohammad-taqi-tahmid-094cf8b4-0db8-4a9f-b787-b4efbb2a90fe-certificate.pdf",
|
||||
label: "CKA Certificate"
|
||||
}
|
||||
];
|
||||
href: 'https://ti-user-certificates.s3.amazonaws.com/e0df7fbf-a057-42af-8a1f-590912be5460/3da54db2-f994-4148-a0ca-705ae1d748cd-mohammad-taqi-tahmid-094cf8b4-0db8-4a9f-b787-b4efbb2a90fe-certificate.pdf',
|
||||
label: 'CKA Certificate',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="text-center p-4 max-w-4xl mx-auto">
|
||||
<h1 className={`text-5xl py-2 ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY} font-medium font-mono tracking-wide`}>
|
||||
<h1
|
||||
className={`text-5xl py-2 ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY} font-medium font-mono tracking-wide`}
|
||||
>
|
||||
Taqi Tahmid
|
||||
</h1>
|
||||
|
||||
|
||||
<h2 className={`text-2xl py-2 font-burtons ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY}`}>
|
||||
Test Automation and DevOps Engineer
|
||||
</h2>
|
||||
|
||||
<div className={`text-md py-5 ${COLORS.TEXT} ${COLORS.DARK_TEXT} leading-8 md:text-xl space-y-4`}>
|
||||
|
||||
<div
|
||||
className={`text-md py-5 ${COLORS.TEXT} ${COLORS.DARK_TEXT} leading-8 md:text-xl space-y-4`}
|
||||
>
|
||||
<p>
|
||||
I am a <span className={BoldStyle}>DevOps</span> and{" "}
|
||||
<span className={BoldStyle}>Test Automation</span> engineer with a{" "}
|
||||
<span className={BoldStyle}>certified Kubernetes Administrator (CKA)</span> certification,
|
||||
specializing in managing Kubernetes clusters and cloud infrastructure.
|
||||
Currently working at Ericsson in Finland as a DevOps Engineer.
|
||||
I am a <span className={BoldStyle}>DevOps</span> and{' '}
|
||||
<span className={BoldStyle}>Test Automation</span> engineer with a{' '}
|
||||
<span className={BoldStyle}>certified Kubernetes Administrator (CKA)</span> certification,
|
||||
specializing in managing Kubernetes clusters and cloud infrastructure. Currently working
|
||||
at Ericsson in Finland as a DevOps Engineer.
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
I bring four years of industry experience in designing CI/CD pipelines
|
||||
and test automation for diverse applications and architectures. I hold a Bachelor's
|
||||
degree from Khulna University of Engineering & Technology (KUET) and a Master's
|
||||
degree from Tampere University. My expertise spans across the entire DevOps lifecycle,
|
||||
from cluster management and infrastructure automation to implementing robust testing frameworks.
|
||||
I bring four years of industry experience in designing CI/CD pipelines and test automation
|
||||
for diverse applications and architectures. I hold a Bachelor's degree from Khulna
|
||||
University of Engineering & Technology (KUET) and a Master's degree from Tampere
|
||||
University. My expertise spans across the entire DevOps lifecycle, from cluster management
|
||||
and infrastructure automation to implementing robust testing frameworks.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center gap-8 py-3">
|
||||
{socialLinks.map((link, index) => (
|
||||
<div key={index} className="group relative">
|
||||
<a
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={`${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY} hover:text-sky-600 dark:hover:text-sky-500 transition-colors duration-200`}
|
||||
aria-label={link.label}
|
||||
>
|
||||
{link.icon}
|
||||
</a>
|
||||
<span className="pointer-events-none absolute -top-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-sm text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
{link.label}
|
||||
</span>
|
||||
</div>
|
||||
<a
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={`${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY} hover:text-sky-600 dark:hover:text-sky-500 transition-colors duration-200`}
|
||||
aria-label={link.label}
|
||||
>
|
||||
{link.icon}
|
||||
</a>
|
||||
<span className="pointer-events-none absolute -top-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-sm text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
{link.label}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Introduction;
|
||||
export default Introduction
|
||||
|
||||
@@ -1,109 +1,120 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import { Menu, Sun, Moon, FileText, Mail, Check, Copy } from "lucide-react";
|
||||
import { COLORS, EMAIL, RESUME } from '../constants';
|
||||
import React, { useEffect, useState, useRef } from 'react'
|
||||
import { Menu, Sun, Moon, FileText, Mail, Check, Copy } from 'lucide-react'
|
||||
import { COLORS, EMAIL, RESUME } from '../constants'
|
||||
|
||||
interface NavProps {
|
||||
darkMode: boolean;
|
||||
toggleDarkMode: () => void;
|
||||
darkMode: boolean
|
||||
toggleDarkMode: () => void
|
||||
}
|
||||
|
||||
const Navbar: React.FC<NavProps> = ({toggleDarkMode, darkMode}) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
const Navbar: React.FC<NavProps> = ({ toggleDarkMode, darkMode }) => {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false)
|
||||
const menuRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const handleCopyEmail = async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(EMAIL);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
await navigator.clipboard.writeText(EMAIL)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
} catch (err) {
|
||||
console.error('Failed to copy email');
|
||||
console.error('Failed to copy email', err)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('DARK_MODE', String(darkMode))
|
||||
},[darkMode])
|
||||
}, [darkMode])
|
||||
|
||||
const menuItem = [
|
||||
{title: 'Home', href: '/'},
|
||||
{title: 'Experience', href: '/experience'},
|
||||
{title: 'Projects', href: '/projects'},
|
||||
{title: 'Interests', href: '/interests'},
|
||||
{ title: 'Home', href: '/' },
|
||||
{ title: 'Experience', href: '/experience' },
|
||||
{ title: 'Projects', href: '/projects' },
|
||||
{ title: 'Interests', href: '/interests' },
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="w-full flex justify-center">
|
||||
<nav className="py-5 mb-6 flex justify-between dark:text-white w-full max-w-5xl px-4">
|
||||
<button
|
||||
onClick={handleCopyEmail}
|
||||
className="flex items-center space-x-2 hover:bg-gray-100 dark:hover:bg-gray-800 px-3 py-2 rounded-lg transition-colors duration-200 group relative"
|
||||
<button
|
||||
onClick={handleCopyEmail}
|
||||
className="flex items-center space-x-2 hover:bg-gray-100 dark:hover:bg-gray-800 px-3 py-2 rounded-lg transition-colors duration-200 group relative"
|
||||
>
|
||||
<Mail size={25} className={`${COLORS.DARK_PRIMARY}`} />
|
||||
<span>Email</span>
|
||||
{copied ? (
|
||||
<Check size={16} className="text-green-500" />
|
||||
) : (
|
||||
<Copy
|
||||
size={16}
|
||||
className="opacity-0 group-hover:opacity-100 transition-opacity duration-200"
|
||||
/>
|
||||
)}
|
||||
<span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
{copied ? 'Copied!' : 'Click to copy'}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<ul className="flex items-center">
|
||||
<li
|
||||
className="transition ease-in-out delay-50 duration-100 cursor-pointer"
|
||||
onClick={toggleDarkMode}
|
||||
>
|
||||
<Mail size={25} className={`${COLORS.DARK_PRIMARY}`} />
|
||||
<span>Email</span>
|
||||
{copied ? (
|
||||
<Check size={16} className="text-green-500" />
|
||||
) : (
|
||||
<Copy size={16} className="opacity-0 group-hover:opacity-100 transition-opacity duration-200" />
|
||||
)}
|
||||
<span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
{copied ? 'Copied!' : 'Click to copy'}
|
||||
</span>
|
||||
</button>
|
||||
<div className="group relative">
|
||||
{darkMode ? (
|
||||
<Sun className="text-amber-400 hover:scale-110" size={30} />
|
||||
) : (
|
||||
<Moon size={24} />
|
||||
)}
|
||||
<span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
{darkMode ? 'Light Mode' : 'Dark Mode'}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="transition ease-in-out delay-50 duration-100">
|
||||
<div className="group relative">
|
||||
<a
|
||||
className="text-white p-2 ml-8 inline-flex"
|
||||
href={RESUME}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<FileText className="hover:scale-110 text-gray-800 dark:text-white" size={30} />
|
||||
</a>
|
||||
<span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
Resume
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="p-2 ml-5 cursor-pointer">
|
||||
<div ref={menuRef} className="group relative">
|
||||
<button onClick={() => setIsMenuOpen(!isMenuOpen)} className="focus:outline-none">
|
||||
<Menu size={24} />
|
||||
</button>
|
||||
|
||||
<ul className="flex items-center">
|
||||
<li className="transition ease-in-out delay-50 duration-100 cursor-pointer"
|
||||
onClick={toggleDarkMode}>
|
||||
<div className="group relative">
|
||||
{darkMode ? <Sun className='text-amber-400 hover:scale-110' size={30} /> : <Moon size={24} />}
|
||||
<span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
{darkMode ? "Light Mode": "Dark Mode"}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="transition ease-in-out delay-50 duration-100">
|
||||
<div className="group relative">
|
||||
<a className="text-white p-2 ml-8 inline-flex"
|
||||
href={RESUME}
|
||||
target="_blank"
|
||||
rel="noreferrer">
|
||||
<FileText className="hover:scale-110 text-gray-800 dark:text-white" size={30} />
|
||||
</a>
|
||||
<span className="pointer-events-none absolute -bottom-8 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-slate-800 px-2 py-1 text-xs text-slate-100 opacity-0 transition before:absolute before:left-1/2 before:top-full before:-translate-x-1/2 before:border-4 before:border-transparent before:border-t-slate-800 before:content-[''] group-hover:opacity-100">
|
||||
Resume
|
||||
</span>
|
||||
{/* Dropdown Menu */}
|
||||
{isMenuOpen && (
|
||||
<div className="absolute right-0 mt-3 w-36 rounded-md shadow-lg bg-amber-50 dark:bg-gray-800 ring-1 ring-black ring-opacity-5">
|
||||
<div className="py-1" role="menu" aria-orientation="vertical">
|
||||
{menuItem.map((item) => (
|
||||
<a
|
||||
key={item.title}
|
||||
href={item.href}
|
||||
className="block px-4 py-2 text-sm text-gray-00 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150"
|
||||
role="menuitem"
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</li>
|
||||
<li className="p-2 ml-5 cursor-pointer">
|
||||
<div ref={menuRef} className="group relative">
|
||||
<button onClick={() => setIsMenuOpen(!isMenuOpen)} className='focus:outline-none'>
|
||||
<Menu size={24}/>
|
||||
</button>
|
||||
|
||||
{/* Dropdown Menu */}
|
||||
{isMenuOpen && (
|
||||
<div className="absolute right-0 mt-3 w-36 rounded-md shadow-lg bg-amber-50 dark:bg-gray-800 ring-1 ring-black ring-opacity-5">
|
||||
<div className="py-1" role="menu" aria-orientation="vertical">
|
||||
{menuItem.map((item) => (
|
||||
<a
|
||||
key={item.title}
|
||||
href={item.href}
|
||||
className="block px-4 py-2 text-sm text-gray-00 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150"
|
||||
role='menuitem'
|
||||
>
|
||||
{item.title}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Navbar;
|
||||
export default Navbar
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import taqimugshot from "../../src/assets/PhotoRoom_20201011_002118.jpg";
|
||||
import taqimugshot from '../../src/assets/PhotoRoom_20201011_002118.jpg'
|
||||
|
||||
const Photo = () => {
|
||||
return (
|
||||
<div className="py-3">
|
||||
<img className="relative mx-auto rounded-full w-80 h-80 object-cover"
|
||||
src={taqimugshot}
|
||||
alt="mugshot"/>
|
||||
</div>
|
||||
<img
|
||||
className="relative mx-auto rounded-full w-80 h-80 object-cover"
|
||||
src={taqimugshot}
|
||||
alt="mugshot"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Photo
|
||||
export default Photo
|
||||
|
||||
@@ -1,39 +1,41 @@
|
||||
import pythonIcon from "../assets/python.svg";
|
||||
import robotIcon from "../assets/robotframework-svgrepo-com.svg";
|
||||
import goIcon from "../assets/go-original.svg";
|
||||
import reactIcon from "../assets/react.svg";
|
||||
import ansibleIcon from "../assets/ansible.svg";
|
||||
import terraformIcon from "../assets/terraform-icon.svg";
|
||||
import jenkinsIcon from "../assets/jenkins.svg";
|
||||
import gitIcon from "../assets/git-icon.svg";
|
||||
import dockerIcon from "../assets/docker-icon.svg";
|
||||
import kubernetesIcon from "../assets/kubernetes.svg";
|
||||
import prometheusIcon from "../assets/prometheus.svg";
|
||||
import grafanaIcon from "../assets/grafana.svg";
|
||||
import { COLORS } from "../constants";
|
||||
import pythonIcon from '../assets/python.svg'
|
||||
import robotIcon from '../assets/robotframework-svgrepo-com.svg'
|
||||
import goIcon from '../assets/go-original.svg'
|
||||
import reactIcon from '../assets/react.svg'
|
||||
import ansibleIcon from '../assets/ansible.svg'
|
||||
import terraformIcon from '../assets/terraform-icon.svg'
|
||||
import jenkinsIcon from '../assets/jenkins.svg'
|
||||
import gitIcon from '../assets/git-icon.svg'
|
||||
import dockerIcon from '../assets/docker-icon.svg'
|
||||
import kubernetesIcon from '../assets/kubernetes.svg'
|
||||
import prometheusIcon from '../assets/prometheus.svg'
|
||||
import grafanaIcon from '../assets/grafana.svg'
|
||||
import { COLORS } from '../constants'
|
||||
|
||||
const Skills = () => {
|
||||
const skills = [
|
||||
{ name: "Python", icon: pythonIcon },
|
||||
{ name: "Golang", icon: goIcon },
|
||||
{ name: "React", icon: reactIcon },
|
||||
{ name: "Robot Framework", icon: robotIcon },
|
||||
{ name: "Ansible", icon: ansibleIcon },
|
||||
{ name: "Terraform", icon: terraformIcon },
|
||||
{ name: "Jenkins", icon: jenkinsIcon },
|
||||
{ name: "Git", icon: gitIcon },
|
||||
{ name: "Docker", icon: dockerIcon },
|
||||
{ name: "Kubernetes", icon: kubernetesIcon },
|
||||
{ name: "Prometheus", icon: prometheusIcon },
|
||||
{ name: "Grafana", icon: grafanaIcon },
|
||||
];
|
||||
{ name: 'Python', icon: pythonIcon },
|
||||
{ name: 'Golang', icon: goIcon },
|
||||
{ name: 'React', icon: reactIcon },
|
||||
{ name: 'Robot Framework', icon: robotIcon },
|
||||
{ name: 'Ansible', icon: ansibleIcon },
|
||||
{ name: 'Terraform', icon: terraformIcon },
|
||||
{ name: 'Jenkins', icon: jenkinsIcon },
|
||||
{ name: 'Git', icon: gitIcon },
|
||||
{ name: 'Docker', icon: dockerIcon },
|
||||
{ name: 'Kubernetes', icon: kubernetesIcon },
|
||||
{ name: 'Prometheus', icon: prometheusIcon },
|
||||
{ name: 'Grafana', icon: grafanaIcon },
|
||||
]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className={`text-2xl py-5 font-burtons ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY}`}>
|
||||
Tools and Languages
|
||||
</h1>
|
||||
<div className={`grid grid-cols-4 gap-6 text-md py-5 leading-8 ${COLORS.TEXT} ${COLORS.DARK_TEXT} mx-auto max-w-2xl md:text-xl`}>
|
||||
<div
|
||||
className={`grid grid-cols-4 gap-6 text-md py-5 leading-8 ${COLORS.TEXT} ${COLORS.DARK_TEXT} mx-auto max-w-2xl md:text-xl`}
|
||||
>
|
||||
{skills.map((skill) => (
|
||||
<div key={skill.name} className="flex flex-col items-center">
|
||||
<img src={skill.icon} alt={skill.name} className="h-10 w-10" />
|
||||
@@ -42,7 +44,7 @@ const Skills = () => {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Skills;
|
||||
export default Skills
|
||||
|
||||
Reference in New Issue
Block a user