|
1 |
| -import { useMediaQuery } from '@/hooks/useMediaQuery'; |
2 |
| -import { BaselineIcon, GalleryVerticalEndIcon } from 'lucide-react'; |
3 |
| -import { Fragment, FunctionComponent, useState } from 'react'; |
4 |
| -import { techIcons } from '@/lib/techIcons'; |
| 1 | +import { Badge } from '@/components/ui/Badge'; |
| 2 | +import { useState } from 'react'; |
5 | 3 |
|
6 |
| -interface Props extends React.SVGProps<SVGElement> { |
7 |
| - size?: number | string; |
| 4 | +interface SkillsProps { |
| 5 | + arr: string[]; |
8 | 6 | }
|
9 | 7 |
|
10 |
| -type TechIconsDisplayProps = { |
11 |
| - heading: string |
12 |
| - techNames: string[] |
13 |
| -} |
14 |
| - |
15 |
| -function TechIconsDisplay({ heading, techNames }: TechIconsDisplayProps) { |
16 |
| - const hasRemainingIcons = (list: string[], startIndex: number, icons = techIcons): boolean => { |
17 |
| - for (let i = startIndex + 1; i < list.length; i++) { |
18 |
| - if (list[i] in icons) { |
19 |
| - return true; |
20 |
| - } |
21 |
| - } |
22 |
| - return false; |
23 |
| - } |
24 |
| - |
25 |
| - const isDesktop = useMediaQuery('(min-width: 768px)') |
26 |
| - const TechIcon: React.FunctionComponent<{ techName: string }> = ({techName}) => { |
27 |
| - // TODO: For techName = SQL, handle multiple SQL service like Postgres, MYSQL, MongoDB, etc. |
28 |
| - const IconComponent: React.FunctionComponent<Props> = techIcons[techName] |
29 |
| - return ( |
30 |
| - <div className="items-center justify-center"> |
31 |
| - <IconComponent size={isDesktop ? 50 : 35}/> |
32 |
| - </div> |
33 |
| - ) |
34 |
| - } |
35 |
| - const [showIcons, setShowIcons] = useState(false) |
36 |
| - const toggleView = () => setShowIcons(!showIcons) |
37 |
| - |
38 |
| - return ( |
39 |
| - <div className="px-4"> |
40 |
| - <div className="inline-flex items-center mb-2"> |
41 |
| - <h3 className="text-xl underline underline-offset-4 items-center"> |
42 |
| - <span className="font-bold">{heading}</span> |
43 |
| - </h3> |
44 |
| - <span> </span> |
45 |
| - {/* { |
46 |
| - showIcons |
47 |
| - ? <BaselineIcon onClick={toggleView} className="w-5 h-5 md:w-6 md:h-6"/> |
48 |
| - : <GalleryVerticalEndIcon onClick={toggleView} className="w-5 h-5 md:w-6 md:h-6"/> |
49 |
| - } */} |
50 |
| - </div> |
51 |
| - {techNames.length > 0 ? ( |
52 |
| - <div> |
53 |
| - {/* TODO: Make this compatible for mobile screens in the future */} |
54 |
| - {/* className="md:flex md:flex-row md:items-start md:justify-start grid grid-cols-2" */} |
55 |
| - {/* {techNames.map((lang, index) => ( |
56 |
| - (lang in techIcons) && <Fragment key={lang}> |
57 |
| - {showIcons ? ( |
58 |
| - <div className="inline-flex items-center justify-center" aria-label={lang}> |
59 |
| - <div className="bg-white p-1 rounded-md shadow-sm"> |
60 |
| - <TechIcon techName={lang} /> |
61 |
| - </div> |
62 |
| - </div> |
63 |
| - ) : ( |
64 |
| - <span className="inline-flex items-center"> |
65 |
| - {lang} |
66 |
| - {index < techNames.length - 1 && hasRemainingIcons(techNames, index) && ( |
67 |
| - <span className="mr-1">,</span> |
68 |
| - )} |
69 |
| - </span> |
70 |
| - )} |
71 |
| - </Fragment> |
72 |
| - ))} */} |
73 |
| - {techNames.map((lang, index) => ( |
74 |
| - <span className="inline-flex items-center"> |
75 |
| - {lang} |
76 |
| - {index < techNames.length - 1 && ( |
77 |
| - <span key={index} className="mr-1">,</span> |
78 |
| - )} |
79 |
| - </span> |
80 |
| - ))} |
81 |
| - </div> |
82 |
| - ) : ( |
83 |
| - <p className="text-gray-600">Nothing to display.</p> |
84 |
| - )} |
85 |
| - </div> |
86 |
| - ) |
87 |
| -} |
88 |
| - |
89 |
| -export function Skills() { |
| 8 | +export function Skills({ arr }: SkillsProps) { |
| 9 | + const [skills, setSkills] = useState(arr) |
90 | 10 | return (
|
91 | 11 | <section id="skills" className="mb-12">
|
92 | 12 | <h2 className="text-2xl md:text-3xl lg:text-4xl font-section font-bold mb-4">Skills</h2>
|
93 |
| - <div className="flex flex-col justify-around"> |
94 |
| - {/* TODO: Check if this fits in small screens & if this is good at all or not */} |
95 |
| - <TechIconsDisplay |
96 |
| - heading="Programming Languages:" |
97 |
| - techNames={["Python3", "HTML5", "CSS3", "JavaScript (ES6)", "TypeScript", "Go", "C", "C++20", "SQL"]} |
98 |
| - /> |
99 |
| - <TechIconsDisplay |
100 |
| - heading="Frameworks:" |
101 |
| - techNames={[ |
102 |
| - "Django", |
103 |
| - "Flask", |
104 |
| - "React", |
105 |
| - "Next.js", |
106 |
| - "Node.js", |
107 |
| - "Axios", |
108 |
| - "Socket.IO", |
109 |
| - "TailwindCSS", |
110 |
| - "D3.js", |
111 |
| - "Jest", |
112 |
| - "Cypress", |
113 |
| - "Pytest" |
114 |
| - ]} |
115 |
| - /> |
116 |
| - <TechIconsDisplay |
117 |
| - heading="Libraries:" |
118 |
| - techNames={[ |
119 |
| - "Pandas", |
120 |
| - "Matplotlib", |
121 |
| - "Plotly", |
122 |
| - "NumPy", |
123 |
| - "OpenCV", |
124 |
| - "Pillow", |
125 |
| - "NetworkX", |
126 |
| - ]} |
127 |
| - /> |
128 |
| - <TechIconsDisplay |
129 |
| - heading="Tools:" |
130 |
| - techNames={[ |
131 |
| - "Git", |
132 |
| - "Linux", |
133 |
| - "Bash", |
134 |
| - "Powershell", |
135 |
| - "Docker", |
136 |
| - "Postman", |
137 |
| - "GCP", |
138 |
| - "AWS", |
139 |
| - ]} |
140 |
| - /> |
141 |
| - </div> |
| 13 | + {skills && skills.length > 0 ? ( |
| 14 | + <div className="space-x-2"> |
| 15 | + {skills.map((skillText, index) => ( |
| 16 | + <Badge key={index}>{skillText}</Badge> |
| 17 | + ))} |
| 18 | + </div> |
| 19 | + ) : ( |
| 20 | + <p>No skills to display.</p> |
| 21 | + )} |
142 | 22 | </section>
|
143 | 23 | )
|
144 | 24 | }
|
0 commit comments