{"id":1,"date":"2025-08-26T19:10:16","date_gmt":"2025-08-26T19:10:16","guid":{"rendered":"https:\/\/soundiip.host.dartmouth.edu\/?p=1"},"modified":"2025-08-26T20:49:55","modified_gmt":"2025-08-26T20:49:55","slug":"hello-world","status":"publish","type":"post","link":"https:\/\/soundiip.host.dartmouth.edu\/?p=1","title":{"rendered":"25F IIP Meeting Availability"},"content":{"rendered":"<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>25F IIP Meeting Availability<\/title>\r\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\r\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\r\n    <style>\r\n        body {\r\n            font-family: 'Inter', sans-serif;\r\n        }\r\n        .custom-focus:focus {\r\n            outline: none;\r\n            box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.5);\r\n        }\r\n        .transition-all {\r\n            transition-property: all;\r\n            transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\r\n            transition-duration: 150ms;\r\n        }\r\n        \/* Loading spinner *\/\r\n        .loader {\r\n            border: 4px solid #f3f3f3;\r\n            border-top: 4px solid #4f46e5;\r\n            border-radius: 50%;\r\n            width: 40px;\r\n            height: 40px;\r\n            animation: spin 1s linear infinite;\r\n        }\r\n        @keyframes spin {\r\n            0% { transform: rotate(0deg); }\r\n            100% { transform: rotate(360deg); }\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body class=\"bg-gray-50 text-gray-800 flex flex-col items-center justify-center min-h-screen p-4\">\r\n\r\n    <div class=\"w-full max-w-5xl mx-auto\">\r\n        <!-- Student-facing Survey -->\r\n        <div id=\"survey-container\" class=\"bg-white p-6 sm:p-8 rounded-xl shadow-lg\">\r\n            <div class=\"text-center mb-8\">\r\n                <h1 class=\"text-2xl sm:text-3xl font-bold text-gray-900\">25F IIP Meeting Availability<\/h1>\r\n                <p class=\"text-gray-600 mt-2\">Please check all the times you are available for a weekly meeting this term.<\/p>\r\n            <\/div>\r\n\r\n            <form id=\"availability-form\">\r\n                <div class=\"mb-6\">\r\n                    <label for=\"studentName\" class=\"block text-sm font-medium text-gray-700 mb-2\">Your Full Name<\/label>\r\n                    <input type=\"text\" id=\"studentName\" name=\"studentName\" required class=\"block w-full px-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 custom-focus sm:text-sm transition-all\" placeholder=\"e.g., Jane Doe\">\r\n                <\/div>\r\n\r\n                <div class=\"mb-6\">\r\n                    <label for=\"studentEmail\" class=\"block text-sm font-medium text-gray-700 mb-2\">Your Email Address<\/label>\r\n                    <input type=\"email\" id=\"studentEmail\" name=\"studentEmail\" required class=\"block w-full px-4 py-3 border border-gray-300 rounded-lg shadow-sm focus:border-indigo-500 custom-focus sm:text-sm transition-all\" placeholder=\"e.g., jane.doe@example.com\">\r\n                <\/div>\r\n\r\n                <div class=\"overflow-x-auto\">\r\n                    <table class=\"w-full text-sm text-left text-gray-500 border-collapse\">\r\n                        <thead class=\"text-xs text-gray-700 uppercase bg-gray-100\">\r\n                            <tr>\r\n                                <th scope=\"col\" class=\"px-4 py-3 rounded-tl-lg\">Time<\/th>\r\n                                <th scope=\"col\" class=\"px-4 py-3 text-center\">Monday<\/th>\r\n                                <th scope=\"col\" class=\"px-4 py-3 text-center\">Tuesday<\/th>\r\n                                <th scope=\"col\" class=\"px-4 py-3 text-center\">Wednesday<\/th>\r\n                                <th scope=\"col\" class=\"px-4 py-3 text-center\">Thursday<\/th>\r\n                                <th scope=\"col\" class=\"px-4 py-3 text-center\">Friday<\/th>\r\n                                <th scope=\"col\" class=\"px-4 py-3 text-center rounded-tr-lg\">Saturday<\/th>\r\n                            <\/tr>\r\n                        <\/thead>\r\n                        <tbody id=\"time-slots-body\">\r\n                            <!-- Time slots will be dynamically generated here -->\r\n                        <\/tbody>\r\n                    <\/table>\r\n                <\/div>\r\n\r\n                <div class=\"mt-8 text-center\">\r\n                    <button type=\"submit\" class=\"w-full sm:w-auto inline-flex justify-center items-center px-8 py-3 border border-transparent text-base font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none custom-focus transition-all\">\r\n                        Submit Availability\r\n                    <\/button>\r\n                <\/div>\r\n            <\/form>\r\n        <\/div>\r\n        \r\n        <!-- Success Message (Hidden by default) -->\r\n        <div id=\"success-message\" class=\"hidden bg-white p-8 rounded-xl shadow-lg text-center\">\r\n             <svg class=\"mx-auto h-12 w-12 text-green-500\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" fill=\"none\" viewbox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\r\n                <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" \/>\r\n            <\/svg>\r\n            <h2 class=\"mt-4 text-2xl font-bold text-gray-900\">Thank You!<\/h2>\r\n            <p class=\"mt-2 text-gray-600\">Your availability has been submitted successfully.<\/p>\r\n        <\/div>\r\n\r\n\r\n        <!-- Admin Login Button -->\r\n        <div id=\"admin-login-container\" class=\"text-center mt-4\">\r\n             <button id=\"admin-login-button\" class=\"text-sm text-indigo-600 hover:underline focus:outline-none custom-focus p-1 rounded\">Admin View<\/button>\r\n        <\/div>\r\n\r\n\r\n        <!-- Professor's Dashboard (Hidden by default) -->\r\n        <div id=\"admin-panel\" class=\"hidden mt-10 bg-white p-6 sm:p-8 rounded-xl shadow-lg\">\r\n            <h2 class=\"text-xl sm:text-2xl font-bold text-gray-900 mb-4\">Submissions Dashboard<\/h2>\r\n            \r\n            <div class=\"flex items-center mb-4 pl-3\">\r\n                <input id=\"select-all-checkbox\" type=\"checkbox\" class=\"h-4 w-4 text-indigo-600 border-gray-300 rounded custom-focus\">\r\n                <label for=\"select-all-checkbox\" class=\"ml-2 block text-sm font-medium text-gray-900\">Select All<\/label>\r\n            <\/div>\r\n\r\n            <div id=\"submissions-list\" class=\"space-y-3 mb-6 max-h-96 overflow-y-auto\">\r\n                <p class=\"text-gray-500\">No submissions yet.<\/p>\r\n            <\/div>\r\n            \r\n            <div class=\"text-center\">\r\n                <button id=\"gemini-button\" class=\"w-full sm:w-auto inline-flex justify-center items-center px-6 py-3 border border-transparent text-base font-medium rounded-lg shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none custom-focus transition-all disabled:bg-indigo-300\">\r\n                    \u2728 Create 1-on-1 Meeting Schedule\r\n                <\/button>\r\n            <\/div>\r\n\r\n            <div id=\"gemini-output-container\" class=\"mt-6 hidden\">\r\n                <h3 class=\"text-lg font-semibold text-gray-900\">AI Scheduling Assistant Says:<\/h3>\r\n                <div id=\"loader\" class=\"flex justify-center items-center my-4 hidden\">\r\n                    <div class=\"loader\"><\/div>\r\n                <\/div>\r\n                <div id=\"gemini-output\" class=\"mt-2 p-4 bg-gray-50 rounded-lg whitespace-pre-wrap text-gray-700\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <script type=\"module\">\r\n        \/\/ --- Firebase SDK Imports ---\r\n        import { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.1\/firebase-app.js\";\r\n        import { getAuth, signInAnonymously } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.1\/firebase-auth.js\";\r\n        import { getFirestore, collection, addDoc, onSnapshot, query, orderBy } from \"https:\/\/www.gstatic.com\/firebasejs\/11.6.1\/firebase-firestore.js\";\r\n\r\n        \/\/ --- DATA AND STATE ---\r\n        let submissions = [];\r\n        let db;\r\n        let auth;\r\n\r\n        \/\/ --- DOM ELEMENTS ---\r\n        const form = document.getElementById('availability-form');\r\n        const surveyContainer = document.getElementById('survey-container');\r\n        const successMessage = document.getElementById('success-message');\r\n        const adminPanel = document.getElementById('admin-panel');\r\n        const submissionsList = document.getElementById('submissions-list');\r\n        const geminiButton = document.getElementById('gemini-button');\r\n        const geminiOutputContainer = document.getElementById('gemini-output-container');\r\n        const geminiOutput = document.getElementById('gemini-output');\r\n        const loader = document.getElementById('loader');\r\n        const timeSlotsBody = document.getElementById('time-slots-body');\r\n        const adminLoginContainer = document.getElementById('admin-login-container');\r\n        const adminLoginButton = document.getElementById('admin-login-button');\r\n        const selectAllCheckbox = document.getElementById('select-all-checkbox');\r\n\r\n        \/\/ --- GEMINI API CALL FUNCTION ---\r\n        async function callGeminiAPI(prompt) {\r\n            const apiKey = \"AIzaSyDd8tiMGS33mCB7DJa4ethYZE0q4cT-rA4\"; \r\n\r\n            if (apiKey === \"YOUR_GOOGLE_AI_API_KEY_HERE\") {\r\n                return \"Error: Please replace 'YOUR_GOOGLE_AI_API_KEY_HERE' with your actual Google AI API key in the code.\";\r\n            }\r\n\r\n            const apiUrl = `https:\/\/generativelanguage.googleapis.com\/v1beta\/models\/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;\r\n            \r\n            const systemPrompt = `You are an expert scheduling assistant for a professor. Your task is to create a one-on-one meeting schedule based on student availability.\r\n\r\n**Goal:** Assign each selected student a unique, exclusive **one-hour** meeting slot.\r\n\r\n**Input:** A list of students and their available 30-minute time slots.\r\n\r\n**Instructions:**\r\n1.  **Analyze Availability:** For each student, find two consecutive 30-minute slots to create a one-hour meeting block.\r\n2.  **Create a Schedule:** Assign a unique one-hour slot to each student. **No two students can have overlapping meeting times.**\r\n3.  **Handle Conflicts:** If it's impossible to schedule everyone for a full hour without conflicts, schedule as many as you can and clearly list the students who could not be scheduled.\r\n4.  **Format the Output:**\r\n    * Present the final schedule in a clear Markdown table with columns for \"Student Name,\" \"Day,\" and \"Meeting Time.\"\r\n    * After the table, provide a section with individually drafted emails for each scheduled student, confirming their specific meeting time. Use placeholders like [Your Name].\r\n    * If there are unscheduled students, list them clearly under a \"Could Not Schedule\" heading.`;\r\n\r\n            const payload = {\r\n                contents: [{ parts: [{ text: prompt }] }],\r\n                systemInstruction: {\r\n                    parts: [{ text: systemPrompt }]\r\n                },\r\n            };\r\n\r\n            let response;\r\n            let retries = 3;\r\n            let delay = 1000;\r\n\r\n            while (retries > 0) {\r\n                try {\r\n                    response = await fetch(apiUrl, {\r\n                        method: 'POST',\r\n                        headers: { 'Content-Type': 'application\/json' },\r\n                        body: JSON.stringify(payload)\r\n                    });\r\n\r\n                    if (response.ok) {\r\n                        const result = await response.json();\r\n                        if (result.candidates && result.candidates[0].content?.parts?.[0]?.text) {\r\n                            return result.candidates[0].content.parts[0].text;\r\n                        } else {\r\n                           throw new Error(\"Invalid response structure from API.\");\r\n                        }\r\n                    } else {\r\n                        throw new Error(`API request failed with status: ${response.status}`);\r\n                    }\r\n                } catch (error) {\r\n                    console.error(`Attempt failed: ${error.message}`);\r\n                    retries--;\r\n                    if (retries === 0) {\r\n                        return `Error: Could not connect to the AI assistant after several attempts. Please check the console for details.`;\r\n                    }\r\n                    await new Promise(res => setTimeout(res, delay));\r\n                    delay *= 2;\r\n                }\r\n            }\r\n        }\r\n\r\n        \/\/ --- FIRESTORE FUNCTIONS ---\r\n        function listenForSubmissions() {\r\n            const submissionsCol = collection(db, `availability-submissions`);\r\n            const q = query(submissionsCol, orderBy('timestamp', 'desc'));\r\n\r\n            onSnapshot(q, (snapshot) => {\r\n                submissions = [];\r\n                snapshot.forEach((doc) => {\r\n                    submissions.push({ id: doc.id, ...doc.data() });\r\n                });\r\n                if (!adminPanel.classList.contains('hidden')) {\r\n                    updateSubmissionsDisplay();\r\n                }\r\n            }, (error) => {\r\n                console.error(\"Error listening for submissions:\", error);\r\n                if (error.code === 'permission-denied') {\r\n                    const projectId = \"iip-scheduler\";\r\n                    const rulesUrl = `https:\/\/console.firebase.google.com\/project\/${projectId}\/firestore\/rules`;\r\n                    const errorMessage = `\r\n                        <div class=\"w-full max-w-3xl mx-auto bg-white p-8 rounded-xl shadow-lg mt-10\">\r\n                            <h2 class=\"text-2xl font-bold text-red-600 mb-4\">Connection Error: Action Required<\/h2>\r\n                            <p class=\"text-gray-700 mb-4\">The app can't retrieve the submissions list because your <strong>Firestore Security Rules<\/strong> are too restrictive.<\/p>\r\n                            <p class=\"text-gray-800 font-semibold mb-4\">Please follow these steps to fix this:<\/p>\r\n                            <ol class=\"text-left list-decimal list-inside space-y-3 bg-red-50 p-6 rounded-lg border border-red-200\">\r\n                                <li>\r\n                                    Click this direct link to open the Firestore Rules editor in your Firebase Console:<br>\r\n                                    <a href=\"${rulesUrl}\" target=\"_blank\" class=\"text-indigo-600 underline font-semibold break-all\">${rulesUrl}<\/a>\r\n                                <\/li>\r\n                                <li>Delete the existing rules and replace them with the following code:<\/li>\r\n                                <li class=\"bg-gray-800 text-white font-mono text-xs p-4 rounded-md overflow-x-auto\">\r\n<pre><code>rules_version = '2';\r\nservice cloud.firestore {\r\n  match \/databases\/{database}\/documents {\r\n    match \/availability-submissions\/{docId} {\r\n      allow read: if request.auth != null;\r\n      allow create: if true;\r\n    }\r\n  }\r\n}<\/code><\/pre>\r\n                                <\/li>\r\n                                <li>Click the <strong>Publish<\/strong> button at the top of the editor.<\/li>\r\n                            <\/ol>\r\n                            <p class=\"mt-6 text-gray-600\">After publishing the new rules, please <strong>refresh this page<\/strong>.<\/p>\r\n                        <\/div>\r\n                    `;\r\n                    document.body.innerHTML = errorMessage;\r\n                }\r\n            });\r\n        }\r\n\r\n        \/\/ --- EVENT HANDLERS ---\r\n        form.addEventListener('submit', async function(event) {\r\n            event.preventDefault();\r\n            \r\n            const studentName = document.getElementById('studentName').value;\r\n            const studentEmail = document.getElementById('studentEmail').value;\r\n            const selectedTimes = Array.from(document.querySelectorAll('input[name=\"availability\"]:checked'))\r\n                                      .map(cb => cb.value);\r\n\r\n            if (selectedTimes.length === 0) {\r\n                alert('Please select at least one time slot.');\r\n                return;\r\n            }\r\n\r\n            const newSubmission = { \r\n                name: studentName, \r\n                email: studentEmail, \r\n                times: selectedTimes,\r\n                timestamp: new Date().getTime()\r\n            };\r\n\r\n            try {\r\n                const submissionsCol = collection(db, `availability-submissions`);\r\n                await addDoc(submissionsCol, newSubmission);\r\n                \r\n                surveyContainer.classList.add('hidden');\r\n                successMessage.classList.remove('hidden');\r\n                adminLoginContainer.classList.add('hidden');\r\n\r\n            } catch (error) {\r\n                console.error(\"Error adding document: \", error);\r\n                alert(\"There was an error submitting your availability. Please try again.\");\r\n            }\r\n        });\r\n\r\n        geminiButton.addEventListener('click', async () => {\r\n            const selectedCheckboxes = document.querySelectorAll('.student-checkbox:checked');\r\n            \r\n            if (selectedCheckboxes.length === 0) {\r\n                alert(\"Please select at least one student to include in the scheduling analysis.\");\r\n                return;\r\n            }\r\n            \r\n            const selectedIds = Array.from(selectedCheckboxes).map(cb => cb.dataset.id);\r\n            const selectedSubmissions = submissions.filter(sub => selectedIds.includes(sub.id));\r\n\r\n            geminiOutputContainer.classList.remove('hidden');\r\n            loader.classList.remove('hidden');\r\n            geminiOutput.classList.add('hidden');\r\n            geminiButton.disabled = true;\r\n\r\n            const formattedSubmissions = selectedSubmissions.map(sub => \r\n                `${sub.name} (${sub.email}): ${sub.times.join(', ')}`\r\n            ).join('\\n');\r\n            \r\n            const prompt = `Here are the selected student submissions:\\n${formattedSubmissions}`;\r\n            \r\n            const result = await callGeminiAPI(prompt);\r\n            \r\n            geminiOutput.textContent = result;\r\n            loader.classList.add('hidden');\r\n            geminiOutput.classList.remove('hidden');\r\n            geminiButton.disabled = false;\r\n        });\r\n\r\n        adminLoginButton.addEventListener('click', () => {\r\n            const adminPassword = \"prof123\";\r\n            const enteredPassword = prompt(\"Please enter the admin password to view submissions:\");\r\n\r\n            if (enteredPassword === adminPassword) {\r\n                adminPanel.classList.remove('hidden');\r\n                updateSubmissionsDisplay();\r\n                adminLoginContainer.style.display = 'none';\r\n            } else if (enteredPassword !== null) {\r\n                console.log(\"Incorrect password attempt.\");\r\n            }\r\n        });\r\n\r\n        selectAllCheckbox.addEventListener('change', (event) => {\r\n            const checkboxes = document.querySelectorAll('.student-checkbox');\r\n            checkboxes.forEach(checkbox => {\r\n                checkbox.checked = event.target.checked;\r\n            });\r\n        });\r\n\r\n        \/\/ --- UI UPDATE FUNCTIONS ---\r\n        function updateSubmissionsDisplay() {\r\n            if (submissions.length === 0) {\r\n                submissionsList.innerHTML = '<p class=\"text-gray-500\">No submissions yet.<\/p>';\r\n                return;\r\n            }\r\n\r\n            submissionsList.innerHTML = submissions.map(sub => `\r\n                <div class=\"p-3 bg-gray-50 rounded-md border border-gray-200 flex items-center\">\r\n                    <input type=\"checkbox\" class=\"student-checkbox h-4 w-4 text-indigo-600 border-gray-300 rounded custom-focus\" data-id=\"${sub.id}\">\r\n                    <div class=\"ml-4 flex-1\">\r\n                        <p class=\"font-semibold text-gray-800\">${sub.name}<\/p>\r\n                        <p class=\"text-sm text-gray-500\">${sub.email}<\/p>\r\n                        <p class=\"text-sm text-gray-600 mt-1\">${sub.times.join(', ')}<\/p>\r\n                    <\/div>\r\n                <\/div>\r\n            `).join('');\r\n        }\r\n        \r\n        function generateTimeSlots() {\r\n            const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\r\n            let html = '';\r\n            let currentHour = 15;\r\n            let currentMinute = 30;\r\n\r\n            while (currentHour < 21) {\r\n                const startHour = currentHour;\r\n                const startMinute = currentMinute;\r\n                let endHour = startHour;\r\n                let endMinute = startMinute + 30;\r\n                if (endMinute >= 60) {\r\n                    endHour++;\r\n                    endMinute -= 60;\r\n                }\r\n                const formatTime = (h, m) => {\r\n                    const ampm = h >= 12 ? 'PM' : 'AM';\r\n                    const displayHour = h > 12 ? h - 12 : (h === 0 ? 12 : h);\r\n                    const displayMinute = m.toString().padStart(2, '0');\r\n                    return `${displayHour}:${displayMinute} ${ampm}`;\r\n                };\r\n                const timeString = `${formatTime(startHour, startMinute)} - ${formatTime(endHour, endMinute)}`;\r\n                const valueString = `${formatTime(startHour, startMinute)}-${formatTime(endHour, endMinute)}`;\r\n                const isLastRow = (endHour === 21 && endMinute === 0);\r\n                const rowClass = isLastRow ? 'bg-white' : 'bg-white border-b border-gray-200';\r\n                const thClass = isLastRow ? 'px-4 py-4 font-medium text-gray-900 whitespace-nowrap rounded-bl-lg' : 'px-4 py-4 font-medium text-gray-900 whitespace-nowrap';\r\n                html += `<tr class=\"${rowClass}\"><th scope=\"row\" class=\"${thClass}\">${timeString}<\/th>`;\r\n                days.forEach((day, index) => {\r\n                    const value = `${day} ${valueString}`;\r\n                    let tdClass = 'p-4 text-center';\r\n                    if (isLastRow && index === days.length - 1) {\r\n                        tdClass += ' rounded-br-lg';\r\n                    }\r\n                    html += `<td class=\"${tdClass}\"><input type=\"checkbox\" name=\"availability\" value=\"${value}\" class=\"w-5 h-5 text-indigo-600 border-gray-300 rounded focus:ring-indigo-500 custom-focus\"><\/td>`;\r\n                });\r\n                html += `<\/tr>`;\r\n                currentMinute += 30;\r\n                if (currentMinute >= 60) {\r\n                    currentHour++;\r\n                    currentMinute -= 60;\r\n                }\r\n            }\r\n            timeSlotsBody.innerHTML = html;\r\n        }\r\n\r\n        \/\/ --- INITIALIZATION ---\r\n        async function initializeAppAndAuth() {\r\n            try {\r\n                const firebaseConfig = {\r\n                    apiKey: \"AIzaSyD4oU8HQYE19mrTk8RFpdLteB8zsJ3CAoY\",\r\n                    authDomain: \"iip-scheduler.firebaseapp.com\",\r\n                    projectId: \"iip-scheduler\",\r\n                    storageBucket: \"iip-scheduler.appspot.com\",\r\n                    messagingSenderId: \"182847402519\",\r\n                    appId: \"1:182847402519:web:5673b55f0c38f76d4ce252\"\r\n                };\r\n\r\n                const app = initializeApp(firebaseConfig);\r\n                db = getFirestore(app);\r\n                auth = getAuth(app);\r\n                \r\n                await signInAnonymously(auth);\r\n                console.log(\"Signed in anonymously.\");\r\n                listenForSubmissions(); \/\/ Start listening for data once authenticated\r\n\r\n            } catch (error) {\r\n                console.error(\"Firebase initialization error:\", error);\r\n                let errorMessage = '<div class=\"text-center p-8 text-red-600\">Could not connect to the scheduling service. Please check your Firebase configuration and try again later.<\/div>';\r\n                \r\n                if (error.code === 'auth\/configuration-not-found') {\r\n                    const projectId = \"iip-scheduler\";\r\n                    const authUrl = `https:\/\/console.firebase.google.com\/project\/${projectId}\/authentication\/providers`;\r\n                    errorMessage = `\r\n                        <div class=\"w-full max-w-3xl mx-auto bg-white p-8 rounded-xl shadow-lg mt-10\">\r\n                            <h2 class=\"text-2xl font-bold text-red-600 mb-4\">Connection Error: Action Required<\/h2>\r\n                            <p class=\"text-gray-700 mb-4\">The app can't connect because <strong>Anonymous Sign-In<\/strong> is not enabled in your Firebase project. This is a required step.<\/p>\r\n                            <p class=\"text-gray-800 font-semibold mb-4\">Please follow these steps to fix this:<\/p>\r\n                            <ol class=\"text-left list-decimal list-inside space-y-3 bg-red-50 p-6 rounded-lg border border-red-200\">\r\n                                <li>\r\n                                    Click this direct link to open the correct page in your Firebase Console:<br>\r\n                                    <a href=\"${authUrl}\" target=\"_blank\" class=\"text-indigo-600 underline font-semibold break-all\">${authUrl}<\/a>\r\n                                <\/li>\r\n                                <li>In the list of providers, find <strong>Anonymous<\/strong>.<\/li>\r\n                                <li>Click the pencil icon <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-4 w-4 inline-block\" viewbox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z\" \/><path fill-rule=\"evenodd\" d=\"M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z\" clip-rule=\"evenodd\" \/><\/svg> to edit it.<\/li>\r\n                                <li><strong>Enable<\/strong> the toggle switch and click <strong>Save<\/strong>.<\/li>\r\n                            <\/ol>\r\n                            <p class=\"mt-6 text-gray-600\">After enabling it, please <strong>refresh this page<\/strong>.<\/p>\r\n                        <\/div>\r\n                    `;\r\n                }\r\n                document.body.innerHTML = errorMessage;\r\n            }\r\n        }\r\n\r\n        document.addEventListener('DOMContentLoaded', () => {\r\n            generateTimeSlots();\r\n            initializeAppAndAuth();\r\n        });\r\n    <\/script>\r\n<\/body>\r\n<\/html>\r\n\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1"}],"version-history":[{"count":4,"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":23,"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions\/23"}],"wp:attachment":[{"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/soundiip.host.dartmouth.edu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}