Compare commits

...

10 Commits

12 changed files with 14533 additions and 395 deletions

14428
frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,8 @@
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-markdown": "^9.0.3",
"react-router-dom": "^7.1.1"
"react-router-dom": "^7.1.1",
"styled-component": "^2.8.0"
},
"devDependencies": {
"@eslint/js": "^9.9.0",

View File

@ -4,6 +4,7 @@ import { Routes, Route } from 'react-router-dom'
import './App.css'
import Home from './pages/Home'
import Navbar from './components/Navbar'
import Sidebar from './components/Sidebar'
import Footer from './components/Footer'
import Experience from './pages/Experience'
import Projects from './pages/Projects'
@ -24,14 +25,22 @@ function App() {
<main className="bg-amber-50 px-10 dark:bg-gray-900">
<section className="min-h-screen">
<Navbar toggleDarkMode={toggleDarkMode} darkMode={darkMode} />
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experience" element={<Experience />} />
<Route path="/projects" element={<Projects />} />
<Route path="/Interests" element={<Interests />} />
</Routes>
</Router>
<div className="md:flex md:flex-row md:h-full">
<div className="mb-4 md:w-1/4 md:max-w-[260px] md:max-h-[900px] border-2 border-gray-300 dark:border-gray-700 rounded-lg shadow-sm">
<Sidebar />
</div>
<div className="md:flex-1">
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experience" element={<Experience />} />
<Route path="/projects" element={<Projects />} />
<Route path="/Interests" element={<Interests />} />
</Routes>
</Router>
</div>
<div className="hidden md:block md:w-1/4 md:max-w-[260px] md:max-h-[900px]"></div>
</div>
<Footer />
</section>
</main>

View File

@ -29,7 +29,7 @@ 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 Love</span>
</div>
</div>
</div>

View File

@ -1,5 +1,4 @@
import { COLORS, SOCIALLINKS } from '../constants'
import { Tooltip } from './Tooltip'
import { COLORS } from '../constants'
const Introduction = () => {
const BoldStyle = 'text-blue-900 dark:text-blue-300 font-semibold'
@ -35,24 +34,6 @@ const Introduction = () => {
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">
<Tooltip label={link.label} position="top">
<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>
</Tooltip>
</div>
))}
</div>
</div>
)
}

View File

