Skip to content

Commit 404bda7

Browse files
authored
Merge pull request #308 from Ctoic/dynamic-components
feat: Add dynamic navbar and footer components
2 parents cdeee70 + 0dc2b2e commit 404bda7

12 files changed

Lines changed: 860 additions & 725 deletions

DYNAMIC_COMPONENTS_GUIDE.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Dynamic Navbar and Footer Implementation Guide
2+
3+
This guide explains how to implement the dynamic navbar and footer system across all pages in your Lisbook project.
4+
5+
## Files Created/Modified
6+
7+
### New Files:
8+
- `includes/navbar.html` - Contains the navbar HTML structure
9+
- `includes/footer.html` - Contains the footer HTML structure
10+
- `dynamic-components.js` - JavaScript file that loads navbar and footer dynamically
11+
- `page-template.html` - Template for new pages
12+
- `DYNAMIC_COMPONENTS_GUIDE.md` - This guide
13+
14+
### Modified Files:
15+
- `index.html` - Updated to use dynamic loading
16+
17+
## How It Works
18+
19+
The system uses JavaScript to dynamically load the navbar and footer into placeholder divs on each page. This ensures consistency across all pages and makes maintenance easier.
20+
21+
## Implementation Steps
22+
23+
### For Existing Pages:
24+
25+
1. **Replace the existing navbar** with a placeholder div:
26+
```html
27+
<!-- Replace your existing <header> or <nav> with: -->
28+
<div id="navbar-placeholder"></div>
29+
```
30+
31+
2. **Replace the existing footer** with a placeholder div:
32+
```html
33+
<!-- Replace your existing <footer> with: -->
34+
<div id="footer-placeholder" class="mt-auto"></div>
35+
```
36+
37+
3. **Add the dynamic components script** before the closing `</body>` tag:
38+
```html
39+
<script src="dynamic-components.js"></script>
40+
```
41+
42+
4. **Remove any existing navbar/footer JavaScript** that's no longer needed.
43+
44+
### For New Pages:
45+
46+
Use the `page-template.html` as a starting point. It already includes:
47+
- Dynamic navbar placeholder
48+
- Dynamic footer placeholder
49+
- All necessary CSS and JavaScript includes
50+
- Theme initialization
51+
- Dynamic components script
52+
53+
## Features Included
54+
55+
The dynamic system includes:
56+
57+
### Navbar Features:
58+
- Responsive design with mobile menu
59+
- Theme toggle (dark/light mode)
60+
- Language selector
61+
- Navigation links (Home, Explore, Scan Book, About, Contact, FAQs)
62+
- Profile link
63+
- Signup button
64+
- Mobile menu toggle
65+
66+
### Footer Features:
67+
- Company information and logo
68+
- Important links section
69+
- Features section
70+
- Social media links
71+
- Newsletter subscription form
72+
- Copyright information
73+
74+
### JavaScript Functionality:
75+
- Theme persistence using localStorage
76+
- Mobile menu toggle
77+
- Newsletter form validation
78+
- Signup button redirect
79+
- Language change communication with iframes
80+
81+
## Benefits
82+
83+
1. **Consistency**: Same navbar and footer across all pages
84+
2. **Maintainability**: Update navbar/footer in one place
85+
3. **Performance**: No duplicate code across pages
86+
4. **Flexibility**: Easy to add new features to all pages at once
87+
88+
## Testing
89+
90+
To test the implementation:
91+
92+
1. Open `index.html` in a browser
93+
2. Verify the navbar loads correctly
94+
3. Test the mobile menu toggle
95+
4. Test the theme toggle
96+
5. Verify the footer loads with newsletter form
97+
6. Check that all links work properly
98+
99+
## Troubleshooting
100+
101+
### Common Issues:
102+
103+
1. **Navbar/Footer not loading**: Check that `dynamic-components.js` is included
104+
2. **JavaScript errors**: Ensure all required CSS frameworks are loaded first
105+
3. **Styling issues**: Verify that `style.css` and Bootstrap are included
106+
4. **Mobile menu not working**: Check that the script is loaded after the DOM
107+
108+
### Console Messages:
109+
- `✓ Navbar loaded successfully` - Navbar loaded correctly
110+
- `✓ Footer loaded successfully` - Footer loaded correctly
111+
- Any error messages will help identify issues
112+
113+
## Customization
114+
115+
To customize the navbar or footer:
116+
117+
1. Edit the HTML in `dynamic-components.js` (in the `loadNavbar()` or `loadFooter()` functions)
118+
2. Or modify the separate HTML files in the `includes/` directory
119+
3. Test changes on all pages
120+
121+
## Browser Compatibility
122+
123+
This system works with:
124+
- Modern browsers (Chrome, Firefox, Safari, Edge)
125+
- Mobile browsers
126+
- File:// protocol (for local development)
127+
- HTTP/HTTPS protocols (for web servers)

