commit remaining frontend updates
This commit is contained in:
+18
-1
@@ -12,7 +12,7 @@ body {
|
||||
.page { display: none; }
|
||||
.page.active { display: flex; flex-direction: column; }
|
||||
|
||||
#loginPage {
|
||||
#loginPage, #registerPage {
|
||||
min-height: 100vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -68,6 +68,12 @@ body {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
}
|
||||
.btn-secondary {
|
||||
background: transparent;
|
||||
color: #667eea;
|
||||
border: 1px solid #667eea;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.login-error {
|
||||
color: #e74c3c;
|
||||
text-align: center;
|
||||
@@ -76,6 +82,17 @@ body {
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.login-register-link {
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.login-register-link a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 首页 */
|
||||
#homePage {
|
||||
min-height: 100vh;
|
||||
|
||||
+24
-1
@@ -21,10 +21,33 @@
|
||||
<input type="password" id="loginPass" placeholder="请输入密码" autocomplete="current-password">
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="doLogin()">登 录</button>
|
||||
<button class="btn btn-secondary" onclick="showRegisterPage()">注册账号</button>
|
||||
<div class="login-error" id="loginError"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 注册页 -->
|
||||
<div id="registerPage" class="page">
|
||||
<div class="login-box">
|
||||
<h1>注册账号</h1>
|
||||
<div class="form-group">
|
||||
<label>用户名</label>
|
||||
<input type="text" id="registerUser" placeholder="请输入用户名" autocomplete="username">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码</label>
|
||||
<input type="password" id="registerPass" placeholder="请输入密码" autocomplete="new-password">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>确认密码</label>
|
||||
<input type="password" id="registerPassConfirm" placeholder="请再次输入密码" autocomplete="new-password">
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="doRegister()">注 册</button>
|
||||
<button class="btn btn-secondary" onclick="showLoginPage()">返回登录</button>
|
||||
<div class="login-error" id="registerError"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 首页 -->
|
||||
<div id="homePage" class="page">
|
||||
<div class="home-header">
|
||||
@@ -457,7 +480,7 @@
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<script src="js/app.js?v=20260224"></script>
|
||||
<script src="js/auth.js"></script>
|
||||
<script src="js/auth.js?v=20260428b"></script>
|
||||
<script src="js/autocomplete.js"></script>
|
||||
<script src="js/month-picker.js"></script>
|
||||
<script src="js/stats.js?v=20260326"></script>
|
||||
|
||||
@@ -20,6 +20,40 @@ async function doLogin() {
|
||||
}
|
||||
}
|
||||
|
||||
async function doRegister() {
|
||||
const user = document.getElementById('registerUser').value.trim();
|
||||
const pass = document.getElementById('registerPass').value.trim();
|
||||
const passConfirm = document.getElementById('registerPassConfirm').value.trim();
|
||||
if (!user || !pass) { document.getElementById('registerError').textContent = '请输入用户名和密码'; return; }
|
||||
if (pass !== passConfirm) { document.getElementById('registerError').textContent = '两次密码输入不一致'; return; }
|
||||
try {
|
||||
const res = await fetch(API + '/api/register', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username: user, password: pass })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok) { document.getElementById('registerError').textContent = data.error; return; }
|
||||
showToast('注册成功,请登录');
|
||||
showLoginPage();
|
||||
} catch (e) {
|
||||
document.getElementById('registerError').textContent = '网络错误';
|
||||
}
|
||||
}
|
||||
|
||||
function showRegisterPage() {
|
||||
document.getElementById('registerError').textContent = '';
|
||||
document.getElementById('registerUser').value = '';
|
||||
document.getElementById('registerPass').value = '';
|
||||
document.getElementById('registerPassConfirm').value = '';
|
||||
showPage('registerPage');
|
||||
}
|
||||
|
||||
function showLoginPage() {
|
||||
document.getElementById('loginError').textContent = '';
|
||||
showPage('loginPage');
|
||||
}
|
||||
|
||||
function doLogout() {
|
||||
token = null;
|
||||
username = null;
|
||||
|
||||
@@ -135,9 +135,8 @@ async function saveEditRecord() {
|
||||
if (time) body.created_at = new Date(time).toISOString();
|
||||
|
||||
try {
|
||||
const res = await fetch(API + '/api/records/' + id, {
|
||||
const res = await apiFetch(API + '/api/records/' + id, {
|
||||
method: 'PUT',
|
||||
headers: headers(),
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
if (!res.ok) { showToast('保存失败'); return; }
|
||||
@@ -152,7 +151,7 @@ async function deleteEditRecord() {
|
||||
const id = document.getElementById('editId').value;
|
||||
if (!confirm('确定删除这条记录?')) return;
|
||||
try {
|
||||
const res = await fetch(API + '/api/records/' + id, { method: 'DELETE', headers: headers() });
|
||||
const res = await apiFetch(API + '/api/records/' + id, { method: 'DELETE' });
|
||||
if (!res.ok) { showToast('删除失败'); return; }
|
||||
showToast('已删除');
|
||||
closeEditModal();
|
||||
|
||||
@@ -11,7 +11,7 @@ async function doExport(format) {
|
||||
closeExportModal();
|
||||
showToast('正在导出...');
|
||||
try {
|
||||
const res = await fetch(API + '/api/export?format=' + format, { headers: headers() });
|
||||
const res = await apiFetch(API + '/api/export?format=' + format);
|
||||
if (!res.ok) {
|
||||
const err = await res.json();
|
||||
showToast(err.error || '导出失败');
|
||||
@@ -88,9 +88,9 @@ async function confirmImport() {
|
||||
if (!pendingImportContent) return;
|
||||
showToast('正在导入...');
|
||||
try {
|
||||
const res = await fetch(API + '/api/import', {
|
||||
const res = await apiFetch(API + '/api/import', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'text/plain; charset=utf-8', 'Authorization': 'Bearer ' + token },
|
||||
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
|
||||
body: pendingImportContent
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
@@ -159,9 +159,8 @@ async function submitRecord() {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(API + '/api/records', {
|
||||
const res = await apiFetch(API + '/api/records', {
|
||||
method: 'POST',
|
||||
headers: headers(),
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
if (!res.ok) { showToast('保存失败'); return; }
|
||||
|
||||
Reference in New Issue
Block a user