PaperMate / frontend /login.html
ntphuc149's picture
feat: add EN/VI language toggle — i18n for all 5 public pages
36042b5
Raw
History Blame
4.87 kB
<!doctype html>
<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 &nbsp;·&nbsp; ACL ARR-style AI Peer Review &nbsp;·&nbsp;
<a href="upload.html" data-i18n="footer.submit">Submit a paper</a>
&nbsp;·&nbsp;
<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>