@ -102,7 +102,8 @@ const Navbar: React.FC<NavProps> = ({ toggleDarkMode, darkMode }) => {
{/* 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">
// Dropdown Menu. The z value is set to 10 so that it appears above other elements.
<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 z-10">
<div className="py-1" role="menu" aria-orientation="vertical">
{menuItem.map((item) => (
<a

View File

@ -0,0 +1,75 @@
import { COLORS, SOCIALLINKS } from '../constants'
import { Tooltip } from './Tooltip'
interface LinkProps {
href: string
children: React.ReactNode
icon: React.ReactNode
label: string
}
const Link: React.FC<LinkProps> = ({ icon, href, children, label }) => {
return (
<div className="transition-all duration-200 hover:translate-x-1">
<div className="m-2 border border-gray-200 dark:border-gray-700 p-2 md:p-3 rounded-lg hover:shadow-md">
<Tooltip label={label} position="top" additionalClass="md:hidden">
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="flex items-center text-gray-700 dark:text-gray-200 hover:text-blue-600 dark:hover:text-blue-400"
>
{icon}
<span className="text-sm font-medium hidden md:inline">{children}</span>
</a>
</Tooltip>
</div>
</div>
)
}
const Sidebar = () => {
const SectionTitle = ({ children }: { children: React.ReactNode }) => (
<h2
className={`mt-4 mb-4 text-lg font-semibold ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY} hidden md:block`}
>
{children}
</h2>
)
return (
<div
className={`grid grid-cols-4 md:grid-cols-1 p-2 md:p-6 max-w-xs mx-auto ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY} rounded-xl shadow-sm`}
>
<SectionTitle>Contact</SectionTitle>
{SOCIALLINKS.contact.map((link, index) => (
<Link key={index} icon={link.icon} href={link.href} label={link.text}>
{link.text}
</Link>
))}
<SectionTitle>Connect</SectionTitle>
{SOCIALLINKS.connect.map((link, index) => (
<Link key={index} icon={link.icon} href={link.href} label={link.text}>
{link.text}
</Link>
))}
<SectionTitle>Follow</SectionTitle>
{SOCIALLINKS.follow.map((link, index) => (
<Link key={index} icon={link.icon} href={link.href} label={link.text}>
{link.text}
</Link>
))}
<SectionTitle>Achievements</SectionTitle>
{SOCIALLINKS.publications.map((link, index) => (
<Link key={index} icon={link.icon} href={link.href} label={link.text}>
{link.text}
</Link>
))}
</div>
)
}
export default Sidebar

View File

@ -1,6 +1,33 @@
import { COLORS, SKILLS } 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 },
]
return (
<div>
<h1 className={`text-2xl py-5 font-burtons ${COLORS.PRIMARY} ${COLORS.DARK_PRIMARY}`}>
@ -9,7 +36,7 @@ const Skills = () => {
<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) => (
{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" />
<p className="mt-2 text-center">{skill.name}</p>

View File

@ -2,9 +2,10 @@ export interface TooltipProps {
children: React.ReactNode
label: string
position: 'top' | 'bottom' | 'left' | 'right'
additionalClass?: string
}
export const Tooltip: React.FC<TooltipProps> = ({ children, label, position }) => {
export const Tooltip: React.FC<TooltipProps> = ({ children, label, position, additionalClass }) => {
const tooltipStyles = {
top: 'bottom-full left-1/2 -translate-x-1/2',
bottom: 'top-full left-1/2 -translate-x-1/2',
@ -12,7 +13,7 @@ export const Tooltip: React.FC<TooltipProps> = ({ children, label, position }) =
right: 'left-full top-1/2 -translate-y-1/2',
}
const tooltipPosition: string = tooltipStyles[position]
const tooltipClass = `pointer-events-none absolute mt-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 ${tooltipPosition}`
const tooltipClass = `pointer-events-none absolute mt-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 ${tooltipPosition} ${additionalClass}`
return (
<div className="group relative">

View File

@ -1,4 +1,6 @@
import { Linkedin, Github, Award, Link } from 'lucide-react'
import { Aperture, Instagram, Mail, Globe, ScrollText } from 'lucide-react'
import { Camera, Plane, Film, Server, Cpu, Trophy, Car, Gamepad2 } from 'lucide-react'
import pythonIcon from './assets/python.svg'
import robotIcon from './assets/robotframework-svgrepo-com.svg'
import goIcon from './assets/go-original.svg'
@ -26,7 +28,6 @@ export const EMAIL = 'taqitahmid@gmail.com'
export const RESUME =
'https://www.linkedin.com/in/taqi-tahmid/overlay/1735981754176/single-media-viewer/?profileId=ACoAACDU_GsBCgKtvw2bmzbVwTy2WixBG6-e3JM'
export const PROJECTS = [
{
title: 'Self-Hosted Kubernetes Homelab Cluster',
@ -87,23 +88,58 @@ export const PROJECTS = [
},
]
export const SOCIALLINKS = [
{
icon: <Linkedin size={32} />,
href: 'https://www.linkedin.com/in/taqi-tahmid/',
label: 'LinkedIn',
},
{
icon: <Github size={32} />,
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',
},
]
export const iconClass = 'text-blue-600 dark:text-blue-400 mr-3'
export const SOCIALLINKS = {
contact: [
{
icon: <Mail size={20} className={iconClass} />,
href: 'mailto:taqitahmid@gmail.com',
text: 'Email Me',
},
{
icon: <Globe size={20} className={iconClass} />,
href: 'https://portfolio.tahmidcloud.com/',
text: 'Website',
},
],
connect: [
{
icon: <Linkedin size={20} className={iconClass} />,
href: 'https://www.linkedin.com/in/taqi-tahmid/',
text: 'LinkedIn',
},
{
icon: <Github size={20} className={iconClass} />,
href: 'https://github.com/theTaqiTahmid',
text: 'GitHub',
},
],
follow: [
{
icon: <Aperture size={20} className={iconClass} />,
href: 'https://500px.com/p/taqi1203050?view=photos',
text: 'Photography',
},
{
icon: <Instagram size={20} className={iconClass} />,
href: 'https://www.instagram.com/tahmidtaqi/',
text: 'Instagram',
},
],
publications: [
{
icon: <Award size={20} className={iconClass} />,
href: 'https://www.credly.com/badges/abb049aa-d811-4954-a460-8c7351ceba3e/public_url',
text: 'CKA Certification',
},
{
icon: <ScrollText size={20} className={iconClass} />,
href: 'https://scholar.google.fi/citations?user=w3BoP0AAAAAJ&hl=en',
text: 'Google Scholar',
},
],
}
export const SKILLS = [
{ name: 'Python', icon: pythonIcon },
@ -118,4 +154,129 @@ export const SKILLS = [
{ name: 'Kubernetes', icon: kubernetesIcon },
{ name: 'Prometheus', icon: prometheusIcon },
{ name: 'Grafana', icon: grafanaIcon },
]
]
export const INTERESTS = [
{
title: 'Travelling',
icon: <Plane size={32} />,
description:
'Exploring new places, experiencing different cultures, and creating lasting memories through adventures around the world. From scenic landscapes to bustling cities, every journey is an opportunity to learn and grow.',
},
{
title: 'Photography',
icon: <Camera size={32} />,
description:
'Capturing moments and perspectives through the lens. Particularly interested in landscape and street photography, always looking to improve composition skills and trying new techniques.',
},
{
title: 'Movies & Shows',
icon: <Film size={32} />,
description:
'Passionate about cinema across various genres and cultures. Enjoy analyzing cinematography, storytelling techniques, and discovering hidden gems from different parts of the world.',
},
{
title: 'Homelab',
icon: <Server size={32} />,
description:
'Managing a personal homelab setup for experimenting with self-hosted services, networking configurations, and learning about system administration in a hands-on environment.',
},
{
title: 'New Technologies',
icon: <Cpu size={32} />,
description:
'Keeping up with the latest technological advancements, particularly in cloud computing, automation, and emerging DevOps tools. Enjoy experimenting with new frameworks and platforms.',
},
{
title: 'Playing Video Games',
icon: <Gamepad2 size={32} />,
description:
'Enthusiastic gamer with a deep appreciation for interactive storytelling and virtual worlds. Enjoy exploring diverse genres from immersive RPGs to strategic multiplayer games.',
},
{
title: 'Sports',
icon: <Trophy size={32} />,
description: 'Avid sports enthusiast following multiple disciplines:',
subInterests: [
{
name: 'Football',
details:
'Following major leagues and international tournaments, appreciating the tactical aspects and team dynamics of the beautiful game.',
},
{
name: 'Cricket',
details:
'Enjoying both test matches and limited-overs formats, following international competitions and analyzing game strategies.',
},
{
name: 'Formula 1',
icon: <Car size={24} />,
details:
'Following the high-speed world of F1, keeping up with team developments, race strategies, and technical innovations in motorsport.',
},
],
},
]
export const EXPERIENCE = [
{
title: 'Experienced Developer (DevOps)',
company: 'Ericsson',
location: 'Jorvas, Finland',
period: 'November-2022 - Present',
responsibilities: [
'Managing and optimizing Kubernetes clusters in production environments',
'Designing and implementing CI/CD pipelines for end to end product development flow using Jenkins',
'Automating infrastructure deployment using Terraform and Ansible',
'Develop and maintain monitoring solutions of various resources for greater observability and troubleshooting',
'Actively support development teams regarding product development flow and infrastructure issues',
'Develop and perform automated end-to-end product testing with Python, Robot Framework, Jenkins, Bash, etc.',
],
tools: 'Kubernetes, Docker, KVM, Openstack, Ansible, Terraform, Prometheus, Grafana',
},
{
title: 'Test Engineer',
company: 'Nokia',
location: 'Espoo, Finland',
period: 'June-2021 - October-2022',
responsibilities: [
'Develop and maintain Cloud RAN E2E test setup for vCU and vDU application testing on top of RedHat Openshift',
'Develop automation and CI/CD flow for Cloud RAN testing using Python, Robot Framework, Bash, Jenkins etc.',
'Develop and perform automated testing to validate the functionality of Nokia Cloud RAN base stations',
'Integrate new hardware and software into the test setup',
'Perform hands on debugging and log analysis to nd root cause and solve any software or hardware issues',
],
tools: 'Keysight Nemo Outdoor, Nemo Analyze, Qualcomm PCAT, QCAT, QXDM',
},
{
title: 'Testing and Prototyping Intern',
company: 'GE Healthcare',
location: 'Helsinki, Finland',
period: 'Jan-2019 - May-2021',
responsibilities: [
'Planning, writing, and performing manual and automated tests of different prototype wireless medical devices',
'Designing driver and PCB circuits in Altium Designer to test the performance of the Digital Sensor Interface',
'Ensuring the PCB componets used in the devices are EU RoHS and REACH compliant',
],
tools:
'LTSpice, Altium Designer, HP-ALM, Vector Network Analyzer, Spectrum Analyzer, Climate Chamber',
},
]
export const EDUCATION = [
{
degree: "Master's in Wireless Communication & RF Systems",
institution: 'Tampere University',
location: 'Tampere, Finland',
period: '2018 - 2020',
thesis: '5G Reference Signals and their Possibility to be for 5G Based Positioning',
},
{
degree: "Bachelor's in Electrical & Electronic Engineering",
institution: 'Khulna University of Engineering & Technology',
location: 'Khulna, Bangladesh',
period: '2013 - 2017',
thesis:
'Density-based smart traffic control system using Canny edge detection technique using Digital Image Processing',
},
]

View File

@ -1,70 +1,7 @@
import { Building2, Calendar, GraduationCap, MapPin, Microscope, Wrench } from 'lucide-react'
import { COLORS } from '../constants'
import { COLORS, EXPERIENCE, EDUCATION } from '../constants'
const Experience = () => {
const experiences = [
{
title: 'Experienced Developer (DevOps)',
company: 'Ericsson',
location: 'Jorvas, Finland',
period: 'November-2022 - Present',
responsibilities: [
'Managing and optimizing Kubernetes clusters in production environments',
'Designing and implementing CI/CD pipelines for end to end product development flow using Jenkins',
'Automating infrastructure deployment using Terraform and Ansible',
'Develop and maintain monitoring solutions of various resources for greater observability and troubleshooting',
'Actively support development teams regarding product development flow and infrastructure issues',
'Develop and perform automated end-to-end product testing with Python, Robot Framework, Jenkins, Bash, etc.',
],
tools: 'Kubernetes, Docker, KVM, Openstack, Ansible, Terraform, Prometheus, Grafana',
},
{
title: 'Test Engineer',
company: 'Nokia',
location: 'Espoo, Finland',
period: 'June-2021 - October-2022',
responsibilities: [
'Develop and maintain Cloud RAN E2E test setup for vCU and vDU application testing on top of RedHat Openshift',
'Develop automation and CI/CD flow for Cloud RAN testing using Python, Robot Framework, Bash, Jenkins etc.',
'Develop and perform automated testing to validate the functionality of Nokia Cloud RAN base stations',
'Integrate new hardware and software into the test setup',
'Perform hands on debugging and log analysis to nd root cause and solve any software or hardware issues',
],
tools: 'Keysight Nemo Outdoor, Nemo Analyze, Qualcomm PCAT, QCAT, QXDM',
},
{
title: 'Testing and Prototyping Intern',
company: 'GE Healthcare',
location: 'Helsinki, Finland',
period: 'Jan-2019 - May-2021',
responsibilities: [
'Planning, writing, and performing manual and automated tests of different prototype wireless medical devices',
'Designing driver and PCB circuits in Altium Designer to test the performance of the Digital Sensor Interface',
'Ensuring the PCB componets used in the devices are EU RoHS and REACH compliant',
],
tools:
'LTSpice, Altium Designer, HP-ALM, Vector Network Analyzer, Spectrum Analyzer, Climate Chamber',
},
]
const education = [
{
degree: "Master's in Wireless Communication & RF Systems",
institution: 'Tampere University',
location: 'Tampere, Finland',
period: '2018 - 2020',
thesis: '5G Reference Signals and their Possibility to be for 5G Based Positioning',
},
{
degree: "Bachelor's in Electrical & Electronic Engineering",
institution: 'Khulna University of Engineering & Technology',
location: 'Khulna, Bangladesh',
period: '2013 - 2017',
thesis:
'Density-based smart traffic control system using Canny edge detection technique using Digital Image Processing',
},
]
return (
<div className="p-4 max-w-4xl mx-auto">
<h2
@ -74,7 +11,7 @@ const Experience = () => {
</h2>
<div className="space-y-8">
{experiences.map((exp, index) => (
{EXPERIENCE.map((exp, index) => (
<div
key={index}
className={`border-l-4 ${COLORS.BORDER} ${COLORS.DARK_BORDER} pl-4 space-y-2`}
@ -128,7 +65,7 @@ const Experience = () => {
</h2>
<div className="space-y-6">
{education.map((edu, index) => (
{EDUCATION.map((edu, index) => (
<div
key={index}
className={`border-l-4 ${COLORS.BORDER} ${COLORS.DARK_BORDER} pl-4 space-y-2`}

View File

@ -1,69 +1,6 @@
import { Camera, Plane, Film, Server, Cpu, Trophy, Car, Gamepad2 } from 'lucide-react'
import { COLORS } from '../constants'
import { COLORS, INTERESTS } from '../constants'
const Interests = () => {
const interests = [
{
title: 'Travelling',
icon: <Plane size={32} />,
description:
'Exploring new places, experiencing different cultures, and creating lasting memories through adventures around the world. From scenic landscapes to bustling cities, every journey is an opportunity to learn and grow.',
},
{
title: 'Photography',
icon: <Camera size={32} />,
description:
'Capturing moments and perspectives through the lens. Particularly interested in landscape and street photography, always looking to improve composition skills and trying new techniques.',
},
{
title: 'Movies & Shows',
icon: <Film size={32} />,
description:
'Passionate about cinema across various genres and cultures. Enjoy analyzing cinematography, storytelling techniques, and discovering hidden gems from different parts of the world.',
},
{
title: 'Homelab',
icon: <Server size={32} />,
description:
'Managing a personal homelab setup for experimenting with self-hosted services, networking configurations, and learning about system administration in a hands-on environment.',
},
{
title: 'New Technologies',
icon: <Cpu size={32} />,
description:
'Keeping up with the latest technological advancements, particularly in cloud computing, automation, and emerging DevOps tools. Enjoy experimenting with new frameworks and platforms.',
},
{
title: 'Playing Video Games',
icon: <Gamepad2 size={32} />,
description:
'Enthusiastic gamer with a deep appreciation for interactive storytelling and virtual worlds. Enjoy exploring diverse genres from immersive RPGs to strategic multiplayer games.',
},
{
title: 'Sports',
icon: <Trophy size={32} />,
description: 'Avid sports enthusiast following multiple disciplines:',
subInterests: [
{
name: 'Football',
details:
'Following major leagues and international tournaments, appreciating the tactical aspects and team dynamics of the beautiful game.',
},
{
name: 'Cricket',
details:
'Enjoying both test matches and limited-overs formats, following international competitions and analyzing game strategies.',
},
{
name: 'Formula 1',
icon: <Car size={24} />,
details:
'Following the high-speed world of F1, keeping up with team developments, race strategies, and technical innovations in motorsport.',
},
],
},
]
return (
<div className="p-4 max-w-4xl mx-auto">
<h1
@ -73,7 +10,7 @@ const Interests = () => {
</h1>
<div className="grid gap-6 md:grid-cols-2">
{interests.map((interest, index) => (
{INTERESTS.map((interest, index) => (
<div
key={index}
className={`group p-6 rounded-lg border-2 border-gray-300 dark:border-gray-700 hover:shadow-lg transition-all duration-300 ${