mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2025-09-08 23:18:43 +00:00
updated sidebar
This commit is contained in:
@@ -2,11 +2,6 @@
|
|||||||
id="sidebar"
|
id="sidebar"
|
||||||
class="bg-gray-900 text-white transition-transform duration-300 ease-in-out fixed top-0 left-0 w-64 h-screen overflow-y-auto"
|
class="bg-gray-900 text-white transition-transform duration-300 ease-in-out fixed top-0 left-0 w-64 h-screen overflow-y-auto"
|
||||||
>
|
>
|
||||||
<!--
|
|
||||||
The sidebar is hidden by default on mobile via CSS (transform: translateX(-100%)).
|
|
||||||
When the "sidebar-open" class is added (via the mobile menu button), CSS will slide it into view.
|
|
||||||
On desktop (min-width: 768px), the sidebar is always visible.
|
|
||||||
-->
|
|
||||||
<div class="flex flex-col h-full">
|
<div class="flex flex-col h-full">
|
||||||
<!-- Top Navigation Links -->
|
<!-- Top Navigation Links -->
|
||||||
<div class="flex-1 overflow-y-auto px-4">
|
<div class="flex-1 overflow-y-auto px-4">
|
||||||
@@ -50,8 +45,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Footer Links -->
|
<!-- Mobile Dropdown Button for Footer Links -->
|
||||||
<div class="mt-auto">
|
<!-- Added p-4 around the button for spacing, and styling consistent with top links -->
|
||||||
|
<div class="md:hidden p-4">
|
||||||
|
<button
|
||||||
|
id="footerDropdownButton"
|
||||||
|
class="flex items-center w-full py-2 px-4 bg-gray-800 hover:bg-gray-700 text-sm font-semibold text-gray-100 rounded shadow-md focus:outline-none transition-colors duration-200"
|
||||||
|
>
|
||||||
|
<!-- Arrow on the left side -->
|
||||||
|
<svg
|
||||||
|
id="footerDropdownIcon"
|
||||||
|
class="w-4 h-4 mr-2 transform transition-transform duration-300"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M19 9l-7 7-7-7"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span id="footerDropdownText">More</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Footer Links Container -->
|
||||||
|
<!-- On mobile: hidden by default; on desktop: visible and pushed to the bottom -->
|
||||||
|
<div id="footerLinksContainer" class="hidden md:block md:mt-auto">
|
||||||
<hr class="border-gray-700" />
|
<hr class="border-gray-700" />
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<nav class="space-y-2 text-sm opacity-70">
|
<nav class="space-y-2 text-sm opacity-70">
|
||||||
@@ -197,4 +220,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var btn = document.getElementById("footerDropdownButton");
|
||||||
|
var footerLinks = document.getElementById("footerLinksContainer");
|
||||||
|
if (btn && footerLinks) {
|
||||||
|
btn.addEventListener("click", function () {
|
||||||
|
footerLinks.classList.toggle("hidden");
|
||||||
|
var icon = document.getElementById("footerDropdownIcon");
|
||||||
|
var textSpan = document.getElementById("footerDropdownText");
|
||||||
|
if (footerLinks.classList.contains("hidden")) {
|
||||||
|
textSpan.textContent = "More";
|
||||||
|
if (icon) {
|
||||||
|
icon.classList.remove("rotate-180");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
textSpan.textContent = "Less";
|
||||||
|
if (icon) {
|
||||||
|
icon.classList.add("rotate-180");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</aside>
|
</aside>
|
||||||
|
58
js/index.js
58
js/index.js
@@ -66,22 +66,37 @@ Promise.all([
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("Sidebar loaded.");
|
console.log("Sidebar loaded.");
|
||||||
|
|
||||||
// Assuming mobileMenuBtn, sidebar, and app are already defined:
|
// Attach mobile menu button toggle logic (for sidebar)
|
||||||
const mobileMenuBtn = document.getElementById("mobileMenuBtn");
|
const mobileMenuBtn = document.getElementById("mobileMenuBtn");
|
||||||
const sidebar = document.getElementById("sidebar");
|
const sidebar = document.getElementById("sidebar");
|
||||||
const app = document.getElementById("app");
|
const app = document.getElementById("app");
|
||||||
|
|
||||||
if (mobileMenuBtn && sidebar && app) {
|
if (mobileMenuBtn && sidebar && app) {
|
||||||
mobileMenuBtn.addEventListener("click", () => {
|
mobileMenuBtn.addEventListener("click", () => {
|
||||||
// Toggle the dedicated class that controls visibility on mobile
|
|
||||||
sidebar.classList.toggle("sidebar-open");
|
sidebar.classList.toggle("sidebar-open");
|
||||||
// Optionally shift main content on mobile
|
|
||||||
app.classList.toggle("sidebar-open");
|
app.classList.toggle("sidebar-open");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attach "More" button toggle logic for footer links
|
||||||
|
const footerDropdownButton = document.getElementById(
|
||||||
|
"footerDropdownButton"
|
||||||
|
);
|
||||||
|
if (footerDropdownButton) {
|
||||||
|
footerDropdownButton.addEventListener("click", () => {
|
||||||
|
const footerLinksContainer = document.getElementById(
|
||||||
|
"footerLinksContainer"
|
||||||
|
);
|
||||||
|
if (!footerLinksContainer) return;
|
||||||
|
footerLinksContainer.classList.toggle("hidden");
|
||||||
|
if (footerLinksContainer.classList.contains("hidden")) {
|
||||||
|
footerDropdownButton.innerHTML = "More ▼";
|
||||||
|
} else {
|
||||||
|
footerDropdownButton.innerHTML = "Less ▲";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Load and set up sidebar navigation
|
// Load and set up sidebar navigation
|
||||||
// (We assume it calls setHashView(...) now)
|
|
||||||
return import("./sidebar.js").then((module) => {
|
return import("./sidebar.js").then((module) => {
|
||||||
module.setupSidebarNavigation();
|
module.setupSidebarNavigation();
|
||||||
});
|
});
|
||||||
@@ -115,7 +130,7 @@ Promise.all([
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) “Application Form” => open application form
|
// 3) "Application Form" => open application form
|
||||||
const openAppFormBtn = document.getElementById("openApplicationModal");
|
const openAppFormBtn = document.getElementById("openApplicationModal");
|
||||||
if (openAppFormBtn) {
|
if (openAppFormBtn) {
|
||||||
openAppFormBtn.addEventListener("click", () => {
|
openAppFormBtn.addEventListener("click", () => {
|
||||||
@@ -168,18 +183,10 @@ Promise.all([
|
|||||||
*/
|
*/
|
||||||
export function setHashView(viewName) {
|
export function setHashView(viewName) {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
|
|
||||||
// Remove possibly conflicting query params
|
|
||||||
url.searchParams.delete("modal");
|
url.searchParams.delete("modal");
|
||||||
url.searchParams.delete("v");
|
url.searchParams.delete("v");
|
||||||
|
|
||||||
// Keep the existing path + updated search, set the new hash
|
|
||||||
const newUrl = url.pathname + url.search + `#view=${viewName}`;
|
const newUrl = url.pathname + url.search + `#view=${viewName}`;
|
||||||
|
|
||||||
// Replace the URL so no full reload
|
|
||||||
window.history.replaceState({}, "", newUrl);
|
window.history.replaceState({}, "", newUrl);
|
||||||
|
|
||||||
// Manually trigger handleHashChange so the view loads immediately
|
|
||||||
handleHashChange();
|
handleHashChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,18 +196,10 @@ export function setHashView(viewName) {
|
|||||||
*/
|
*/
|
||||||
export function setQueryParam(key, value) {
|
export function setQueryParam(key, value) {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
|
|
||||||
// Remove any #view=... from the hash
|
|
||||||
url.hash = "";
|
url.hash = "";
|
||||||
|
|
||||||
// Set the query param
|
|
||||||
url.searchParams.set(key, value);
|
url.searchParams.set(key, value);
|
||||||
|
|
||||||
// Replace the URL
|
|
||||||
const newUrl = url.pathname + url.search;
|
const newUrl = url.pathname + url.search;
|
||||||
window.history.replaceState({}, "", newUrl);
|
window.history.replaceState({}, "", newUrl);
|
||||||
|
|
||||||
// Immediately handle it
|
|
||||||
handleQueryParams();
|
handleQueryParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +211,6 @@ function handleQueryParams() {
|
|||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const modalParam = urlParams.get("modal");
|
const modalParam = urlParams.get("modal");
|
||||||
|
|
||||||
// 5) Check ?modal=... param (moved from original code)
|
|
||||||
if (modalParam === "appeals") {
|
if (modalParam === "appeals") {
|
||||||
const appealsModal = document.getElementById("contentAppealsModal");
|
const appealsModal = document.getElementById("contentAppealsModal");
|
||||||
if (appealsModal) {
|
if (appealsModal) {
|
||||||
@@ -225,7 +223,6 @@ function handleQueryParams() {
|
|||||||
if (appealsModal) {
|
if (appealsModal) {
|
||||||
appealsModal.classList.add("hidden");
|
appealsModal.classList.add("hidden");
|
||||||
}
|
}
|
||||||
// Show disclaimer if not seen
|
|
||||||
if (!localStorage.getItem("hasSeenDisclaimer")) {
|
if (!localStorage.getItem("hasSeenDisclaimer")) {
|
||||||
const disclaimerModal = document.getElementById("disclaimerModal");
|
const disclaimerModal = document.getElementById("disclaimerModal");
|
||||||
if (disclaimerModal) {
|
if (disclaimerModal) {
|
||||||
@@ -240,7 +237,6 @@ function handleQueryParams() {
|
|||||||
appModal.classList.remove("hidden");
|
appModal.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If there's no special param, disclaimers can show if user hasn't seen them
|
|
||||||
const hasSeenDisclaimer = localStorage.getItem("hasSeenDisclaimer");
|
const hasSeenDisclaimer = localStorage.getItem("hasSeenDisclaimer");
|
||||||
if (!hasSeenDisclaimer) {
|
if (!hasSeenDisclaimer) {
|
||||||
const disclaimerModal = document.getElementById("disclaimerModal");
|
const disclaimerModal = document.getElementById("disclaimerModal");
|
||||||
@@ -250,7 +246,6 @@ function handleQueryParams() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8) Additional forms
|
|
||||||
if (modalParam === "feedback") {
|
if (modalParam === "feedback") {
|
||||||
const feedbackModal = document.getElementById("generalFeedbackModal");
|
const feedbackModal = document.getElementById("generalFeedbackModal");
|
||||||
if (feedbackModal) {
|
if (feedbackModal) {
|
||||||
@@ -268,7 +263,6 @@ function handleQueryParams() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9) Close buttons
|
|
||||||
const closeFeedbackBtn = document.getElementById("closeGeneralFeedbackModal");
|
const closeFeedbackBtn = document.getElementById("closeGeneralFeedbackModal");
|
||||||
if (closeFeedbackBtn) {
|
if (closeFeedbackBtn) {
|
||||||
closeFeedbackBtn.addEventListener("click", () => {
|
closeFeedbackBtn.addEventListener("click", () => {
|
||||||
@@ -296,10 +290,6 @@ function handleQueryParams() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// You could also check ?v=someEvent to open a video, etc.
|
|
||||||
// if you want to keep ?v= param logic here.
|
|
||||||
// ...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -308,10 +298,7 @@ function handleQueryParams() {
|
|||||||
function handleHashChange() {
|
function handleHashChange() {
|
||||||
console.log("handleHashChange called, current hash =", window.location.hash);
|
console.log("handleHashChange called, current hash =", window.location.hash);
|
||||||
const hash = window.location.hash || "";
|
const hash = window.location.hash || "";
|
||||||
// Expecting something like #view=most-recent-videos
|
|
||||||
const match = hash.match(/^#view=(.+)/);
|
const match = hash.match(/^#view=(.+)/);
|
||||||
|
|
||||||
// If no #view=..., load "most-recent-videos" as default
|
|
||||||
if (!match || !match[1]) {
|
if (!match || !match[1]) {
|
||||||
import("./viewManager.js").then(({ loadView, viewInitRegistry }) => {
|
import("./viewManager.js").then(({ loadView, viewInitRegistry }) => {
|
||||||
loadView("views/most-recent-videos.html").then(() => {
|
loadView("views/most-recent-videos.html").then(() => {
|
||||||
@@ -323,11 +310,8 @@ function handleHashChange() {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const viewName = match[1];
|
const viewName = match[1];
|
||||||
const viewUrl = `views/${viewName}.html`;
|
const viewUrl = `views/${viewName}.html`;
|
||||||
|
|
||||||
// Load the partial
|
|
||||||
import("./viewManager.js").then(({ loadView, viewInitRegistry }) => {
|
import("./viewManager.js").then(({ loadView, viewInitRegistry }) => {
|
||||||
loadView(viewUrl).then(() => {
|
loadView(viewUrl).then(() => {
|
||||||
const initFn = viewInitRegistry[viewName];
|
const initFn = viewInitRegistry[viewName];
|
||||||
|
Reference in New Issue
Block a user