-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
286 lines (244 loc) · 10 KB
/
script.js
File metadata and controls
286 lines (244 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
// 1. IMPORT your data
import { contentData } from './skill/categories.js';
// 2. DECLARE variables in the top-level scope
let contentContainer;
let searchInput;
let clearSearchBtn;
let noResultsMessage;
let backButton;
let currentCategoryTitle;
let dynamicNavBar;
let heroSection;
let categorySectionTitle; // NEW: Section title for categories
let currentView = 'categories';
let currentCategoryId = null;
// 3. DEFINE all your functions
// Function to display sub-topics within a category
function displaySubTopics(categoryId, filteredSubTopics = null) {
const category = contentData.categories.find(cat => cat.id === categoryId);
if (!category || !category.subTopics){
window.location.hash = '';
return;
}
contentContainer.innerHTML = '';
// UX Logic
heroSection.classList.add('hidden');
dynamicNavBar.classList.remove('hidden');
categorySectionTitle.classList.add('hidden'); // Hide category title
noResultsMessage.classList.add('hidden');
currentCategoryTitle.textContent = category.name;
currentView = 'subTopics';
currentCategoryId = categoryId;
const topicsToDisplay = filteredSubTopics || category.subTopics;
// ... rest of the function remains the same ...
if (topicsToDisplay.length === 0) {
noResultsMessage.classList.remove('hidden');
return;
}
topicsToDisplay.forEach(subTopic => {
const subTopicCard = createCard(subTopic, 'subTopic');
contentContainer.appendChild(subTopicCard);
});
}
// Function to display projects (remains similar, updating visibility)
function showProjects(filteredProjects = null) {
const projectsCategory = contentData.categories.find(cat => cat.id === 'projects');
if (!projectsCategory || !projectsCategory.projects) {
window.location.hash = '';
return;
}
contentContainer.innerHTML = '';
// UX Logic
heroSection.classList.add('hidden');
dynamicNavBar.classList.remove('hidden');
categorySectionTitle.classList.add('hidden'); // Hide category title
noResultsMessage.classList.add('hidden');
currentCategoryTitle.textContent = projectsCategory.name;
currentView = 'projects';
currentCategoryId = 'projects';
const projectsToDisplay = filteredProjects || projectsCategory.projects;
if (projectsToDisplay.length === 0) {
noResultsMessage.classList.remove('hidden');
return;
}
projectsToDisplay.forEach(project => {
const projectCard = createCard(project, 'project');
contentContainer.appendChild(projectCard);
});
}
// Function to create cards (remains the same as the previous version)
function createCard(item, type) {
// ... (omitted for brevity, as it's the same as the previous full version)
const card = document.createElement('div');
card.className = "bg-white p-6 rounded-xl shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1 border-l-4 border-gray-200 hover:border-blue-500";
if (type === 'category') {
card.classList.add("cursor-pointer");
card.innerHTML = `
<h3 class="text-2xl font-bold text-blue-700 mb-3">${item.name}</h3>
<p class="text-gray-700 leading-relaxed">${item.description}</p>
`;
card.onclick = () => {
window.location.hash = item.id;
};
} else if (type === 'subTopic') {
// ... (subTopic card content logic)
let imageHtml = '';
if (item.imageLink) {
imageHtml = `<div class="mb-4">
<img src="${item.imageLink}" alt="${item.title}" class="rounded-lg w-full h-40 object-cover shadow-md bg-gray-100">
</div>`;
}
let buttonsHtml = '';
const links = [
{ link: item.videoLink, text: 'Watch Video', color: 'bg-blue-600 hover:bg-blue-700' },
{ link: item.pdfLink, text: 'See PDF', color: 'bg-purple-600 hover:bg-purple-700' },
{ link: item.websiteLink, text: 'Visit Website', color: 'bg-green-600 hover:bg-green-700' },
{ link: item.githubLink, text: 'View GitHub', color: 'bg-gray-700 hover:bg-gray-800' },
];
links.forEach(btn => {
if (btn.link) {
buttonsHtml += `
<a href="${btn.link}" target="_blank" class="flex-1 text-center ${btn.color} text-white font-medium py-2 px-4 rounded-full shadow-md transition-colors duration-200 text-sm">
${btn.text}
</a>
`;
}
});
card.innerHTML = `
${imageHtml}
<div>
<h3 class="text-xl font-semibold text-gray-900 mb-2">${item.title}</h3>
<p class="text-gray-600 mb-4">${item.description}</p>
</div>
<div class="mt-4 flex flex-wrap gap-2">
${buttonsHtml}
</div>
`;
} else if (type === 'project') {
// ... (project card content logic)
card.classList.remove("cursor-pointer");
card.innerHTML = `
<h3 class="text-xl font-semibold text-gray-900 mb-2">${item.name}</h3>
<p class="text-gray-600 mb-4">${item.description}</p>
<a href="${item.githubLink}" target="_blank" class="inline-block bg-gray-700 text-white font-medium py-2 px-4 rounded-full shadow-md hover:bg-gray-800 transition-colors duration-200">
View GitHub
</a>
`;
}
return card;
}
// Function to display categories (initial view)
function displayCategories(filteredCategories = contentData.categories) {
contentContainer.innerHTML = '';
// UX Logic: Show Hero on homepage, Show category title
dynamicNavBar.classList.add('hidden');
heroSection.classList.remove('hidden');
categorySectionTitle.classList.remove('hidden'); // Show category title
noResultsMessage.classList.add('hidden');
currentView = 'categories';
currentCategoryId = null;
if (!Array.isArray(filteredCategories) || filteredCategories.length === 0) {
if(searchInput.value.length > 0) {
noResultsMessage.classList.remove('hidden');
}
return;
}
filteredCategories.forEach(category => {
const categoryCard = createCard(category, 'category');
contentContainer.appendChild(categoryCard);
});
}
// Function to handle search logic (unchanged)
function handleSearch() {
const searchTerm = searchInput.value.toLowerCase();
clearSearchBtn.style.display = searchTerm.length > 0 ? 'block' : 'none';
if (currentView === 'categories') {
const filteredCategories = contentData.categories.filter(cat =>
cat.name.toLowerCase().includes(searchTerm) ||
cat.description.toLowerCase().includes(searchTerm)
);
displayCategories(filteredCategories);
} else if (currentView === 'subTopics' && currentCategoryId) {
const category = contentData.categories.find(cat => cat.id === currentCategoryId);
if (category && category.subTopics) {
const filteredSubTopics = category.subTopics.filter(sub =>
sub.title.toLowerCase().includes(searchTerm) ||
sub.description.toLowerCase().includes(searchTerm)
);
displaySubTopics(currentCategoryId, filteredSubTopics);
}
} else if (currentView === 'projects') {
const projectsCategory = contentData.categories.find(cat => cat.id === 'projects');
if (projectsCategory && projectsCategory.projects) {
const filteredProjects = projectsCategory.projects.filter(proj =>
proj.name.toLowerCase().includes(searchTerm) ||
proj.description.toLowerCase().includes(searchTerm)
);
showProjects(filteredProjects);
}
}
}
// --- Routing Function (unchanged) ---
function route() {
const hash = window.location.hash.substring(1);
const parts = hash.split('/');
if (parts.length > 0 && parts[0]) {
const categoryId = parts[0];
const category = contentData.categories.find(cat => cat.id === categoryId);
if (category) {
if (categoryId === 'projects') {
showProjects();
} else if (category.subTopics) {
displaySubTopics(categoryId);
} else {
window.location.hash = '';
displayCategories();
}
} else {
window.location.hash = '';
displayCategories();
}
} else {
displayCategories();
}
}
// 4. SET UP event listeners
document.addEventListener('DOMContentLoaded', () => {
// Assigning ALL variables
contentContainer = document.getElementById('content-container');
searchInput = document.getElementById('searchInput');
clearSearchBtn = document.getElementById('clearSearchBtn');
noResultsMessage = document.getElementById('noResultsMessage');
dynamicNavBar = document.getElementById('dynamic-nav-bar');
backButton = document.getElementById('backButton');
currentCategoryTitle = document.getElementById('currentCategoryTitle');
heroSection = document.getElementById('hero-section');
categorySectionTitle = document.getElementById('category-section-title'); // NEW Assignment
// Event listeners
if (searchInput) {
searchInput.addEventListener('keyup', handleSearch);
}
if (clearSearchBtn) {
clearSearchBtn.addEventListener('click', () => {
if (searchInput) {
searchInput.value = '';
}
handleSearch();
});
}
if (backButton) {
backButton.addEventListener('click', () => {
if (searchInput) {
searchInput.value = '';
}
handleSearch();
// Explicitly route to home to clear hash
window.location.hash = '';
route();
});
}
// Initial page load
route();
});
// Listen for hash changes (browser back/forward)
window.addEventListener('hashchange', route);