DavidL72Code/UMB_Sustainable_Chatbot
0
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>SSL Research Assistant</title>7 <link rel="preconnect" href="https://fonts.googleapis.com">8 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>9 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Lora:wght@600;700&display=swap" rel="stylesheet">10 <link rel="icon" href="https://www.umb.edu/media/umassboston/site-assets/images/favicons/favicon_48x48.svg" type="image/svg+xml">11 <link rel="icon" href="https://www.umb.edu/media/umassboston/site-assets/images/favicons/favicon_96x96.png" type="image/png">12 <link rel="stylesheet" href="/static/styles.css?v=bea1aaa">13 <script>14 // Backend URL — set this to your Hugging Face Space.15 // Vercel: override at deploy time by editing this line or injecting via16 // a build step. Leave blank ("") to call the same origin as the page.17 window.API_BASE = ""; // same-origin: /api is proxied by vercel.json18 </script>19</head>20<body>21 22 <header class="site-header">23 <div class="header-inner">24 <img25 src="/static/umb-logo.svg"26 alt="UMass Boston"27 class="header-umb-logo"28 >29 <div class="header-logo">30 <span class="header-logo-name">Sustainable Solutions Lab</span>31 <span class="header-logo-tagline">Pursuing Climate Justice</span>32 </div>33 <nav class="header-links" aria-label="Header navigation">34 <a id="dashboardLink" href="#" class="header-ssl-link">Dashboard</a>35 <a href="https://www.umb.edu/ssl/" target="_blank" rel="noreferrer" class="header-ssl-link">Visit SSL</a>36 <span id="accountArea" class="account-area" hidden>37 <span id="accountEmail" class="account-email"></span>38 <button type="button" id="signInButton" class="header-ssl-link account-button">Sign in</button>39 <button type="button" id="signOutButton" class="header-ssl-link account-button" hidden>Sign out</button>40 </span>41 </nav>42 </div>43 </header>44 45 <main class="shell">46 <section class="hero">47 <h1>Research Assistant</h1>48 <p class="hero-copy">49 Ask questions about the Sustainable Solutions Lab's research, projects, publications, staff, and initiatives.50 Responses are drawn directly from SSL source documents.51 </p>52 </section>53 54 <div class="chat-layout">55 56 <aside class="sidebar" aria-label="Recent questions">57 <div class="sidebar-header">58 <span>Recent Questions</span>59 <button type="button" id="newChatButton" class="sidebar-new" title="Start a new chat">+ New</button>60 </div>61 <ul class="sidebar-list" id="sidebarList">62 <li class="sidebar-empty">Your questions will appear here.</li>63 </ul>64 <p class="sidebar-note" id="sidebarNote" hidden>65 Sign in to keep your chat history. Without an account nothing you ask is saved.66 </p>67 </aside>68 69 <section class="chat-card" aria-label="Chat interface">70 <div class="chat-card-header">71 <span class="status-dot" aria-hidden="true"></span>72 <span class="chat-card-title">SSL Research Assistant</span>73 </div>74 75 <div id="chatMessages" class="chat-messages" role="log" aria-live="polite" aria-label="Conversation">76 <article class="message assistant">77 <div class="message-label">78 <span class="assistant-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></span>79 SSL Assistant80 </div>81 <div class="message-bubble"><p>Hello. I'm the SSL Research Assistant, here to help you explore the work of the Sustainable Solutions Lab at UMass Boston.</p><p>I can answer questions about our research projects, publications, staff, initiatives, funding, and community partnerships. My responses are drawn directly from SSL source documents, so I work best with specific questions about SSL's work and focus areas.</p><p>If you need to reach the lab directly, you can contact us at <a href="mailto:ssl@umb.edu" class="bubble-link">ssl@umb.edu</a> or visit <a href="https://www.umb.edu/ssl/" target="_blank" rel="noreferrer" class="bubble-link">umb.edu/ssl</a>. How can I help you?</p></div>82 </article>83 84 <div id="suggestedQuestions" class="suggested-questions">85 <p class="suggested-label">Try asking</p>86 <div class="suggested-list">87 <button class="suggested-btn" type="button">What research projects is SSL currently working on?</button>88 <button class="suggested-btn" type="button">Who are the staff members at SSL?</button>89 <button class="suggested-btn" type="button">What publications has SSL produced?</button>90 <button class="suggested-btn" type="button">What does SSL do for climate justice?</button>91 <button class="suggested-btn" type="button">How can I get involved with SSL?</button>92 <button class="suggested-btn" type="button">What funding or grants does SSL receive?</button>93 </div>94 </div>95 </div>96 97 <!-- Only shown when the backend reports it is still loading, which is98 rare: the Space is usually warm. Hidden by default so the common99 case never sees a flash. -->100 <div id="warmingNotice" class="warming-notice" role="status" aria-live="polite" hidden>101 <span class="warming-spinner" aria-hidden="true"></span>102 <span>Warming up — loading SSL documents. This takes a few seconds.</span>103 </div>104 105 <form id="chatForm" class="composer" novalidate>106 <label class="sr-only" for="messageInput">Ask a question</label>107 <input108 id="messageInput"109 name="message"110 type="text"111 placeholder="Ask about SSL research, projects, staff, publications..."112 autocomplete="off"113 required114 >115 <button id="sendButton" type="submit" aria-label="Send message">116 <span class="send-arrow" aria-hidden="true">↑</span>117 </button>118 </form>119 </section>120 121 </div>122 </main>123 124 <footer class="site-footer">125 <a href="mailto:ssl@umb.edu" class="footer-email-btn">Email Us</a>126 <span>127 <a href="https://www.umb.edu/ssl/" target="_blank" rel="noreferrer" class="footer-site-link">Sustainable Solutions Lab</a>128 —129 <a href="https://www.umb.edu/" target="_blank" rel="noreferrer" class="footer-site-link">University of Massachusetts Boston</a>130 </span>131 <span class="footer-credit">Built by Team 1 “RAG's to Riches”</span>132 </footer>133 134 <div class="auth-overlay" id="sessionFullOverlay" hidden>135 <div class="auth-dialog notice-dialog" role="alertdialog" aria-modal="true"136 aria-labelledby="sessionFullTitle" aria-describedby="sessionFullBody">137 <button type="button" class="auth-close" id="sessionFullClose" aria-label="Close">×</button>138 <h2 id="sessionFullTitle">This chat is full</h2>139 <p id="sessionFullBody" class="notice-body">140 You have hit the session message cap please start a new session to continue.141 </p>142 <button type="button" class="auth-submit" id="sessionFullNew">Start a new chat</button>143 </div>144 </div>145 146 <div class="auth-overlay" id="confirmOverlay" hidden>147 <div class="auth-dialog notice-dialog" role="alertdialog" aria-modal="true"148 aria-labelledby="confirmTitle" aria-describedby="confirmBody">149 <button type="button" class="auth-close" id="confirmClose" aria-label="Close">×</button>150 <h2 id="confirmTitle">Confirm your account</h2>151 <p id="confirmBody" class="notice-body">152 Your account has been created. Check your email for a confirmation link153 and open it to activate your account. You need to confirm before you can154 sign in.155 </p>156 <button type="button" class="auth-submit" id="confirmOk">Got it</button>157 </div>158 </div>159 160 <div class="auth-overlay" id="authOverlay" hidden>161 <div class="auth-dialog" role="dialog" aria-modal="true" aria-labelledby="authTitle">162 <button type="button" class="auth-close" id="authClose" aria-label="Close">×</button>163 <h2 id="authTitle">Sign in</h2>164 <p class="auth-blurb" id="authBlurb">165 Signing in saves your chat history so you can pick up where you left off.166 You can keep using the assistant without an account — nothing you167 ask is saved unless you sign in.168 </p>169 <form id="authForm" novalidate>170 <div class="auth-field" id="authEmailField">171 <label for="authEmail">Email</label>172 <input type="email" id="authEmail" autocomplete="email" required>173 </div>174 <div class="auth-field" id="authPasswordField">175 <label for="authPassword">Password</label>176 <input type="password" id="authPassword" autocomplete="current-password" required minlength="8">177 </div>178 <p class="auth-error" id="authError" hidden></p>179 <button type="submit" class="auth-submit" id="authSubmit">Sign in</button>180 <p class="auth-forgot"><button type="button" id="forgotLink">Forgot password?</button></p>181 </form>182 <p class="auth-switch">183 <span id="authSwitchText">New here?</span>184 <button type="button" id="authSwitchButton">Create an account</button>185 </p>186 </div>187 </div>188 189 <template id="messageTemplate">190 <article class="message">191 <div class="message-label"></div>192 <div class="message-bubble"></div>193 </article>194 </template>195 196 <template id="loadingTemplate">197 <article class="message assistant" id="loadingMessage">198 <div class="message-label">199 <span class="assistant-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></span>200 SSL Assistant201 </div>202 <div class="message-bubble loading-bubble" aria-live="polite" aria-label="Assistant is thinking">203 <span class="dot"></span>204 <span class="dot"></span>205 <span class="dot"></span>206 </div>207 </article>208 </template>209 210 <template id="suggestionsTemplate">211 <div class="suggestion-chips" role="navigation" aria-label="Suggested follow-up questions">212 <p class="suggestion-chips-label">You might also want to ask</p>213 <div class="suggestion-chips-list"></div>214 </div>215 </template>216 217 <script>218 const dashboardBase = (window.API_BASE || "").replace(/\/+$/, "");219 const dashboardHref = new URL("/dashboard.html", window.location.origin);220 if (dashboardBase) {221 dashboardHref.searchParams.set("api_base", dashboardBase);222 }223 // Open to everyone: the dashboard shows only the caller's own activity —224 // this session's questions from the browser, plus their saved chats if225 // they are signed in. The aggregate staff view stays behind admin auth.226 document.getElementById("dashboardLink").href = dashboardHref.toString();227 </script>228 <script src="/static/app.js?v=bea1aaa"></script>229</body>230</html>231 