-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.js
462 lines (416 loc) · 18.6 KB
/
app.js
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
// defining a dom shortcut function.
function dcl(t = 'div') {
if (!t) {
t = 'div';
}
return document.createElement(t);
}
// This block for Type writer effect on headline section
const heading = ' I am Abu Raihan , <br/> Full Stack Web Developer!';
const hArr = heading.split(' ');
let typeCount = 1;
function typeWriter() {
if (typeCount < hArr.length) {
document.querySelector(
'.type-animation',
).innerHTML += ` ${hArr[typeCount]}`;
typeCount += 1;
setTimeout(typeWriter, 200);
}
}
typeWriter();
// this peace of code is responsible for scroll spy
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('.nav_item_action');
window.onscroll = () => {
sections.forEach((section) => {
const top = window.scrollY;
const offset = section.offsetTop - 200;
const height = section.offsetHeight;
const id = section.getAttribute('id');
if (top >= offset && top < height + offset) {
navLinks.forEach((link) => {
link.classList.remove('active');
document
.querySelectorAll(`a[href*=${id}]`)
.forEach((item) => item.classList.add('active'));
});
}
});
};
navLinks.forEach((link) => {
link.addEventListener('click', (event) => {
event.preventDefault();
const targetId = link.getAttribute('href');
const targetSection = document.querySelector(targetId);
if (targetSection) {
targetSection.scrollIntoView({ behavior: 'smooth' });
}
});
});
// Navigation Menu
const mobileMenu = document.querySelector('.header_menu');
const navItems = document.querySelector('.mobile_nav_items');
const selectNavItems = document.querySelectorAll('#m_nav');
const crossIcon = document.querySelector('.toggle-cross');
let setMobileNav = false;
function toggleNav() {
if (setMobileNav) {
navItems.classList.remove('df');
setMobileNav = false;
} else {
navItems.classList.add('df');
setMobileNav = true;
}
}
mobileMenu.addEventListener('click', toggleNav);
crossIcon.addEventListener('click', toggleNav);
selectNavItems.forEach((item) => {
item.addEventListener('click', toggleNav);
});
// Project Section
// project data
const projectData = [
{
id: 'project10',
title: 'Resort Booking',
frame: ['Full-stack', 2023],
primaryText:
'Resort Booking: Your gateway to dream resorts. Discover, book, and manage your ideal getaway effortlessly with our user-friendly web app. Access comprehensive resort details, amenities, and real-time availability to plan memorable journeys hassle-free',
tags: ['HTML', 'CSS', 'Javascript', 'React', 'Redux', 'Ruby on Rails', 'PostgreSQL'],
imageUrl:
'https://user-images.githubusercontent.com/35267447/257567388-16d64fa7-4149-48a1-a480-05dfa0ae4efb.PNG',
projectDetails:
'Resort Booking is an innovative web application designed to empower travelers in finding and booking their dream resorts effortlessly. With an extensive collection of resorts and comprehensive details, users can explore diverse destinations, hand-picking their ideal getaway. The platform provides valuable insights into resort amenities, room types, and real-time availability, ensuring informed decision-making. Seamlessly managing bookings, users experience a hassle-free reservation process, making their vacation planning a breeze. With a user-friendly interface and an array of options, Resort Booking promises to redefine the way travelers embark on their next memorable journey.',
liveLink: 'https://resort-booking-front-end-c8l1.onrender.com/',
sourceLink: 'https://github.com/raihan2bd/resort-booking-front-end',
},
{
id: 'project9',
title: 'Hungry Hub',
frame: ['E-commerce', 'Frontend', 2023],
primaryText:
'Hungry Hub is a React-based platform for online food ordering and delivery. Browse restaurant menus, add items to your cart, and securely place orders for home delivery.',
tags: ['HTML', 'CSS', 'Javascript', 'React', 'Redux', 'Firebase'],
imageUrl:
'https://user-images.githubusercontent.com/35267447/223940500-3aea07b1-4bc6-4705-ae49-e64f96544b44.PNG',
projectDetails:
'Hungry Hub is an online platform built using React, Redux, and Firebase, which allows users to browse and cart food items from a variety of restaurants and place orders for home delivery. Users can sign up, browse the menus of different restaurants, add food items to their cart, and proceed to checkout. The platform integrates with Firebase to provide secure payment options and order tracking for users. With Hungry Hub, users can enjoy the convenience of online food ordering and get their favorite meals delivered straight to their doorstep.',
liveLink: 'https://hungry-hub.onrender.com/',
sourceLink: 'https://github.com/raihan2bd/hungry-hub',
},
{
id: 'project8',
title: 'Hotel Bookings',
frame: ['Full-Stack', 2023],
primaryText:
'Hotel Bookings project built using Go and postgresql is likely a web application that allows users to search for available hotels, view room details, and make reservations.',
tags: ['HTML', 'CSS', 'Javascript', 'Golang', 'PostgreSQL'],
imageUrl:
'https://user-images.githubusercontent.com/35267447/223337938-c8ab34f0-20c6-4d8e-b47a-10558d3c7beb.PNG',
projectDetails:
'Hotel Bookings project built using Go and postgresql is likely a web application that allows users to search for available hotels, view room details, and make reservations. It may include features such as user authentication, and integration with third-party APIs for displaying hotel information and availability.',
sourceLink: 'https://github.com/raihan2bd/hotel-bookings',
},
{
id: 'project7',
title: 'BookStore',
frame: ['Microverse', 'Frontend', 2023],
primaryText:
'Book Store is a Microverce React MVP project. Using this project user can read a book. User can see a book list. User can update a book. And also User can delete book from the book list.',
tags: ['HTML', 'CSS', 'Javascript', 'React', 'Redux'],
imageUrl:
'https://user-images.githubusercontent.com/35267447/214837157-45734f12-5466-4238-9e15-d4b68eb66c9b.png',
projectDetails:
'Book Store is a Microverse React MVP project that enables users to read books and manage their reading lists. With this project, users can view a list of available books, update book details, and remove books from their reading list as needed, providing a simple and convenient platform for managing their reading interests',
liveLink: 'https://book-store-1ok9.onrender.com/',
sourceLink: 'https://github.com/raihan2bd/book-store',
},
{
id: 'project6',
title: 'Weather APP',
frame: ['Microverse', 'Frontend', 2023],
primaryText:
'Weather-Forecast is a Microverce React capstone project. Using this project users can see a list of countries in a particular region with country details and also see the weather of that country.',
tags: ['HTML', 'CSS', 'Javascript', 'React', 'Redux'],
imageUrl:
'https://user-images.githubusercontent.com/35267447/217789912-ead664b3-086f-4de2-8df8-e0229f60ae8a.PNG',
projectDetails:
'Weather-Forecast is a Microverse React capstone project that allows users to view a list of countries in a selected region along with country details. Additionally, users can also view the weather information for a selected country, providing a comprehensive picture of weather patterns and travel information for their destination of interest.',
liveLink: 'https://weather-forecast-0xbe.onrender.com/',
sourceLink: 'https://github.com/raihan2bd/weather-forecast',
},
{
id: 'project5',
title: 'RSL Media',
frame: ['Microverse', 'Frontend', 2023],
primaryText:
'RSL Media is a Microverse group project that offers an online entertainment streaming source for TV shows and movies. It leverages an external tvmaze API service to preserve data.',
tags: ['HTML', 'CSS', 'Javascript'],
imageUrl:
'https://raw.githubusercontent.com/raihan2bd/js-capstone/main/src/assets/img/home.png',
projectDetails:
'The RSL Media project is a Microverse group project that offers users an online entertainment streaming source for TV shows and movies. The project leverages an external tvmaze API service to preserve data related to various TV shows and movies. The platform allows users to add likes to their favorite shows and add comments to share their thoughts with other users. Additionally, users can reserve a show they want to watch later. Overall, the project provides a streamlined and convenient way for users to discover and enjoy their favorite TV shows and movies while engaging with a community of fellow enthusiasts.',
liveLink: 'https://raihan2bd.github.io/js-capstone/',
sourceLink: 'https://github.com/raihan2bd/js-capstone',
},
{
id: 'project1',
title: 'Todolist',
frame: ['Microverse', 'Frontend', 2022],
primaryText:
'To-do list is a tool that helps to organize your day. It simply lists the things that you need to do and allows you to mark them as complete.',
tags: ['HTML', 'CSS', 'Javascript'],
imageUrl: './images/todo-list-js.png',
projectDetails:
'This is A simple but effective and responsive (mobile first) Microverse exercise project. To-do list is a tool that helps to organize your day. It simply lists the things that you need to do and allows you to mark them as complete.',
liveLink: 'https://raihan2bd.github.io/Todo-List/',
sourceLink: 'https://github.com/raihan2bd/Todo-List',
},
{
id: 'project2',
title: 'Awesome Book',
frame: ['Microverse', 'Front-End', 2022],
primaryText:
'Awesome books is a simple website that displays a list of books and allows you to add and remove books from that list.',
tags: ['HTML', 'CSS', 'Javascript'],
imageUrl: './images/awesome-book-js1.png',
projectDetails:
'This is A simple but effective and responsive (mobile first) Microverse exercize project. Awesome books is a simple website that displays a list of books and allows you to add and remove books from that list.',
liveLink: 'https://raihan2bd.github.io/Awesome-Books/',
sourceLink: 'https://github.com/raihan2bd/Awesome-Books',
},
{
id: 'project3',
title: 'Full-Stack Bootcamp',
frame: ['Microverse', 'Front-End', 2022],
primaryText:
'This is A simple but effective and responsive (mobile first) Microverse Capstone Project 1. The theme about this project is a online full stack webdevelopment bootcamp.',
tags: ['HTML', 'CSS', 'Javascript'],
imageUrl: './images/code-with-raihan-js.png',
projectDetails:
'This is A simple but effective and responsive (mobile first) Microverse Capstone Project 1. The theme about this project is a online full stack webdevelopment bootcamp. Boost your career joining our highly professional fullstack Bootcamp and start a remote international fulltime job. Through out this Bootcamp your learning path will be practical and beginner friendly.',
liveLink: 'https://raihan2bd.github.io/code-with-raihan/',
sourceLink: 'https://github.com/raihan2bd/code-with-raihan/',
},
]; // End of portfolio data
// Fetch single project from projectData
function fetchOnePoject(id) {
const projects = projectData;
let project;
for (let i = 0; i < projectData.length; i += 1) {
if (projects[i].id === id) {
project = projects[i];
}
}
if (project) {
const article = dcl('article');
article.classList.add('popup_article');
article.setAttribute('id', project.id);
const articleModal = dcl();
articleModal.classList.add('article-modal');
// Article title
const workTitle = dcl('h2');
workTitle.classList.add('work_title');
workTitle.innerText = project.title;
// cross-icon
const crossIcon = dcl('span');
crossIcon.setAttribute('id', 'article-close');
crossIcon.innerHTML = '<img src="./images/cross-icon.png" alt="X"/>';
// work_info
const workInfo = dcl('ul');
workInfo.classList.add('work_info');
// work_info_item
project.frame.forEach((f) => {
const workInfoItem = dcl('li');
workInfoItem.classList.add('w_info_item');
workInfoItem.innerText = f;
workInfo.appendChild(workInfoItem);
});
// image
const articleImage = dcl();
articleImage.classList.add('article-image');
articleImage.innerHTML = `<img class='article-img' src='${project.imageUrl}' alt='${project.title}'/>`;
// project block
const projectBlock = dcl();
projectBlock.classList.add('article-block');
// left block
const leftBlock = dcl();
leftBlock.classList.add('left-block');
// article_details_content
const workDetailsContent = dcl('p');
workDetailsContent.classList.add('work_details_content');
workDetailsContent.innerText = project.projectDetails;
leftBlock.append(workDetailsContent);
// right block
const rightBlock = dcl();
rightBlock.classList.add('right-block');
// work_cat
const workCat = dcl('ul');
workCat.classList.add('work_cats');
project.tags.forEach((tag) => {
const catLi = dcl('li');
catLi.innerText = tag;
workCat.appendChild(catLi);
});
// actions
const actions = dcl();
actions.classList.add('actions');
// live link
if (project.liveLink) {
const liveLink = dcl('a');
liveLink.classList.add('article-btn');
liveLink.setAttribute('href', project.liveLink);
liveLink.setAttribute('target', '_blank');
liveLink.innerHTML = 'See Live <span class="btn-icon"><img src="./images/btn-live.png" alt= "Live"/></span>';
actions.appendChild(liveLink);
}
// source link
const sourceLink = dcl('a');
sourceLink.classList.add('article-btn');
sourceLink.setAttribute('href', project.sourceLink);
sourceLink.setAttribute('target', '_blank');
sourceLink.innerHTML = 'See Source <span class="btn-icon"><img src="./images/btn-github.png" alt= "Live"/></span>';
// appending link
actions.appendChild(sourceLink);
// appending rightBlock
rightBlock.append(workCat, actions);
// appending projectBlock
projectBlock.append(leftBlock, rightBlock);
// appending article-modal
articleModal.append(
crossIcon,
workTitle,
workInfo,
articleImage,
projectBlock,
);
// appending article-modal to article
article.append(articleModal);
// end of if condition
document.querySelector('main').append(article);
// add event
const closeModal = document.getElementById('article-close');
closeModal.addEventListener('click', () => {
document.querySelector('main').removeChild(article);
});
}
}
// this fetchAllProject function will add data in portfolio section dinamically
function fetchAllProject() {
// select the portfolio
const portfolio = document.getElementById('projects');
projectData.forEach((project) => {
// Dom element for card
const card = dcl();
card.classList.add('work_card');
const workPreview = dcl();
workPreview.classList.add('work_preview');
workPreview.innerHTML = `<img class='project-img' src='${project.imageUrl}' alt='${project.title}'/>`;
card.appendChild(workPreview);
// work_details
const workDetails = dcl();
workDetails.classList.add('work_details');
// work title
const workTitle = dcl('h2');
workTitle.classList.add('work_title');
workTitle.innerText = project.title;
workDetails.appendChild(workTitle);
// work_info
const workInfo = dcl('ul');
workInfo.classList.add('work_info');
// work_info_item
project.frame.forEach((f) => {
const workInfoItem = dcl('li');
workInfoItem.classList.add('w_info_item');
workInfoItem.innerText = f;
workInfo.appendChild(workInfoItem);
});
workDetails.appendChild(workInfo);
// work_details_content
const workDetailsContent = dcl('p');
workDetailsContent.classList.add('work_details_content');
workDetailsContent.innerText = project.primaryText;
workDetails.appendChild(workDetailsContent);
// work_cat
const workCat = dcl('ul');
workCat.classList.add('work_cats');
project.tags.forEach((tag) => {
const catLi = dcl('li');
catLi.innerText = tag;
workCat.appendChild(catLi);
});
workDetails.appendChild(workCat);
// action button
const atnBrn = dcl('button');
atnBrn.classList.add('atn_btn');
atnBrn.innerText = 'See More';
atnBrn.setAttribute('id', project.id);
atnBrn.addEventListener('click', () => {
fetchOnePoject(project.id);
});
workDetails.appendChild(atnBrn);
card.appendChild(workDetails);
portfolio.appendChild(card);
});
}
// selecting input elements
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const messageInput = document.getElementById('message');
// Store formData in localStorage
function loadLocalStorage() {
const formData = JSON.parse(window.localStorage.getItem('formData'));
if (formData) {
nameInput.value = formData.name;
emailInput.value = formData.email;
messageInput.value = formData.message;
}
}
// OnChange function will store form data in localStorage
function onChange(e) {
let formData = JSON.parse(localStorage.getItem('formData'));
if (!formData) {
formData = {};
}
// saving form data on localStorage
const m = e.target.name;
formData[m] = e.target.value;
formData = JSON.stringify(formData);
window.localStorage.setItem('formData', formData);
}
// Fire event on form input
nameInput.addEventListener('change', onChange);
emailInput.addEventListener('change', onChange);
messageInput.addEventListener('change', onChange);
// Load Data in dom on the fly
window.onload = () => {
fetchAllProject();
loadLocalStorage();
};
// Form Validation
function onSubmit(e) {
const inputEmail = document.getElementById('email');
const formInfo = document.getElementById('form-info');
const email = inputEmail.value;
// Check if email value is lowercase or not
if (email !== email.toLowerCase()) {
e.preventDefault();
inputEmail.classList.add('invalid');
formInfo.classList.add('error');
formInfo.innerText = 'Error form is not sent! The Email should be in lower case!!';
} else {
inputEmail.classList.remove('invalid');
formInfo.classList.remove('error');
}
}
const contactForm = document.getElementById('contact-form');
contactForm.addEventListener('submit', onSubmit);
// Remove Error onchange from the form.
const inputEmail = document.getElementById('email');
const formInfo = document.getElementById('form-info');
inputEmail.addEventListener('change', () => {
inputEmail.classList.remove('invalid');
formInfo.classList.remove('error');
formInfo.innerText = '';
});