about.html

Lines changed: 46 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
1010
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet" />
1111
<script src="https://unpkg.com/lucide@latest"></script>
12+
<!-- Include the same CSS and JS as index.html -->
13+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
14+
<link rel="stylesheet" href="style.css" />
15+
<link rel="icon" href="Images/favicon.jpg" type="image/png" />
16+
<script src="https://cdn.tailwindcss.com"></script>
17+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" />
18+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
19+
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous" />
1220
<style>
1321
* {
1422
box-sizing: border-box;
@@ -618,7 +626,28 @@
618626

619627
</style>
620628
</head>
621-
<body>
629+
<body class="bg-gray-900 text-gray-300 d-flex flex-column min-vh-100">
630+
<script>
631+
// Initialize theme with fallback (no localStorage dependency)
632+
(function() {
633+
try {
634+
const saved = localStorage.getItem('theme');
635+
const theme = saved === 'light' ? 'light' : 'dark';
636+
document.documentElement.setAttribute('data-theme', theme);
637+
if (document.body) {
638+
document.body.classList.remove('light-theme', 'dark-theme');
639+
document.body.classList.add(theme + '-theme');
640+
}
641+
} catch (e) {
642+
// Fallback to dark theme if localStorage fails
643+
document.documentElement.setAttribute('data-theme', 'dark');
644+
if (document.body) {
645+
document.body.classList.add('dark-theme');
646+
}
647+
console.warn('Theme init error, using default dark theme', e);
648+
}
649+
})();
650+
</script>
622651

623652

624653
<script>
@@ -650,33 +679,8 @@
650679
}
651680
</script>
652681

653-
<nav class="navbar">
654-
<div class="container">
655-
<a class="logo" href="./index.html">
656-
Lisbook
657-
</a>
658-
659-
<div id="menu" class="nav-menu">
660-
<button id="menu-close" class="menu-close-btn">
661-
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
662-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
663-
</svg>
664-
</button>
665-
<a href="./index.html" class="nav-link">Home</a>
666-
<a href="./about.html" class="nav-link">About</a>
667-
<a href="./contact.html" class="nav-link">Contact</a>
668-
<a href="./faq.html" class="nav-link">FAQs</a>
669-
670-
671-
</div>
672-
673-
<button id="menu-toggle" title="Menu" class="menu-toggle-btn">
674-
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
675-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7" />
676-
</svg>
677-
</button>
678-
</div>
679-
</nav>
682+
<!-- Dynamic Navbar Placeholder -->
683+
<div id="navbar-placeholder"></div>
680684

681685

682686

@@ -914,115 +918,23 @@ <h2>Join Our Open-Source Project!</h2>
914918
});
915919
</script>
916920

921+
<!-- Scripts -->
922+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
923+
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
924+
crossorigin="anonymous"></script>
925+
926+
<!-- Dynamic Components Loader -->
927+
<script src="dynamic-components.js"></script>
928+
929+
<!-- Your page-specific scripts go here -->
930+
<script src="script.js"></script>
931+
<script src="app.js"></script>
932+
<script src="translation.js"></script>
917933

