+
+
-
-
+
+ // Close mobile sidebar if needed
+ if (window.innerWidth < 1024 && sidebar) {
+ sidebar.classList.add("-translate-x-full");
+ document.body.classList.remove("overflow-hidden");
+ const overlay = document.getElementById("sidebarOverlay");
+ overlay?.remove();
+ }
+ });
+ });
+ };
+
+ // Display user profile information and handle role-based access
+ const updateUserProfile = async (user: { id: string }) => {
+ if (!user) return;
+
+ try {
+ // Use fields from the User interface in the schema
+ const extendedUser = await get.getOne("users", user.id, {
+ fields: [
+ "id",
+ "name",
+ "email",
+ "verified",
+ "avatar",
+ "pid",
+ "member_id",
+ "graduation_year",
+ "major",
+ ],
+ });
+
+ const displayName = extendedUser.name || "Unknown User";
+ // Default role is Member
+ let displayRole = "Member";
+
+ // Map the officer type from the database to our OfficerStatus type
+ let officerStatus: OfficerStatus = "";
+
+ // Get the officer record for this user if it exists
+ // Use fields from the Officer interface in the schema
+ const officerRecords = await get.getList(
+ "officers",
+ 1,
+ 50,
+ `user="${user.id}"`,
+ "",
+ {
+ fields: ["id", "type", "role"],
+ },
+ );
+
+ if (officerRecords && officerRecords.items.length > 0) {
+ const officerType = officerRecords.items[0].type;
+ const officerRole = officerRecords.items[0].role;
+
+ // Use the role field from the officer's collection
+ if (officerRole) {
+ displayRole = officerRole;
+ }
+
+ // Map the officer type to our OfficerStatus
+ switch (officerType) {
+ case OfficerTypes.ADMINISTRATOR:
+ officerStatus = "administrator";
+ break;
+ case OfficerTypes.EXECUTIVE:
+ officerStatus = "executive";
+ break;
+ case OfficerTypes.GENERAL:
+ officerStatus = "general";
+ break;
+ case OfficerTypes.HONORARY:
+ officerStatus = "honorary";
+ break;
+ case OfficerTypes.PAST:
+ officerStatus = "past";
+ break;
+ default:
+ officerStatus = "none";
+ }
+ } else {
+ // Check if user is a sponsor by querying the sponsors collection
+ const sponsorRecords = await get.getList(
+ "sponsors",
+ 1,
+ 1,
+ `user="${user.id}"`,
+ "",
+ {
+ fields: ["id", "company"],
+ },
+ );
+
+ if (sponsorRecords && sponsorRecords.items.length > 0) {
+ officerStatus = "sponsor";
+ displayRole = "Sponsor";
+ } else {
+ officerStatus = "none";
+ }
+ }
+
+ const initials = (extendedUser.name || "U")
+ .split(" ")
+ .map((n: string) => n[0])
+ .join("")
+ .toUpperCase();
+
+ // Update profile display
+ if (userName) userName.textContent = displayName;
+ if (userRole) userRole.textContent = displayRole;
+ if (userInitials) userInitials.textContent = initials;
+
+ // Update section visibility based on role
+ updateSectionVisibility(officerStatus);
+ } catch (error) {
+ console.error("Error fetching user profile:", error);
+ const fallbackValues = {
+ name: "Unknown User",
+ role: "Member",
+ initials: "?",
+ };
+
+ if (userName) userName.textContent = fallbackValues.name;
+ if (userRole) userRole.textContent = fallbackValues.role;
+ if (userInitials) userInitials.textContent = fallbackValues.initials;
+
+ updateSectionVisibility("" as OfficerStatus);
+ }
+ };
+
+ // Mobile sidebar toggle
+ const mobileSidebarToggle = document.getElementById(
+ "mobileSidebarToggle",
+ );
+ if (mobileSidebarToggle && sidebar) {
+ const toggleSidebar = () => {
+ const isOpen = !sidebar.classList.contains("-translate-x-full");
+
+ if (isOpen) {
+ sidebar.classList.add("-translate-x-full");
+ document.body.classList.remove("overflow-hidden");
+ const overlay = document.getElementById("sidebarOverlay");
+ overlay?.remove();
+ } else {
+ sidebar.classList.remove("-translate-x-full");
+ document.body.classList.add("overflow-hidden");
+ const overlay = document.createElement("div");
+ overlay.id = "sidebarOverlay";
+ overlay.className =
+ "fixed inset-0 bg-black bg-opacity-50 z-40 xl:hidden";
+ overlay.addEventListener("click", toggleSidebar);
+ document.body.appendChild(overlay);
+ }
+ };
+
+ mobileSidebarToggle.addEventListener("click", toggleSidebar);
+ }
+
+ // Function to initialize the page
+ const initializePage = async () => {
+ try {
+ // Initialize auth sync for IndexedDB
+ await initAuthSync();
+
+ // Check if user is authenticated
+ if (!auth.isAuthenticated()) {
+ // console.log("User not authenticated");
+ if (pageLoadingState) pageLoadingState.classList.add("hidden");
+ if (notAuthenticatedState)
+ notAuthenticatedState.classList.remove("hidden");
+ return;
+ }
+
+ if (pageLoadingState) pageLoadingState.classList.remove("hidden");
+ if (pageErrorState) pageErrorState.classList.add("hidden");
+ if (notAuthenticatedState)
+ notAuthenticatedState.classList.add("hidden");
+
+ // Show loading states
+ const userProfileSkeleton = document.getElementById(
+ "userProfileSkeleton",
+ );
+ const userProfileSignedOut = document.getElementById(
+ "userProfileSignedOut",
+ );
+ const userProfileSummary =
+ document.getElementById("userProfileSummary");
+ const menuLoadingSkeleton = document.getElementById(
+ "menuLoadingSkeleton",
+ );
+ const actualMenu = document.getElementById("actualMenu");
+
+ if (userProfileSkeleton)
+ userProfileSkeleton.classList.remove("hidden");
+ if (userProfileSummary) userProfileSummary.classList.add("hidden");
+ if (userProfileSignedOut)
+ userProfileSignedOut.classList.add("hidden");
+ if (menuLoadingSkeleton)
+ menuLoadingSkeleton.classList.remove("hidden");
+ if (actualMenu) actualMenu.classList.add("hidden");
+
+ const user = auth.getCurrentUser();
+ await updateUserProfile(user);
+
+ // Show actual profile and hide skeleton
+ if (userProfileSkeleton) userProfileSkeleton.classList.add("hidden");
+ if (userProfileSummary) userProfileSummary.classList.remove("hidden");
+
+ // Hide all sections first
+ document.querySelectorAll(".dashboard-section").forEach((section) => {
+ section.classList.add("hidden");
+ });
+
+ // Show appropriate default section based on role
+ // Get the officer record for this user if it exists
+ let officerStatus: OfficerStatus = "none";
+
+ try {
+ const officerRecords = await get.getList(
+ "officers",
+ 1,
+ 50,
+ `user="${user.id}"`,
+ "",
+ {
+ fields: ["id", "type", "role"],
+ },
+ );
+
+ if (officerRecords && officerRecords.items.length > 0) {
+ const officerType = officerRecords.items[0].type;
+ // We can also get the role here if needed for display elsewhere
+ const officerRole = officerRecords.items[0].role;
+
+ // Map the officer type to our OfficerStatus
+ switch (officerType) {
+ case OfficerTypes.ADMINISTRATOR:
+ officerStatus = "administrator";
+ break;
+ case OfficerTypes.EXECUTIVE:
+ officerStatus = "executive";
+ break;
+ case OfficerTypes.GENERAL:
+ officerStatus = "general";
+ break;
+ case OfficerTypes.HONORARY:
+ officerStatus = "honorary";
+ break;
+ case OfficerTypes.PAST:
+ officerStatus = "past";
+ break;
+ default:
+ officerStatus = "none";
+ }
+ } else {
+ // Check if user is a sponsor by querying the sponsors collection
+ const sponsorRecords = await get.getList(
+ "sponsors",
+ 1,
+ 1,
+ `user="${user.id}"`,
+ "",
+ {
+ fields: ["id", "company"],
+ },
+ );
+
+ if (sponsorRecords && sponsorRecords.items.length > 0) {
+ officerStatus = "sponsor";
+ } else {
+ officerStatus = "none";
+ }
+ }
+ } catch (error) {
+ console.error("Error determining officer status:", error);
+ officerStatus = "none";
+ }
+
+ let defaultSection;
+ let defaultButton;
+
+ // Set default section based on role
+ // Only sponsors get a different default view
+ if (officerStatus === "sponsor") {
+ // For sponsors, show the sponsor dashboard
+ defaultSection = document.getElementById("sponsorDashboardSection");
+ defaultButton = document.querySelector(
+ '[data-section="sponsorDashboard"]',
+ );
+ } else {
+ // For all other users (including administrators), show the profile section
+ defaultSection = document.getElementById("profileSection");
+ defaultButton = document.querySelector('[data-section="profile"]');
+
+ // Log the default section for debugging
+ // console.log(`Setting default section to profile for user with role: ${officerStatus}`);
+ }
+
+ if (defaultSection) {
+ defaultSection.classList.remove("hidden");
+ }
+ if (defaultButton) {
+ defaultButton.classList.add("active", "bg-base-200");
+ }
+
+ // Initialize navigation
+ handleNavigation();
+
+ // Show actual menu and hide skeleton
+ if (menuLoadingSkeleton) menuLoadingSkeleton.classList.add("hidden");
+ if (actualMenu) actualMenu.classList.remove("hidden");
+
+ // Show main content and hide loading
+ if (mainContent) mainContent.classList.remove("hidden");
+ if (pageLoadingState) pageLoadingState.classList.add("hidden");
+ } catch (error) {
+ console.error("Error initializing dashboard:", error);
+ if (pageLoadingState) pageLoadingState.classList.add("hidden");
+ if (pageErrorState) pageErrorState.classList.remove("hidden");
+ }
+ };
+
+ // Initialize when DOM is loaded
+ document.addEventListener("DOMContentLoaded", initializePage);
+
+ // Handle login button click
+ document
+ .querySelector(".login-button")
+ ?.addEventListener("click", async () => {
+ try {
+ if (pageLoadingState) pageLoadingState.classList.remove("hidden");
+ if (notAuthenticatedState)
+ notAuthenticatedState.classList.add("hidden");
+ await auth.login();
+ } catch (error) {
+ console.error("Login error:", error);
+ if (pageLoadingState) pageLoadingState.classList.add("hidden");
+ if (pageErrorState) pageErrorState.classList.remove("hidden");
+ }
+ });
+
+ // Handle logout button click
+ document.getElementById("logoutButton")?.addEventListener("click", () => {
+ auth.logout();
+ window.location.reload();
+ });
+
+ // Handle responsive sidebar
+ if (sidebar) {
+ if (window.innerWidth < 1024) {
+ sidebar.classList.add("-translate-x-full");
+ }
+
+ window.addEventListener("resize", () => {
+ if (window.innerWidth >= 1024) {
+ const overlay = document.getElementById("sidebarOverlay");
+ if (overlay) {
+ overlay.remove();
+ document.body.classList.remove("overflow-hidden");
+ }
+ sidebar.classList.remove("-translate-x-full");
+ }
+ });
+ }
+
+