start-suite / templates /auth.html
ayush-thakur02's picture
Upload 8 files
b07efa0 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Start Suite - Login</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='icon.png') }}">
<style>
@import url('https://fonts.googleapis.com/css2?family=Audiowide&family=Lexend:wght@100..900&display=swap');
* {
margin: 0;
padding: 0;
font-family: "Lexend", sans-serif;
}
body {
font-family: 'Roboto', sans-serif;
background: #4285f4;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: #333;
overflow: hidden;
position: relative;
}
/* Rain Effect Styles */
.rain-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
.rain-drop {
position: absolute;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.2));
border-radius: 50px;
animation: fall linear infinite;
opacity: 0.7;
}
@keyframes fall {
0% {
transform: translateY(-20px);
opacity: 1;
}
100% {
transform: translateY(100vh);
opacity: 0.3;
}
}
.auth-container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 40px;
width: 100%;
max-width: 400px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
position: relative;
z-index: 2;
}
.auth-header {
text-align: center;
margin-bottom: 30px;
}
.auth-title {
font-size: 2rem;
font-weight: 700;
color: #333;
margin-bottom: 10px;
}
.auth-subtitle {
color: #666;
font-size: 1rem;
}
.auth-form {
display: flex;
flex-direction: column;
gap: 20px;
}
.form-group {
position: relative;
}
.form-input {
width: calc(100% - 42px);
padding: 15px 20px;
border: 2px solid #e1e5e9;
border-radius: 10px;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-input::placeholder {
color: #999;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 10px;
margin-top: 5px;
}
.checkbox-input {
width: 18px;
height: 18px;
accent-color: #667eea;
cursor: pointer;
}
.checkbox-label {
font-size: 0.9rem;
color: #666;
cursor: pointer;
user-select: none;
}
.auth-btn {
padding: 15px 30px;
border: none;
border-radius: 10px;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
background: #667eea;
color: white;
}
.auth-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
}
.auth-btn:active {
transform: translateY(0);
}
.auth-toggle {
text-align: center;
margin-top: 20px;
}
.auth-toggle a {
color: #667eea;
text-decoration: none;
font-weight: 500;
cursor: pointer;
}
.auth-toggle a:hover {
text-decoration: underline;
}
.error-message {
color: #e74c3c;
font-size: 0.9rem;
margin-top: 10px;
text-align: center;
}
.success-message {
color: #27ae60;
font-size: 0.9rem;
margin-top: 10px;
text-align: center;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<div class="rain-container" id="rainContainer"></div>
<div class="auth-container">
<div class="auth-header">
<h1 class="auth-title">Start Suite</h1>
<p class="auth-subtitle">Your personalized dashboard</p>
</div>
<form class="auth-form" id="loginForm">
<div class="form-group">
<input type="text" class="form-input" id="username" placeholder="Username" required>
</div>
<div class="form-group">
<input type="password" class="form-input" id="password" placeholder="Password" required>
</div>
<div class="form-group" id="rememberMeGroup">
<div class="checkbox-group">
<input type="checkbox" class="checkbox-input" id="rememberMe" checked>
<label for="rememberMe" class="checkbox-label">Remember me for 30 days</label>
</div>
</div>
<button type="submit" class="auth-btn" id="authBtn">Login</button>
<div class="error-message hidden" id="errorMessage"></div>
<div class="success-message hidden" id="successMessage"></div>
</form>
<div class="auth-toggle">
<span id="toggleText">Don't have an account? </span>
<a href="#" id="toggleLink">Sign up</a>
</div>
</div>
<script>
let isLoginMode = true;
const form = document.getElementById('loginForm');
const authBtn = document.getElementById('authBtn');
const toggleLink = document.getElementById('toggleLink');
const toggleText = document.getElementById('toggleText');
const errorMessage = document.getElementById('errorMessage');
const successMessage = document.getElementById('successMessage');
const rememberMeGroup = document.getElementById('rememberMeGroup');
const rememberMeCheckbox = document.getElementById('rememberMe');
function showError(message) {
errorMessage.textContent = message;
errorMessage.classList.remove('hidden');
successMessage.classList.add('hidden');
}
function showSuccess(message) {
successMessage.textContent = message;
successMessage.classList.remove('hidden');
errorMessage.classList.add('hidden');
}
function hideMessages() {
errorMessage.classList.add('hidden');
successMessage.classList.add('hidden');
}
toggleLink.addEventListener('click', (e) => {
e.preventDefault();
isLoginMode = !isLoginMode;
if (isLoginMode) {
authBtn.textContent = 'Login';
toggleText.textContent = "Don't have an account? ";
toggleLink.textContent = 'Sign up';
rememberMeGroup.style.display = 'block'; // Show remember me for login
} else {
authBtn.textContent = 'Sign Up';
toggleText.textContent = 'Already have an account? ';
toggleLink.textContent = 'Login';
rememberMeGroup.style.display = 'none'; // Hide remember me for signup
}
hideMessages();
});
form.addEventListener('submit', async (e) => {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const rememberMe = rememberMeCheckbox.checked;
if (!username || !password) {
showError('Please fill in all fields');
return;
}
const endpoint = isLoginMode ? '/login' : '/register';
const requestBody = { username, password };
// Add rememberMe flag for login requests
if (isLoginMode) {
requestBody.rememberMe = rememberMe;
}
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody)
});
const data = await response.json();
if (response.ok) {
showSuccess(data.message);
setTimeout(() => {
window.location.href = '/';
}, 1000);
} else {
showError(data.error);
}
} catch (error) {
showError('An error occurred. Please try again.');
}
});
// Rain Effect
class RainEffect {
constructor() {
this.rainContainer = document.getElementById('rainContainer');
this.rainDrops = [];
this.maxDrops = 100;
this.init();
}
init() {
this.createRain();
this.animateRain();
}
createRain() {
for (let i = 0; i < this.maxDrops; i++) {
this.createRainDrop();
}
}
createRainDrop() {
const drop = document.createElement('div');
drop.className = 'rain-drop';
// Random horizontal position
const x = Math.random() * window.innerWidth;
// Random size variation
const size = Math.random() * 0.8 + 0.2;
drop.style.width = `${2 * size}px`;
drop.style.height = `${20 * size}px`;
// Random speed (duration)
const duration = Math.random() * 2 + 1; // 1-3 seconds
drop.style.animationDuration = `${duration}s`;
// Random delay
const delay = Math.random() * 2;
drop.style.animationDelay = `${delay}s`;
// Position the drop
drop.style.left = `${x}px`;
drop.style.top = '-20px';
this.rainContainer.appendChild(drop);
this.rainDrops.push(drop);
}
animateRain() {
// Clean up and recreate drops periodically
setInterval(() => {
this.rainDrops.forEach(drop => {
const rect = drop.getBoundingClientRect();
if (rect.top > window.innerHeight) {
// Reset the drop to the top with new random position
drop.style.left = `${Math.random() * window.innerWidth}px`;
drop.style.top = '-20px';
// Randomize properties again
const size = Math.random() * 0.8 + 0.2;
drop.style.width = `${2 * size}px`;
drop.style.height = `${20 * size}px`;
const duration = Math.random() * 2 + 1;
drop.style.animationDuration = `${duration}s`;
}
});
}, 100);
}
}
// Initialize rain effect when the page loads
new RainEffect();
</script>
</body>
</html>