918-
<footer class="site-footer">
919-
<div class="footer-column">
920-
<div class="footer-brand">
921-
<a href="./index.html" class="brand-link">
922-
<img src="https://i.imgur.com/uR1GFCk.png" alt="Lisbook Logo" width="84" />
923-
</a>
924-
<div class="brand-text">
925-
<div class="brand-title">Lisbook</div>
926-
<p class="brand-tagline">LisBook is a straightforward audiobook player designed for simplicity and ease of use.
927-
</p>
928-
</div>
929-
</div>
930-
</div>
931-
932-
<div class="footer-column">
933-
<h5 class="footer-col-title">Important Link</h5>
934-
<ul class="footer-nav">
935-
<li class="nav-item"><a href="index.html">Home</a></li>
936-
<li class="nav-item"><a href="about.html">About</a></li>
937-
<li class="nav-item"><a href="contact.html">Contact</a></li>
938-
<li class="nav-item"><a href="faq.html">FAQs</a></li>
939-
<li class="nav-item"><a href="profile.html">Profile</a></li>
940-
</ul>
941-
</div>
942-
943-
<div class="footer-column">
944-
<h5 class="footer-col-title">Features</h5>
945-
<ul class="footer-nav">
946-
<li class="nav-item"><a href="#">Play/Pause</a></li>
947-
<li class="nav-item"><a href="#">Skip Chapters</a></li>
948-
<li class="nav-item"><a href="#">Change Speed</a></li>
949-
<li class="nav-item"><a href="#">Change Volume</a></li>
950-
<li class="nav-item"><a href="#">Change Theme</a></li>
951-
</ul>
952-
</div>
953934

954-
<div class="footer-column">
955-
<h5 class="footer-col-title">Follow Us</h5>
956-
<ul class="footer-nav">
957-
<li class="nav-item">
958-
<a href="https://www.instagram.com/dev_with_ctoic" target="_blank">
959-
<i class="bi bi-instagram"></i> Instagram
960-
</a>
961-
</li>
962-
<li class="nav-item">
963-
<a href="https://x.com/Ct0ic" target="_blank">
964-
<i class="bi bi-twitter-x"></i> Twitter-X
965-
</a>
966-
</li>
967-
<li class="nav-item">
968-
<a href="https://www.linkedin.com/in/ctoic/" target="_blank">
969-
<i class="bi bi-linkedin"></i> LinkedIn
970-
</a>
971-
</li>
972-
<li class="nav-item">
973-
<a href="https://github.com/Ctoic" target="_blank">
974-
<i class="bi bi-github"></i> GitHub
975-
</a>
976-
</li>
977-
</ul>
978-
</div>
935+
<!-- Dynamic Footer Placeholder -->
936+
<div id="footer-placeholder" class="mt-auto"></div>
979937

980-
<div class="footer-column">
981-
<h5 class="footer-col-title">Stay Updated</h5>
982-
<p>Subscribe to our newsletter for updates on new features and audiobooks.</p>
983-
<form id="newsletterForm">
984-
<input type="email" id="newsletterEmail" placeholder="Enter your email" required>
985-
<div id="emailError" class="invalid-feedback">Please provide a valid email address.</div>
986-
<button type="submit">Subscribe</button>
987-
</form>
988-
<div id="newsletterMessage" class="newsletter-message"></div>
989-
</div>
990-
</footer>
991-
992-
<script >
993-
document.addEventListener('DOMContentLoaded', function () {
994-
const newsletterForm = document.getElementById('newsletterForm');
995-
const emailInput = document.getElementById('newsletterEmail');
996-
const emailError = document.getElementById('emailError');
997-
const newsletterMessage = document.getElementById('newsletterMessage');
998-
999-
newsletterForm.addEventListener('submit', function (event) {
1000-
// Prevent the form from actually submitting to a server
1001-
event.preventDefault();
1002-
1003-
// Clear previous messages
1004-
newsletterMessage.textContent = '';
1005-
emailError.style.display = 'none';
1006-
emailInput.classList.remove('is-invalid');
1007-
1008-
// Simple email validation regex
1009-
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1010-
const email = emailInput.value.trim();
1011-
1012-
if (email === '' || !emailPattern.test(email)) {
1013-
// Show validation error
1014-
emailError.style.display = 'block';
1015-
emailInput.classList.add('is-invalid');
1016-
newsletterMessage.textContent = '';
1017-
} else {
1018-
// Show success message
1019-
newsletterMessage.textContent = 'Thank you for subscribing!';
1020-
newsletterMessage.style.color = '#198754'; // Success green
1021-
emailInput.value = ''; // Clear the input field
1022-
}
1023-
});
1024-
});
1025-
</script>
1026938

1027939

1028940

0 commit comments

Comments
 (0)