Skip to content
Open
48 changes: 38 additions & 10 deletions _includes/header.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
<header class="sticky top-0 w-full z-50 bg-white border-b border-gray-200">
<div class="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between">
<div class="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between">

<!-- Logo -->
<a href="{{ '/' | relative_url }}" class="flex items-center gap-3 font-semibold text-lg text-gray-900">
<div class="w-9 h-9 bg-white rounded-lg shadow-sm flex items-center justify-center overflow-hidden">
<img src="{{ site.baseurl }}/assets/images/blt-logo.png"
alt="BLT Logo"
class="w-full h-full object-contain p-1">
<img src="{{ site.baseurl }}/assets/images/blt-logo.png" alt="BLT Logo"
class="w-full h-full object-contain p-1">
</div>
<span>{{ site.university.name | default: "BLT University" }}</span>
</a>

<!-- Navigation -->
<!-- Navigation (Desktop) -->
<nav class="hidden md:flex gap-8 text-sm font-medium text-gray-600">
{% for item in site.navigation %}
<a href="{{ item.url | relative_url }}"
class="{% if page.url == item.url %}
<a href="{{ item.url | relative_url }}" class="{% if page.url == item.url %}
text-bltRed border-b-2 border-bltRed pb-1
{% else %}
hover:text-gray-900 transition-colors
{% endif %}">
{{ item.title }}
</a>
{{ item.title }}
</a>
{% endfor %}
</nav>

<!-- Mobile Menu Button -->
<button id="mobile-menu-button" type="button"
class="md:hidden p-2 text-gray-600 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-bltRed/20 rounded-md transition-all duration-200"
aria-label="Toggle navigation"
aria-controls="mobile-menu"
aria-expanded="false">
<svg id="menu-icon" class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
</svg>
<svg id="close-icon" class="hidden w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>

</div>

<!-- Mobile Menu -->
<div id="mobile-menu"
class="hidden md:hidden absolute top-16 left-0 w-full bg-white border-b border-gray-100 shadow-xl overflow-hidden transition-all duration-300 ease-in-out opacity-0 max-h-0">
<nav class="flex flex-col gap-1 p-4 text-sm font-medium text-gray-600">
{% for item in site.navigation %}
<a href="{{ item.url | relative_url }}" class="px-4 py-3 rounded-lg transition-all duration-200 {% if page.url == item.url %}
bg-bltRedLight text-bltRed font-semibold
{% else %}
hover:bg-gray-50 hover:text-gray-900
{% endif %}">
{{ item.title }}
</a>
{% endfor %}
</nav>
</div>
</header>
26 changes: 17 additions & 9 deletions _layouts/default.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<!DOCTYPE html>
<html lang="en" class="scroll-smooth">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title | default: "BLT University" }}</title>
<meta name="description" content="{{ page.description | default: site.description }}">

{% seo %}

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">

<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
<script>
tailwind.config = {
Expand All @@ -21,18 +22,25 @@
colors: { bltRed: '#dc2626', bltRedLight: '#fef2f2', bltRedHover: '#b91c1c', bltDark: '#0f172a' },
boxShadow: { 'soft': '0 20px 40px -15px rgba(0,0,0,0.05)', 'float': '0 30px 60px -15px rgba(0,0,0,0.08)' }
}
}
},
safelist: [
'max-h-[500px]',
'opacity-100'
]
}
</script>
</head>
<body class="bg-[#fafafa] text-gray-900 font-sans antialiased selection:bg-bltRed selection:text-white flex flex-col min-h-screen">


<body
class="bg-[#fafafa] text-gray-900 font-sans antialiased selection:bg-bltRed selection:text-white flex flex-col min-h-screen">

{% include header.html %}

{{ content }}

{% include footer.html %}

<script src="{{ '/assets/js/main.js' | relative_url }}"></script>
</body>

</html>
89 changes: 74 additions & 15 deletions assets/js/main.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
// BLT University JavaScript

