Files
zydi-user/login.html
T
2025-01-12 05:13:22 +00:00

434 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>黑盒智能开发者平台</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Arial', sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
}
.header {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.container {
background-color: rgba(255, 255, 255, 0.9);
border-radius: 15px;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
position: relative;
overflow: hidden;
width: 80%;
max-width: 1200px; /* Set a maximum width */
min-height: 900px; /* Use a fixed minimum height */
margin: 20px auto; /* Add some margin */
}
.form-container {
position: absolute;
top: 0;
height: 100%;
transition: all 0.6s ease-in-out;
}
.sign-in-container {
left: 0;
width: 50%;
z-index: 2;
}
.sign-up-container {
left: 0;
width: 50%;
opacity: 0;
z-index: 1;
}
.container.right-panel-active .sign-in-container {
transform: translateX(100%);
}
.container.right-panel-active .sign-up-container {
transform: translateX(100%);
opacity: 1;
z-index: 5;
}
form {
background-color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 50px;
height: 100%;
text-align: center;
}
h1 {
font-weight: bold;
margin-bottom: 30px;
font-size: 3.5em;
}
p {
font-size: 1.2em;
margin-bottom: 30px; /* Increase bottom margin */
}
input {
background-color: #eee;
border: none;
padding: 12px 15px;
margin: 15px 0;
width: 100%;
border-radius: 10px;
}
button {
border-radius: 50px;
border: 1px solid #667eea;
background-color: #667eea;
color: #FFFFFF;
font-size: 20px;
font-weight: bold;
padding: 12px 45px;
letter-spacing: 3px;
text-transform: uppercase;
transition: transform 80ms ease-in;
margin-bottom: 50px;
}
button:active {
transform: scale(0.95);
}
button:focus {
outline: none;
}
button.ghost {
background-color: transparent;
border-color: #FFFFFF;
}
.social-container {
margin: 20px 0;
}
.social-container a {
border: 1px solid #DDDDDD;
border-radius: 50%;
display: inline-flex;
justify-content: center;
align-items: center;
margin: 0 5px;
height: 40px;
width: 40px;
}
.overlay-container {
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
overflow: hidden;
transition: transform 0.6s ease-in-out;
z-index: 100;
}
.container.right-panel-active .overlay-container{
transform: translateX(-100%);
}
.overlay {
background: #667eea;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background-repeat: no-repeat;
background-size: cover;
background-position: 0 0;
color: #FFFFFF;
position: relative;
left: -100%;
height: 100%;
width: 200%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
}
.container.right-panel-active .overlay {
transform: translateX(50%);
}
.overlay-panel {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 40px;
text-align: center;
top: 0;
height: 100%;
width: 50%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
}
.overlay-left {
transform: translateX(-20%);
}
.container.right-panel-active .overlay-left {
transform: translateX(0);
}
.overlay-right {
right: 0;
transform: translateX(0);
}
.container.right-panel-active .overlay-right {
transform: translateX(20%);
}
@media (max-width: 768px) {
.container {
width: 90%;
min-height: 90vh;
}
form {
padding: 0 20px;
}
.overlay-panel {
padding: 0 20px;
}
.title {
font-size: 2em;
}
.logo {
font-size: 2.5em;
}
}
</style>
</head>
<body>
<div class="container" id="container">
<div class="form-container sign-up-container">
<form id="signupForm">
<h1>Create Account</h1>
<!-- <div class="social-container">
<a href="#" class="social"><i class="fab fa-google"></i></a>
<a href="#" class="social"><i class="fab fa-github"></i></a>
</div> -->
<span>use your email for registration</span>
<input type="text" placeholder="Username" id="signupUsername" required />
<input type="password" placeholder="Password" id="signupPassword" required />
<div class="password-rules">
Password must be at least 8 characters long and include uppercase, lowercase, digit, and special character (!@#$%^&*?:).
</div>
<input type="email" placeholder="Email" id="signupEmail" required />
<input type="tel" placeholder="Phone" id="signupPhone" required />
<button type="submit">REGISTER</button>
</form>
</div>
<div class="form-container sign-in-container">
<form id="signinForm">
<h1>Sign in</h1>
<!-- <div class="social-container">
<a href="#" class="social"><i class="fab fa-google"></i></a>
<a href="#" class="social"><i class="fab fa-github"></i></a>
</div> -->
<span>use your account</span>
<input type="text" placeholder="Username" id="signinUsername" required />
<input type="password" placeholder="Password" id="signinPassword" required />
<a href="#">Forgot your password?</a>
<button type="submit">Sign In</button>
</form>
</div>
<div class="overlay-container">
<div class="overlay">
<div class="overlay-panel overlay-left">
<h1>Welcome Back!</h1>
<p>To keep connected with us please login with your personal info</p>
<button class="ghost" id="signIn">Sign In</button>
</div>
<div class="overlay-panel overlay-right">
<h1>Hello, Friend!</h1>
<p>Start your journey with us</p>
<button class="ghost" id="signUp">Sign Up</button>
</div>
</div>
</div>
</div>
<script>
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('container');
signUpButton.addEventListener('click', () => {
container.classList.add("right-panel-active");
});
signInButton.addEventListener('click', () => {
container.classList.remove("right-panel-active");
});
const API_URL = 'https://user.obscura.work/user';
// 页面加载时检查登录状态
document.addEventListener('DOMContentLoaded', checkLoginStatus);
function checkLoginStatus() {
const token = localStorage.getItem('access_token');
if (token) {
validateToken(token);
} else {
showLoginForm();
}
}
async function validateToken(token) {
try {
const response = await fetch(`${API_URL}/me`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (response.ok) {
const data = await response.json();
console.log('用户信息:', data);
redirectToDashboard();
} else {
throw new Error('无效的token');
}
} catch (error) {
console.error('错误:', error);
logout();
}
}
function showLoginForm() {
container.classList.remove("right-panel-active");
}
function redirectToDashboard(token) {
window.location.href = `https://user.obscura.work/platform.html`;
}
async function logout() {
const token = localStorage.getItem('access_token');
if (token) {
try {
await fetch(`${API_URL}/logout`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
},
});
} catch (error) {
console.error('登出时发生错误:', error);
}
}
localStorage.removeItem('access_token');
showLoginForm();
}
// 注册
document.getElementById('signupForm').addEventListener('submit', async (e) => {
e.preventDefault();
const username = document.getElementById('signupUsername').value;
const password = document.getElementById('signupPassword').value;
const email = document.getElementById('signupEmail').value;
const phoneNumber = document.getElementById('signupPhone').value;
try {
const response = await fetch(`${API_URL}/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: username,
email: email,
phone_number: phoneNumber,
password: password
}),
});
const data = await response.json();
if (response.ok) {
alert(data.message);
showLoginForm();
} else {
let errorMessage = '注册失败: ';
if (typeof data.detail === 'object') {
for (let key in data.detail) {
errorMessage += `${key}: ${data.detail[key].join(', ')}\n`;
}
} else {
errorMessage += data.detail || '发生未知错误';
}
alert(errorMessage);
}
} catch (error) {
console.error('错误:', error);
alert('发生错误,请重试。');
}
});
// 登录
document.getElementById('signinForm').addEventListener('submit', async (e) => {
e.preventDefault();
const username = document.getElementById('signinUsername').value;
const password = document.getElementById('signinPassword').value;
try {
const response = await fetch(`${API_URL}/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`,
});
const data = await response.json();
if (response.ok) {
localStorage.setItem('access_token', data.access_token);
alert('登录成功');
redirectToDashboard(data.access_token);
} else {
alert(data.detail || '登录失败');
}
} catch (error) {
console.error('错误:', error);
alert('发生错误,请重试。');
}
});
// 处理需要认证的API请求
async function makeAuthenticatedRequest(url, options = {}) {
const token = localStorage.getItem('access_token');
if (!token) {
throw new Error('未找到token');
}
const headers = new Headers(options.headers || {});
headers.append('Authorization', `Bearer ${token}`);
const response = await fetch(url, { ...options, headers });
if (response.status === 401) {
logout();
throw new Error('未授权');
}
return response;
}
</script>
</body>
</html>