@@ -4,55 +4,55 @@ import { techStackData, certificatesData } from './data.js';
4
4
5
5
// Function to initialize everything
6
6
function initializeContent ( ) {
7
- renderTechStack ( ) ;
8
- renderCertificates ( ) ;
9
- setupLazyLoading ( ) ;
7
+ renderTechStack ( ) ;
8
+ renderCertificates ( ) ;
9
+ setupLazyLoading ( ) ;
10
10
}
11
11
12
12
// Tech Stack Generator Functions
13
13
function renderTechStack ( ) {
14
- // For mobile view
15
- const mobileContainer = document . querySelector ( '.block.md\\:hidden.space-y-6' ) ;
16
- if ( mobileContainer ) {
17
- techStackData . categories . forEach ( category => {
18
- // Create category heading
19
- const categoryHeading = document . createElement ( 'div' ) ;
20
- categoryHeading . className = 'mb-8' ;
21
- categoryHeading . innerHTML = `
14
+ // For mobile view
15
+ const mobileContainer = document . querySelector ( '.block.md\\:hidden.space-y-6' ) ;
16
+ if ( mobileContainer ) {
17
+ techStackData . categories . forEach ( category => {
18
+ // Create category heading
19
+ const categoryHeading = document . createElement ( 'div' ) ;
20
+ categoryHeading . className = 'mb-8' ;
21
+ categoryHeading . innerHTML = `
22
22
<h3 class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 px-4 py-3 mb-3 rounded-t-lg">
23
23
${ category . name }
24
24
</h3>
25
25
` ;
26
26
27
- // Create skill cards for this category
28
- category . skills . forEach ( skill => {
29
- const skillCard = createMobileSkillCard ( skill ) ;
30
- categoryHeading . appendChild ( skillCard ) ;
31
- } ) ;
32
-
33
- mobileContainer . appendChild ( categoryHeading ) ;
34
- } ) ;
35
- }
36
-
37
- // For desktop view (table)
38
- const tableBody = document . getElementById ( 'tech-desktop-table' ) ;
39
- if ( tableBody ) {
40
- techStackData . categories . forEach ( category => {
41
- let tableHead = createDesktopSkillHead ( category )
42
- tableBody . insertAdjacentHTML ( 'beforeend' , tableHead )
43
- category . skills . forEach ( skill => {
44
- const skillRow = createDesktopSkillRow ( skill ) ;
45
- tableBody . appendChild ( skillRow ) ;
46
- } ) ;
47
- } ) ;
48
- }
27
+ // Create skill cards for this category
28
+ category . skills . forEach ( skill => {
29
+ const skillCard = createMobileSkillCard ( skill ) ;
30
+ categoryHeading . appendChild ( skillCard ) ;
31
+ } ) ;
32
+
33
+ mobileContainer . appendChild ( categoryHeading ) ;
34
+ } ) ;
35
+ }
36
+
37
+ // For desktop view (table)
38
+ const tableBody = document . getElementById ( 'tech-desktop-table' ) ;
39
+ if ( tableBody ) {
40
+ techStackData . categories . forEach ( category => {
41
+ let tableHead = createDesktopSkillHead ( category )
42
+ tableBody . insertAdjacentHTML ( 'beforeend' , tableHead )
43
+ category . skills . forEach ( skill => {
44
+ const skillRow = createDesktopSkillRow ( skill ) ;
45
+ tableBody . appendChild ( skillRow ) ;
46
+ } ) ;
47
+ } ) ;
48
+ }
49
49
}
50
50
51
51
function createMobileSkillCard ( skill ) {
52
- const card = document . createElement ( 'div' ) ;
53
- card . className = 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg mb-4 overflow-hidden shadow-sm' ;
52
+ const card = document . createElement ( 'div' ) ;
53
+ card . className = 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg mb-4 overflow-hidden shadow-sm' ;
54
54
55
- card . innerHTML = `
55
+ card . innerHTML = `
56
56
<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700">
57
57
<div class="flex items-center gap-3">
58
58
<img src="${ skill . icon } " alt="${ skill . name } " title="${ skill . name } " class="w-6 h-6" />
@@ -86,11 +86,11 @@ function createMobileSkillCard(skill) {
86
86
</div>
87
87
` ;
88
88
89
- return card ;
89
+ return card ;
90
90
}
91
91
92
92
function createDesktopSkillHead ( category ) {
93
- let html = `<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 rounded-md">
93
+ let html = `<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400 rounded-md">
94
94
<tr>
95
95
<th scope="col" class="px-6 py-3">${ category . name } </th>
96
96
<th scope="col" class="px-6 py-3">Proficiency</th>
@@ -99,14 +99,14 @@ function createDesktopSkillHead(category) {
99
99
</tr>
100
100
</thead>`
101
101
102
- return html ;
102
+ return html ;
103
103
}
104
104
105
105
function createDesktopSkillRow ( skill ) {
106
- const row = document . createElement ( 'tr' ) ;
107
- row . className = 'bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200' ;
106
+ const row = document . createElement ( 'tr' ) ;
107
+ row . className = 'bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200' ;
108
108
109
- row . innerHTML = `
109
+ row . innerHTML = `
110
110
<th scope="row" class="flex flex-row items-center gap-3 px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
111
111
<img src="${ skill . icon } " alt="${ skill . name } " title="${ skill . name } " class="w-6 h-6" />
112
112
${ skill . fullName }
@@ -136,29 +136,29 @@ function createDesktopSkillRow(skill) {
136
136
</td>
137
137
` ;
138
138
139
- return row ;
139
+ return row ;
140
140
}
141
141
142
142
// Certificate Generator Functions
143
143
function renderCertificates ( ) {
144
- const certificatesContainer = document . querySelector ( '.certificates-cards' ) ;
145
- if ( certificatesContainer ) {
146
- // Clear existing certificates if any
147
- certificatesContainer . innerHTML = '' ;
148
-
149
- // Generate certificate cards
150
- certificatesData . forEach ( cert => {
151
- const certCard = createCertificateCard ( cert ) ;
152
- certificatesContainer . appendChild ( certCard ) ;
153
- } ) ;
154
- }
144
+ const certificatesContainer = document . querySelector ( '.certificates-cards' ) ;
145
+ if ( certificatesContainer ) {
146
+ // Clear existing certificates if any
147
+ certificatesContainer . innerHTML = '' ;
148
+
149
+ // Generate certificate cards
150
+ certificatesData . forEach ( cert => {
151
+ const certCard = createCertificateCard ( cert ) ;
152
+ certificatesContainer . appendChild ( certCard ) ;
153
+ } ) ;
154
+ }
155
155
}
156
156
157
157
function createCertificateCard ( cert ) {
158
- const card = document . createElement ( 'div' ) ;
159
- card . className = 'certificates-card flex flex-col justify-between items-center gap-3 bg-primary p-5 border-2 border-priGray rounded-3xl shadow-btn max-w-80' ;
158
+ const card = document . createElement ( 'div' ) ;
159
+ card . className = 'certificates-card flex flex-col justify-between items-center gap-3 bg-primary p-5 border-2 border-priGray rounded-3xl shadow-btn max-w-80' ;
160
160
161
- card . innerHTML = `
161
+ card . innerHTML = `
162
162
<div class="cer-picture w-full h-full">
163
163
<div class="spinner flex justify-center items-center w-full h-full place-items-center">
164
164
<div role="status">
@@ -192,48 +192,48 @@ function createCertificateCard(cert) {
192
192
</div>
193
193
` ;
194
194
195
- return card ;
195
+ return card ;
196
196
}
197
197
198
198
// Setup lazy loading for certificate images
199
199
function setupLazyLoading ( ) {
200
- // Check if IntersectionObserver is supported
201
- if ( 'IntersectionObserver' in window ) {
202
- const lazyImages = document . querySelectorAll ( 'img.lazy' ) ;
203
-
204
- const imageObserver = new IntersectionObserver ( ( entries , observer ) => {
205
- entries . forEach ( entry => {
206
- if ( entry . isIntersecting ) {
207
- const img = entry . target ;
208
- img . src = img . dataset . src ;
209
-
210
- // Show image after it's loaded
211
- img . onload = ( ) => {
212
- img . classList . remove ( 'opacity-0' ) ;
213
- img . classList . add ( 'opacity-100' ) ;
214
-
215
- // Hide spinner when image loads
216
- const spinner = img . parentElement . querySelector ( '.spinner' ) ;
217
- if ( spinner ) {
218
- spinner . style . display = 'none' ;
219
- }
220
- } ;
221
-
222
- imageObserver . unobserve ( img ) ;
223
- }
224
- } ) ;
225
- } ) ;
226
-
227
- lazyImages . forEach ( img => imageObserver . observe ( img ) ) ;
228
- } else {
229
- // Fallback for browsers that don't support IntersectionObserver
230
- const lazyImages = document . querySelectorAll ( 'img.lazy' ) ;
231
- lazyImages . forEach ( img => {
232
- img . src = img . dataset . src ;
200
+ // Check if IntersectionObserver is supported
201
+ if ( 'IntersectionObserver' in window ) {
202
+ const lazyImages = document . querySelectorAll ( 'img.lazy' ) ;
203
+
204
+ const imageObserver = new IntersectionObserver ( ( entries , observer ) => {
205
+ entries . forEach ( entry => {
206
+ if ( entry . isIntersecting ) {
207
+ const img = entry . target ;
208
+ img . src = img . dataset . src ;
209
+
210
+ // Show image after it's loaded
211
+ img . onload = ( ) => {
233
212
img . classList . remove ( 'opacity-0' ) ;
234
213
img . classList . add ( 'opacity-100' ) ;
235
- } ) ;
236
- }
214
+
215
+ // Hide spinner when image loads
216
+ const spinner = img . parentElement . querySelector ( '.spinner' ) ;
217
+ if ( spinner ) {
218
+ spinner . style . display = 'none' ;
219
+ }
220
+ } ;
221
+
222
+ imageObserver . unobserve ( img ) ;
223
+ }
224
+ } ) ;
225
+ } ) ;
226
+
227
+ lazyImages . forEach ( img => imageObserver . observe ( img ) ) ;
228
+ } else {
229
+ // Fallback for browsers that don't support IntersectionObserver
230
+ const lazyImages = document . querySelectorAll ( 'img.lazy' ) ;
231
+ lazyImages . forEach ( img => {
232
+ img . src = img . dataset . src ;
233
+ img . classList . remove ( 'opacity-0' ) ;
234
+ img . classList . add ( 'opacity-100' ) ;
235
+ } ) ;
236
+ }
237
237
}
238
238
239
239
// Run initialization when DOM is fully loaded
0 commit comments