Skip to content

Commit fcac3e6

Browse files
Feature/skill page (#15) - Enhances graphs for the skill page
* Minor changes to the project for its first release. * Add skills parameter to the experience data, and display it on a separate page. * Test rechtarts for creating graphics for the skills. * Enable the graph as a component. * Add barchart to the skills page. * Enable stacked barpgrah-component. * Adapt the graph to work with the data from the skills page and add legend to the barGraph. * Enable website with the first graph for the skill page. * Update the project version and add some comments for the skill page. * Update packages. * Fix schema use for the skills. * Add await for data expected from workExperience. * Changes to fix the build of the project. * Update to Nextjs 15.2.2 * Update project goals. * Add second graph with information about my technology stack. * Correct temporary data to sample the graphs and improve the style for them. * Add react-icons dependency to the project and enable a hamburger menu. * Update project plan.
1 parent 5049826 commit fcac3e6

File tree

7 files changed

+260
-85
lines changed

7 files changed

+260
-85
lines changed

app/components/graphBar.tsx

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
'use client';
2+
3+
import { BarChart, Bar, XAxis, YAxis, ResponsiveContainer, Legend, CartesianGrid, Tooltip, ComposedChart } from 'recharts';
4+
5+
interface skillData {
6+
name: string;
7+
totalYears: number;
8+
yearsAtCompany: object;
9+
}
10+
11+
interface GraphBarComponentProps {
12+
skillData: skillData[];
13+
}
14+
15+
// Define colors for the bars
16+
const colors = ['#3674B5', '#578FCA', '#A1E3F9', '#D1F8EF']
17+
18+
// Get all unique companies names from the data
19+
function flatCompanies(skillData: skillData[]) {
20+
return Array.from(new Set(skillData.flatMap(item => Object.keys(item.yearsAtCompany))));
21+
}
22+
23+
export function GraphBarVer({ skillData }: GraphBarComponentProps) {
24+
25+
const companies = flatCompanies(skillData);
26+
27+
return (
28+
<ResponsiveContainer width="100%" height="100%">
29+
<BarChart
30+
width={600}
31+
height={500}
32+
data={skillData}
33+
margin={{
34+
top: 20,
35+
right: 20,
36+
bottom: 20,
37+
left: 20,
38+
}}
39+
>
40+
<XAxis dataKey="name"/>
41+
<YAxis
42+
dataKey="totalYears"
43+
domain={[0,6]}/>
44+
<Legend />
45+
<Tooltip />
46+
{companies.map((company, index) => (
47+
<Bar
48+
key={`${company}-${index}`}
49+
dataKey={`yearsAtCompany.${company}`}
50+
stackId="1"
51+
fill={colors[index % colors.length]}
52+
name={company} />
53+
))}
54+
</BarChart>
55+
</ResponsiveContainer>
56+
);
57+
}
58+
59+
export function GraphBarHor({ skillData }: GraphBarComponentProps) {
60+
61+
const companies = flatCompanies(skillData);
62+
63+
return (
64+
<ResponsiveContainer width="100%" height="100%">
65+
<ComposedChart
66+
layout="vertical"
67+
width={600}
68+
height={500}
69+
data={skillData}
70+
margin={{
71+
top: 20,
72+
right: 20,
73+
bottom: 20,
74+
left: 20,
75+
}}
76+
>
77+
<XAxis
78+
type="number"
79+
domain={[0,6]}/>
80+
<YAxis
81+
dataKey="name"
82+
type="category"
83+
tick={{ fontSize: 10 }}/>
84+
<Legend />
85+
<Tooltip />
86+
{companies.map((company, index) => (
87+
<Bar
88+
key={`${company}-${index}`}
89+
dataKey={`yearsAtCompany.${company}`}
90+
stackId="1"
91+
fill={colors[index % colors.length]}
92+
name={company}
93+
/>
94+
))}
95+
</ComposedChart>
96+
</ResponsiveContainer>
97+
);
98+
}

app/components/graphBarComponent.tsx

Lines changed: 0 additions & 43 deletions
This file was deleted.

app/components/nav.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
'use client';
2+
13
import Link from 'next/link'
4+
import { useState } from 'react'
5+
import { FiMenu, FiX } from 'react-icons/fi'
26

37
const navItems = {
48
'/': {
@@ -19,13 +23,28 @@ const navItems = {
1923
}
2024

2125
export function Navbar() {
26+
const [isMenuOpen, setIsMenuOpen] = useState(false)
27+
28+
const toggleMenu = () => {
29+
setIsMenuOpen(!isMenuOpen)
30+
}
31+
2232
return (
2333
<aside className="-ml-[8px] mb-16 tracking-tight">
2434
<div className="lg:sticky lg:top-20">
35+
{/* HamburgerMenu */}
36+
<div className='md:hidden'>
37+
<button
38+
onClick={toggleMenu}
39+
className="text-2xl focus:outline-none"
40+
aria-label="Toggle Menu">
41+
{isMenuOpen ? <FiX/> : <FiMenu/>}
42+
</button>
43+
</div>
44+
{/* NavMenu */}
2545
<nav
26-
className="flex flex-row items-start relative px-0 pb-0 fade md:overflow-auto scroll-pr-6 md:relative"
27-
id="nav"
28-
>
46+
className={`${isMenuOpen ? 'block' : 'hidden'} md:flex flex-col md:flex-row items-start relative px-0 pb-0 fade md:overflow-auto scroll-pr-6 md:relative`}
47+
id="nav">
2948
<div className="flex flex-row space-x-0 pr-10">
3049
{Object.entries(navItems).map(([path, { name }]) => {
3150
return (

app/skills/page.tsx

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
// import { getSkills } from "app/utils/utils";
2-
import {GraphBarComponent} from "app/components/graphBarComponent";
2+
import {GraphBarVer, GraphBarHor} from "app/components/graphBar";
33

44
// Temporary data for the graph
55
const testProgramingExperience = [
6-
{
7-
name: 'Java',
8-
totalYears: 1,
9-
yearsAtCompany: {
10-
'Livello/HSRW': 1,
11-
}
12-
},
136
{
147
name: 'C#',
158
totalYears: 1,
@@ -35,23 +28,95 @@ const testProgramingExperience = [
3528
}
3629
},
3730
]
38-
39-
// TODO-1: define method to get data from skills for the graph above
40-
// TODO-2: create seconds graph for the technologies
41-
// TODO-3: create a npm package for the graph component?
31+
// temporary technology data
32+
const testTechStackExperience = [
33+
{
34+
name: 'AZ/GCP',
35+
totalYears: 5,
36+
yearsAtCompany: {
37+
'GEA': 3,
38+
'Livello/HSRW': 2,
39+
}
40+
},
41+
{
42+
name: '.NET',
43+
totalYears: 3,
44+
yearsAtCompany: {
45+
'GEA': 3,
46+
}
47+
},
48+
{
49+
name: 'React/React Native',
50+
totalYears: 3,
51+
yearsAtCompany: {
52+
'Livello/HSRW': 2,
53+
'GEA': 1,
54+
}
55+
},
56+
{
57+
name: '2G/3G/4G/5G',
58+
totalYears: 6,
59+
yearsAtCompany: {
60+
'Huawei': 3.5,
61+
'WIND': 2,
62+
}
63+
},
64+
{
65+
name: 'GitLab/DevOps Pipelines',
66+
totalYears: 5,
67+
yearsAtCompany: {
68+
'Livello/HSRW': 3,
69+
'GEA': 2,
70+
}
71+
},
72+
{
73+
name: 'SQL/NoSQL',
74+
totalYears: 4,
75+
yearsAtCompany: {
76+
'Livello/HSRW': 2,
77+
'GEA': 2,
78+
}
79+
},
80+
{
81+
name: 'Docker',
82+
totalYears: 4,
83+
yearsAtCompany: {
84+
'Livello/HSRW': 2,
85+
'GEA': 2,
86+
}
87+
},
88+
{
89+
name: 'Kubernetes',
90+
totalYears: 1,
91+
yearsAtCompany: {
92+
'Livello/HSRW': 1,
93+
}
94+
},
95+
{
96+
name: 'Ansible',
97+
totalYears: 2,
98+
yearsAtCompany: {
99+
'Livello/HSRW': 2,
100+
}
101+
}
102+
]
42103

43104
export default function Page() {
44105
return (
45-
// TODO: Change the grid size for the cols below when using XL screen (greater than 1280 px)
46-
<section className="grid xl:grid-cols-2 w-full gap-10 max-w-[1400px]">
106+
<section className="grid xl:grid-cols-2 w-full gap-10 max-w-[1600px]">
47107
<h1 className="mb-8 text-2xl font-semibold tracking-tighter">Skills</h1>
48108
<p>In the graph below you can find the years of experience that I have collected per programming language on each company that I have work for.</p>
49109

50-
<GridItem title="Programming Experience">
51-
<GraphBarComponent skillData={testProgramingExperience} />
110+
<GridItem title="Main Programming Experience">
111+
<GraphBarVer skillData={testProgramingExperience} />
52112
</GridItem>
113+
<GridItem title="Main Technology Stack">
114+
<GraphBarHor skillData={testTechStackExperience} />
115+
</GridItem>
116+
53117
</section>
54118
);
119+
// TODO: Enable the code below when the getSkills method is defined
55120
{/* <ul>
56121
{getSkills().map((skill) => (
57122
<li key={skill}>{skill}</li>
@@ -61,8 +126,8 @@ export default function Page() {
61126

62127
function GridItem({ title, children }) {
63128
return (
64-
<div className="flex flex-col items-center justify-center p-4 border border-slate-900 bg-slate-900/1 rounded-xl h-[400px]">
65-
<h3 className="text-2xl font-semibold text-white mb-4">{title}</h3>
129+
<div className="flex flex-col items-center justify-center p-4 border border-slate-900 bg-slate-900/1 rounded-xl h-[400px] w-[700px]">
130+
<h3 className="text-2xl font-semibold text-blue-500 mb-4">{title}</h3>
66131
{children}
67132
</div>
68133
);

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"private": true,
3-
"version": "1.1.1",
3+
"version": "1.1.2",
44
"scripts": {
55
"dev": "next dev",
66
"build": "next build",
@@ -19,6 +19,7 @@
1919
"postcss": "^8.5.3",
2020
"react": "18.2.0",
2121
"react-dom": "18.2.0",
22+
"react-icons": "^5.5.0",
2223
"recharts": "^2.15.1",
2324
"sugar-high": "^0.6.1",
2425
"tailwindcss": "4.0.0-alpha.13",

pnpm-lock.yaml

Lines changed: 12 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)