修正
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>NJTS 会計システム - メイン</title>
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<link rel="stylesheet" href="/css/mobile.css" />
|
||||
<script src="js/auth.js"></script>
|
||||
<style>
|
||||
body {
|
||||
@@ -79,6 +81,50 @@
|
||||
.logout-btn:hover {
|
||||
background: #c82333;
|
||||
}
|
||||
.change-pw-btn {
|
||||
padding: 8px 12px;
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
.change-pw-btn:hover { background: #545b62; }
|
||||
/* パスワード変更モーダル */
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 1000;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.modal-overlay.active { display: flex; }
|
||||
.modal-box {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
padding: 32px;
|
||||
width: 360px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
||||
}
|
||||
.modal-box h3 { margin: 0 0 20px; }
|
||||
.modal-box .form-group { margin-bottom: 14px; }
|
||||
.modal-box label { display: block; margin-bottom: 5px; font-size: 13px; font-weight: 600; color: #333; }
|
||||
.modal-box input[type="password"] {
|
||||
width: 100%; padding: 10px; border: 1px solid #ddd;
|
||||
border-radius: 5px; font-size: 14px; box-sizing: border-box;
|
||||
}
|
||||
.modal-box .btn-row { display: flex; gap: 10px; margin-top: 20px; }
|
||||
.modal-box .btn-row button { flex: 1; padding: 10px; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; }
|
||||
.modal-box .btn-submit { background: #007bff; color: white; }
|
||||
.modal-box .btn-submit:hover { background: #0056b3; }
|
||||
.modal-box .btn-cancel { background: #e9ecef; color: #333; }
|
||||
.modal-box .btn-cancel:hover { background: #d0d5db; }
|
||||
.modal-msg { padding: 8px 12px; border-radius: 4px; margin-bottom: 12px; display: none; font-size: 13px; }
|
||||
.modal-msg.error { background: #fee; color: #c33; border: 1px solid #fcc; }
|
||||
.modal-msg.success { background: #efe; color: #3a3; border: 1px solid #cfc; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -86,10 +132,35 @@
|
||||
<h1>NJTS</h1>
|
||||
<div class="user-info">
|
||||
<span>ユーザー: <strong id="username">読み込み中...</strong></span>
|
||||
<button class="change-pw-btn" onclick="openChangePw()">パスワード変更</button>
|
||||
<button class="logout-btn" onclick="logout()">ログアウト</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- パスワード変更モーダル -->
|
||||
<div class="modal-overlay" id="changePwModal">
|
||||
<div class="modal-box">
|
||||
<h3>🔒 パスワード変更</h3>
|
||||
<div class="modal-msg" id="changePwMsg"></div>
|
||||
<div class="form-group">
|
||||
<label>現在のパスワード</label>
|
||||
<input type="password" id="cpCurrent" placeholder="現在のパスワード" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>新しいパスワード(8文字以上)</label>
|
||||
<input type="password" id="cpNew" placeholder="新しいパスワード" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>新しいパスワード(確認)</label>
|
||||
<input type="password" id="cpConfirm" placeholder="もう一度入力" />
|
||||
</div>
|
||||
<div class="btn-row">
|
||||
<button class="btn-submit" onclick="submitChangePw()">変更する</button>
|
||||
<button class="btn-cancel" onclick="closeChangePw()">キャンセル</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="grid">
|
||||
<section class="card">
|
||||
<h2>会計システム</h2>
|
||||
@@ -142,6 +213,56 @@
|
||||
}
|
||||
});
|
||||
|
||||
// パスワード変更モーダル
|
||||
function openChangePw() {
|
||||
document.getElementById("cpCurrent").value = "";
|
||||
document.getElementById("cpNew").value = "";
|
||||
document.getElementById("cpConfirm").value = "";
|
||||
const msg = document.getElementById("changePwMsg");
|
||||
msg.style.display = "none";
|
||||
document.getElementById("changePwModal").classList.add("active");
|
||||
}
|
||||
function closeChangePw() {
|
||||
document.getElementById("changePwModal").classList.remove("active");
|
||||
}
|
||||
function showChangePwMsg(text, isError) {
|
||||
const msg = document.getElementById("changePwMsg");
|
||||
msg.textContent = text;
|
||||
msg.className = "modal-msg " + (isError ? "error" : "success");
|
||||
msg.style.display = "block";
|
||||
}
|
||||
async function submitChangePw() {
|
||||
const current = document.getElementById("cpCurrent").value;
|
||||
const newPw = document.getElementById("cpNew").value;
|
||||
const confirm = document.getElementById("cpConfirm").value;
|
||||
const user = getCurrentUser();
|
||||
if (!current || !newPw || !confirm) {
|
||||
showChangePwMsg("すべての項目を入力してください", true); return;
|
||||
}
|
||||
if (newPw.length < 8) {
|
||||
showChangePwMsg("新しいパスワードは8文字以上にしてください", true); return;
|
||||
}
|
||||
if (newPw !== confirm) {
|
||||
showChangePwMsg("新しいパスワードが一致しません", true); return;
|
||||
}
|
||||
try {
|
||||
const res = await fetch("/api/users/change-password", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username: user.username, current_password: current, new_password: newPw })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok) {
|
||||
showChangePwMsg("パスワードを変更しました。再ログインしてください", false);
|
||||
setTimeout(() => { logout(); }, 2000);
|
||||
} else {
|
||||
showChangePwMsg(data.detail || "変更に失敗しました", true);
|
||||
}
|
||||
} catch (e) {
|
||||
showChangePwMsg("エラー: " + e.message, true);
|
||||
}
|
||||
}
|
||||
|
||||
// dropdown toggle
|
||||
const toggle = document.getElementById("accountingToggle");
|
||||
const menu = document.getElementById("accountingMenu");
|
||||
|
||||
Reference in New Issue
Block a user