Files
njts-accounting-core/frontend/index.html
2026-06-01 00:35:53 +09:00

360 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
http-equiv="Cache-Control"
content="no-cache, no-store, must-revalidate"
/>
<meta http-equiv="Pragma" content="no-cache" />
<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 {
font-family:
system-ui,
-apple-system,
"Yu Gothic UI",
"Hiragino Kaku Gothic ProN",
"メイリオ",
sans-serif;
padding: 24px;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
max-width: 980px;
margin: 0 auto;
}
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
background: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
display: flex;
flex-direction: column;
}
.card h2 {
margin-top: 0;
}
.card p:last-child {
margin-top: auto;
margin-bottom: 0;
padding-top: 12px;
}
.btn {
display: inline-block;
padding: 10px 14px;
border-radius: 6px;
background: #007bff;
color: #fff;
text-decoration: none;
white-space: nowrap;
}
header {
max-width: 980px;
margin: 0 auto 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
header h1 {
margin: 0;
font-size: 20px;
}
.user-info {
display: flex;
align-items: center;
gap: 15px;
font-size: 14px;
color: #333;
}
.logout-btn {
padding: 8px 12px;
background: #dc3545;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
}
.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>
<header>
<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>
<p>
会計モジュールの主要画面へ移動します。仕訳入力、試算表、元帳に移動できます。
</p>
<p>
<a class="btn" href="journal-entry.html">仕訳入力へ</a>
<a
class="btn"
href="trial-balance.html"
style="margin-left: 10px; background: #28a745"
>試算表へ</a
>
<a
class="btn"
href="opening_balance.html"
style="margin-left: 10px; background: #fd7e14"
>期首残高入力へ</a
>
</p>
</section>
<section class="card">
<h2>給与システム</h2>
<p>給与・賞与の計算や従業員管理を行います。</p>
<p><a class="btn" href="payroll.html">給与システムを開く</a></p>
</section>
<section class="card">
<h2>🏦 銀行明細照会</h2>
<p>
銀行のCSVデータを取込み、明細を管理します。重複チェック付きで安全に取込め、月別・銀行別の検索・印刷が可能です。
</p>
<p>
<a class="btn" href="bank-statement.html" style="background: #1565c0"
>銀行明細を開く</a
>
</p>
</section>
<section class="card">
<h2>🏛 e-Gov 電子送達</h2>
<p>
年金事務所からの電子送達書類(社会保険通知など)を取得・管理します。<br />
GビズIDでe-Govにログインし、毎月の電子通知CSVを確認できます。
</p>
<p>
<a class="btn" href="egov.html" style="background: #6f42c1"
>e-Gov 連携を開く</a
>
</p>
</section>
</main>
<script>
// ユーザー情報を表示
document.addEventListener("DOMContentLoaded", function () {
const user = getCurrentUser();
if (user) {
document.getElementById("username").textContent = user.username;
}
});
// パスワード変更モーダル
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);
}
}
</script>
</body>
</html>