Spaces:
Running
Running
| <html lang="en" data-theme="light"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>PaperMate — Sign in</title> | |
| <link | |
| rel="stylesheet" | |
| href="https://cdn.jsdelivr.net/npm/remixicon@4.3.0/fonts/remixicon.css" | |
| /> | |
| <link rel="stylesheet" href="css/style.css?v=2" /> | |
| </head> | |
| <body> | |
| <div class="bg-ambient" aria-hidden="true"> | |
| <div class="bg-grid"></div> | |
| </div> | |
| <div class="page-wrap"> | |
| <header> | |
| <div class="container"> | |
| <a href="home.html" class="logo"> | |
| Paper<span class="logo-accent">Mate</span> | |
| </a> | |
| <nav> | |
| <a href="home.html" data-i18n="nav.home">Home</a> | |
| </nav> | |
| </div> | |
| </header> | |
| <main> | |
| <div class="container" style="max-width: 460px"> | |
| <div class="hero fade-in"> | |
| <div class="hero-badge"><span class="dot"></span> <span data-i18n="login.kicker">Account</span></div> | |
| <h1 data-i18n="login.h1">Sign in</h1> | |
| <p data-i18n="login.p">Sign in with Google to access your dashboard.</p> | |
| </div> | |
| <div class="card fade-in"> | |
| <div class="kicker"><span class="dot"></span> <span data-i18n="login.continue_kicker">Continue with</span></div> | |
| <div class="rule"></div> | |
| <div class="alert alert-error" id="error-msg"></div> | |
| <button type="button" class="btn btn-primary" id="google-btn"> | |
| <i class="ri-google-fill"></i> <span data-i18n="login.google_btn">Sign in with Google</span> | |
| </button> | |
| <div id="signed-in" style="display: none; margin-top: 16px"> | |
| <div class="alert alert-info" style="display: block"> | |
| <i class="ri-checkbox-circle-line"></i> | |
| Signed in as <strong id="me-email"></strong>. | |
| </div> | |
| <div style="display: flex; gap: 8px; margin-top: 12px"> | |
| <a class="btn btn-outline" id="admin-link" href="admin.html" style="display: none"> | |
| <i class="ri-dashboard-3-line"></i> <span data-i18n="login.admin_dashboard">Admin Dashboard</span> | |
| </a> | |
| <button type="button" class="btn btn-outline" id="signout-btn"> | |
| <i class="ri-logout-box-r-line"></i> <span data-i18n="login.sign_out">Sign out</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <footer> | |
| <div class="container"> | |
| PaperMate · ACL ARR-style AI Peer Review · | |
| <a href="upload.html" data-i18n="footer.submit">Submit a paper</a> | |
| · | |
| <a href="mailto:26ai.phucnt@vinuni.edu.vn" data-i18n="footer.contact">Contact</a> | |
| </div> | |
| </footer> | |
| </div> | |
| <script src="js/i18n.js?v=1"></script> | |
| <script src="js/theme.js?v=3"></script> | |
| <script type="module" src="js/nav-auth.js?v=4"></script> | |
| <script type="module"> | |
| import { signInWithGoogle, getMe, signOut, onAuthStateChange } from "./js/auth.js"; | |
| const errorMsg = document.getElementById("error-msg"); | |
| const googleBtn = document.getElementById("google-btn"); | |
| const signedIn = document.getElementById("signed-in"); | |
| const meEmail = document.getElementById("me-email"); | |
| const adminLink = document.getElementById("admin-link"); | |
| const signoutBtn = document.getElementById("signout-btn"); | |
| function showError(msg) { | |
| errorMsg.textContent = msg; | |
| errorMsg.style.display = "block"; | |
| } | |
| const redirectTo = window.location.href; | |
| googleBtn.addEventListener("click", async () => { | |
| try { | |
| const { error } = await signInWithGoogle(redirectTo); | |
| if (error) showError(error.message); | |
| } catch (e) { | |
| showError(e.message || "Sign-in failed."); | |
| } | |
| }); | |
| signoutBtn.addEventListener("click", async () => { | |
| await signOut(); | |
| window.location.reload(); | |
| }); | |
| // On load (and after the OAuth redirect), reflect the session state. | |
| // Use onAuthStateChange so we catch the SIGNED_IN event fired after | |
| // Supabase parses the #access_token fragment from the OAuth redirect. | |
| (async () => { | |
| try { | |
| await onAuthStateChange(async (event, session) => { | |
| if (event === "SIGNED_IN" && session) { | |
| window.location.replace("home.html"); | |
| } | |
| }); | |
| // Also check immediately in case the session already exists | |
| const me = await getMe(); | |
| if (me) window.location.replace("home.html"); | |
| } catch (e) { | |
| showError(e.message || "Auth not configured."); | |
| } | |
| })(); | |
| </script> | |
| </body> | |
| </html> | |