document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {

// Course Filtering
const categoryFilter = document.getElementById('category-filter');
const levelFilter = document.getElementById('level-filter');
const searchFilter = document.getElementById('search-filter');
const coursesGrid = document.getElementById('courses-grid');
const noResults = document.getElementById('no-results');

if (categoryFilter && levelFilter && searchFilter && coursesGrid) {
function filterCourses() {
const categoryValue = categoryFilter.value.toLowerCase();
const levelValue = levelFilter.value.toLowerCase();
const searchValue = searchFilter.value.toLowerCase();

const courses = coursesGrid.getElementsByClassName('course-card');
let visibleCount = 0;

Array.from(courses).forEach(course => {
const courseCategory = course.getAttribute('data-category');
const courseLevel = course.getAttribute('data-level');
const courseSearch = course.getAttribute('data-search');

const categoryMatch = !categoryValue || courseCategory === categoryValue;
const levelMatch = !levelValue || courseLevel === levelValue;
const searchMatch = !searchValue || courseSearch.includes(searchValue);

if (categoryMatch && levelMatch && searchMatch) {
course.style.display = '';
visibleCount++;
} else {
course.style.display = 'none';
}
});

if (noResults) {
noResults.style.display = visibleCount === 0 ? 'block' : 'none';
}
}

categoryFilter.addEventListener('change', filterCourses);
levelFilter.addEventListener('change', filterCourses);
searchFilter.addEventListener('input', filterCourses);
}

// Parse URL parameters for enrollment
const urlParams = new URLSearchParams(window.location.search);
const courseParam = urlParams.get('course');
const titleParam = urlParams.get('title');

if (courseParam && window.location.pathname.includes('/enroll/')) {
console.log('Enrolling in course:', courseParam, titleParam);

// Update the enrollment button to prefill the title if available
if (titleParam) {
const enrollButton = document.querySelector('[data-enrollment-button]');
Expand All @@ -64,7 +64,7 @@ document.addEventListener('DOMContentLoaded', function() {
}
}
}

// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
Expand All @@ -78,10 +78,69 @@ document.addEventListener('DOMContentLoaded', function() {
}
});
});


// Mobile Menu Toggle
const mobileMenuButton = document.getElementById('mobile-menu-button');
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('menu-icon');
const closeIcon = document.getElementById('close-icon');
let mobileMenuTimer = null;

if (mobileMenuButton && mobileMenu) {
const openMenu = () => {
mobileMenu.classList.remove('hidden');
// Trigger reflow for transition
mobileMenu.offsetHeight;
mobileMenu.classList.remove('max-h-0', 'opacity-0');
mobileMenu.classList.add('max-h-[500px]', 'opacity-100');
menuIcon.classList.add('hidden');
closeIcon.classList.remove('hidden');
mobileMenuButton.setAttribute('aria-expanded', 'true');
};

const closeMenu = () => {
mobileMenu.classList.remove('max-h-[500px]', 'opacity-100');
mobileMenu.classList.add('max-h-0', 'opacity-0');
menuIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
mobileMenuButton.setAttribute('aria-expanded', 'false');

if (mobileMenuTimer) clearTimeout(mobileMenuTimer);
mobileMenuTimer = setTimeout(() => {
mobileMenu.classList.add('hidden');
mobileMenuTimer = null;
}, 300); // Wait for transition to finish
};

mobileMenuButton.addEventListener('click', () => {
if (mobileMenuButton.getAttribute('aria-expanded') === 'true') {
closeMenu();
} else {
openMenu();
}
});

// Close menu on resize if screen becomes desktop-sized
window.addEventListener('resize', () => {
if (window.innerWidth >= 768) {
if (mobileMenuTimer) {
clearTimeout(mobileMenuTimer);
mobileMenuTimer = null;
}

mobileMenu.classList.add('hidden');
mobileMenu.classList.add('max-h-0', 'opacity-0');
mobileMenu.classList.remove('max-h-[500px]', 'opacity-100');
menuIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
mobileMenuButton.setAttribute('aria-expanded', 'false');
}
});
}

// Add active class to current navigation item
const currentPath = window.location.pathname;
document.querySelectorAll('.site-navigation a').forEach(link => {
document.querySelectorAll('.site-navigation a, #mobile-menu a').forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active');
}
Expand Down