Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29bea44e14 | ||
|
|
436dbb4665 | ||
|
|
baa31ca72b | ||
|
|
dc5c652d35 | ||
|
|
d002469a41 | ||
|
|
37fc091ce3 | ||
|
|
1c827ac251 |
1
src/main/java/com/example/demo/domain/model/test.txt
Normal file
1
src/main/java/com/example/demo/domain/model/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
テスト
|
||||
1
src/main/java/com/example/demo/domain/service/test.txt
Normal file
1
src/main/java/com/example/demo/domain/service/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
テスト
|
||||
1
src/main/java/com/example/demo/infra/entity/test.txt
Normal file
1
src/main/java/com/example/demo/infra/entity/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
テスト
|
||||
1
src/main/java/com/example/demo/infra/repository/test.txt
Normal file
1
src/main/java/com/example/demo/infra/repository/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
テスト
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class ApprovalReceiveController {
|
||||
|
||||
// 申請受信ボックスに遷移
|
||||
@GetMapping("/approvalReceive")
|
||||
public String approvalReceive() {
|
||||
return "approvalReceive";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class BookApprovalController {
|
||||
|
||||
// 寄贈申請フォームに遷移
|
||||
@GetMapping("/bookApproval")
|
||||
public String bookApproval() {
|
||||
return "bookApproval";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class BookController {
|
||||
|
||||
// 図書一覧に遷移
|
||||
@GetMapping("/book")
|
||||
public String book() {
|
||||
return "book";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class BookInsertController {
|
||||
|
||||
// 寄贈申請フォームに遷移
|
||||
@GetMapping("/bookInsert")
|
||||
public String bookInsert() {
|
||||
return "bookInsert";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class LendListController {
|
||||
|
||||
// 貸出中一覧に遷移
|
||||
@GetMapping("/lendlist")
|
||||
public String lendlist() {
|
||||
return "lendlist";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class LoginController {
|
||||
|
||||
// 初期画面
|
||||
@GetMapping("/login")
|
||||
public String login() {
|
||||
return "login";
|
||||
}
|
||||
|
||||
// ログイン処理が実行された後
|
||||
@GetMapping("/topmenu")
|
||||
public String topmenu() {
|
||||
return "topmenu";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class LogoutController {
|
||||
|
||||
// ログアウト処理を実行
|
||||
@GetMapping("/logout")
|
||||
public String logout() {
|
||||
return "login";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.example.demo.presentation.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class PasswordChangeController {
|
||||
|
||||
// パスワード変更画面に遷移
|
||||
@GetMapping("/passwordChange")
|
||||
public String passwordChange() {
|
||||
return "passwordChange";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
テスト
|
||||
@@ -1 +1,4 @@
|
||||
spring.application.name=ShareBooks
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/sharebooks
|
||||
spring.datasource.username=rezouser
|
||||
spring.datasource.password=Rezo_0000
|
||||
677
src/main/resources/templates/approvalReceive.html
Normal file
677
src/main/resources/templates/approvalReceive.html
Normal file
@@ -0,0 +1,677 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>寄贈申請 受信BOX</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Yu Gothic", "Meiryo", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #f5f7fb;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Header
|
||||
--------------------- */
|
||||
.header {
|
||||
height: 60px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #dfe4ea;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #173a70;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
padding: 8px 14px;
|
||||
border: 1px solid #d0d7de;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Layout
|
||||
--------------------- */
|
||||
.wrapper {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 60px);
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Sidebar
|
||||
--------------------- */
|
||||
.sidebar {
|
||||
width: 230px;
|
||||
background: #002a63;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
padding: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
margin: 6px 10px;
|
||||
padding: 14px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu li:hover {
|
||||
background: #0b57d0;
|
||||
}
|
||||
|
||||
.menu li.active {
|
||||
background: #0b57d0;
|
||||
}
|
||||
|
||||
/* 空白を詰める */
|
||||
.menu-spacer {
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Main
|
||||
--------------------- */
|
||||
.main {
|
||||
flex: 1;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 40px;
|
||||
color: #173a70;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Search
|
||||
--------------------- */
|
||||
.search-box {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
< !-- .form-group {
|
||||
-->< !-- flex: 1;
|
||||
-->< !--
|
||||
}
|
||||
|
||||
-->.form-group label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
select {
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
border: 1px solid #d7dde5;
|
||||
border-radius: 4px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: 38px;
|
||||
padding: 0 18px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
background: #0b57d0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-clear {
|
||||
background: #fff;
|
||||
border: 1px solid #d0d7de;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Table
|
||||
--------------------- */
|
||||
.result-count {
|
||||
margin-bottom: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-box {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #f3f5f7;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid #edf0f2;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th {
|
||||
color: #173a70;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.good {
|
||||
background: #dff5df;
|
||||
color: #2b7a2b;
|
||||
}
|
||||
|
||||
.used {
|
||||
background: #dbeafe;
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
.damage {
|
||||
background: #fff3cd;
|
||||
color: #8a6d3b;
|
||||
}
|
||||
|
||||
.pending {
|
||||
color: #f0a000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.approved {
|
||||
color: #0b57d0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rejected {
|
||||
color: #d9534f;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Pagination
|
||||
--------------------- */
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.page-buttons {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 1px solid #d0d7de;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.page-btn.active {
|
||||
background: #0b57d0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Bottom Info
|
||||
--------------------- */
|
||||
.info-area {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.info-title {
|
||||
font-weight: bold;
|
||||
color: #173a70;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.info-box ul {
|
||||
margin-left: 18px;
|
||||
}
|
||||
|
||||
.info-box li {
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 25px;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* --------------------
|
||||
Action Buttons
|
||||
--------------------- */
|
||||
.action-area {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 7px 14px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
/* 押した感を出すためのアニメーション */
|
||||
transition: background-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
/* ホバー時 */
|
||||
.action-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 3px 7px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
/* 押下中 */
|
||||
.action-btn:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* 承認 */
|
||||
.approve-btn {
|
||||
background: #0b57d0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.approve-btn:hover {
|
||||
background: #0846a8;
|
||||
}
|
||||
|
||||
/* 却下 */
|
||||
.reject-btn {
|
||||
background: #d9534f;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.reject-btn:hover {
|
||||
background: #b52b27;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
|
||||
<div class="logo">📖 ShareBooks</div>
|
||||
|
||||
<div class="header-right">
|
||||
<span>山田 太郎 さん(管理者)</span>
|
||||
<button class="logout-btn">ログアウト</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<aside class="sidebar">
|
||||
|
||||
<div class="sidebar-title">管理者メニュー</div>
|
||||
|
||||
<ul class="menu">
|
||||
<li>🏠 トップメニュー</li>
|
||||
</ul>
|
||||
|
||||
<div class="menu-spacer"></div>
|
||||
|
||||
<ul class="menu">
|
||||
<li class="active">📚 寄贈申請受信BOX</li>
|
||||
</ul>
|
||||
|
||||
</aside>
|
||||
|
||||
<main class="main">
|
||||
|
||||
<div class="breadcrumb">トップメニュー > 図書管理 > 寄贈申請受信BOX</div>
|
||||
|
||||
<h1 class="page-title">寄贈申請受信BOX</h1>
|
||||
|
||||
<div class="description">
|
||||
ユーザーから提出された図書寄贈申請の一覧です。申請内容を確認し、承認または却下を行ってください。</div>
|
||||
|
||||
<div class="search-box">
|
||||
|
||||
<div class="search-row">
|
||||
|
||||
<div class="form-group">
|
||||
<label>本の状態</label> <select>
|
||||
<option>すべて</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-search">検索</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="result-count">受信件数:${donationList.size()}件</div>
|
||||
|
||||
<div class="table-box">
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>社員ID</th>
|
||||
<th>社員名</th>
|
||||
<th>タイトル</th>
|
||||
<th>著者名</th>
|
||||
<th>本の状態</th>
|
||||
<th>出版社</th>
|
||||
<th>カテゴリ</th>
|
||||
<th>備考</th>
|
||||
<th>詳細URL</th>
|
||||
<th>承認 / 却下</th>
|
||||
<th>登録画面移動 / <br> 差し戻し
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<!--モック用ダミーデータ。実装時に削除-->
|
||||
|
||||
<tr>
|
||||
<td>100002</td>
|
||||
<td>佐藤 花子</td>
|
||||
<td>AIモデル開発入門</td>
|
||||
<td>田中 美咲</td>
|
||||
|
||||
<td><span class="status good">良好</span></td>
|
||||
|
||||
<td>技術評論社</td>
|
||||
<td>IT・プログラミング</td>
|
||||
<td>付属品なし</td>
|
||||
|
||||
<td><a href="https://amazon..." target="_blank"> 詳細URL </a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="action-area">
|
||||
|
||||
|
||||
<form action="donationApprove" method="post" style="display: inline;">
|
||||
|
||||
<input type="hidden" name="donationId" value="1">
|
||||
|
||||
<button type="submit" class="action-btn approve-btn">
|
||||
承認
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
<form action="donationReject" method="post" style="display: inline;"
|
||||
onsubmit="return confirm('この寄贈申請を却下しますか?');">
|
||||
|
||||
<input type="hidden" name="donationId" value="1">
|
||||
|
||||
<button type="submit" class="action-btn reject-btn">
|
||||
却下
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
<!-- 承認待ちを想定したダミーなので、登録と戻しは非表示-->
|
||||
|
||||
<!-- <td>-->
|
||||
<!-- <div class="action-area">-->
|
||||
|
||||
<!-- <form action="donationApprove" method="post"-->
|
||||
<!-- style="display: inline;">-->
|
||||
<!-- <input type="hidden" name="donationId" value="2">-->
|
||||
|
||||
<!-- <button type="submit" class="action-btn approve-btn">-->
|
||||
<!-- 登録-->
|
||||
<!-- </button>-->
|
||||
|
||||
<!-- </form>-->
|
||||
|
||||
<!-- <form action="donationReject" method="post"-->
|
||||
<!-- style="display: inline;"-->
|
||||
<!-- onsubmit="return confirm('この寄贈申請を却下しますか?');">-->
|
||||
|
||||
<!-- <input type="hidden" name="donationId" value="2">-->
|
||||
|
||||
<!-- <button type="submit" class="action-btn reject-btn">-->
|
||||
<!-- 戻し-->
|
||||
<!-- </button>-->
|
||||
|
||||
<!-- </form>-->
|
||||
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- </td>-->
|
||||
|
||||
<td>
|
||||
<div class="action-area">
|
||||
|
||||
<form action="donationApprove" method="post" style="display: inline;">
|
||||
|
||||
<input type="hidden" name="donationId" value="2">
|
||||
|
||||
<button type="submit" class="action-btn approve-btn">
|
||||
登録</button>
|
||||
|
||||
</form>
|
||||
|
||||
<form action="donationReject" method="post" style="display: inline;"
|
||||
onsubmit="return confirm('この寄贈申請を却下しますか?');">
|
||||
|
||||
<input type="hidden" name="donationId" value="2">
|
||||
|
||||
<button type="submit" class="action-btn reject-btn">
|
||||
戻し</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>100003</td>
|
||||
<td>鈴木 一郎</td>
|
||||
<td>Pythonではじめるデータ分析</td>
|
||||
<td>佐藤 拓也</td>
|
||||
|
||||
<td><span class="status used">使用感あり</span></td>
|
||||
|
||||
<td>オライリー</td>
|
||||
<td>IT・プログラミング</td>
|
||||
<td>CD-ROMあり</td>
|
||||
|
||||
<td><a href="https://amazon..." target="_blank"> 詳細URL </a>
|
||||
</td>
|
||||
|
||||
<!-- 承認済みを想定したダミーなので、承認と却下は非表示-->
|
||||
|
||||
<!-- <td>-->
|
||||
<!-- <div class="action-area">-->
|
||||
|
||||
<!-- <form action="donationApprove" method="post"-->
|
||||
<!-- style="display: inline;">-->
|
||||
|
||||
<!-- <input type="hidden" name="donationId" value="2">-->
|
||||
|
||||
<!-- <button type="submit" class="action-btn approve-btn">-->
|
||||
<!-- 承認-->
|
||||
<!-- </button>-->
|
||||
|
||||
<!-- </form>-->
|
||||
|
||||
<!-- <form action="donationReject" method="post"-->
|
||||
<!-- style="display: inline;"-->
|
||||
<!-- onsubmit="return confirm('この寄贈申請を却下しますか?');">-->
|
||||
|
||||
<!-- <input type="hidden" name="donationId" value="2">-->
|
||||
|
||||
<!-- <button type="submit" class="action-btn reject-btn">-->
|
||||
<!-- 却下-->
|
||||
<!-- </button>-->
|
||||
|
||||
<!-- </form>-->
|
||||
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- </td>-->
|
||||
|
||||
<td>
|
||||
<div class="action-area">
|
||||
|
||||
<form action="donationApprove" method="post" style="display: inline;">
|
||||
<input type="hidden" name="donationId" value="2">
|
||||
|
||||
<button type="submit" class="action-btn approve-btn">
|
||||
登録</button>
|
||||
</form>
|
||||
|
||||
<form action="donationReject" method="post" style="display: inline;"
|
||||
onsubmit="return confirm('この寄贈申請を却下しますか?');">
|
||||
|
||||
<input type="hidden" name="donationId" value="2">
|
||||
|
||||
<button type="submit" class="action-btn reject-btn">
|
||||
戻し</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<!--モック用ダミーデータ終わり-->
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="info-area">
|
||||
|
||||
<div class="info-box">
|
||||
<div class="info-title">本の状態の判断基準</div>
|
||||
|
||||
<ul>
|
||||
<li><b>新品同様</b>:ほぼ未使用</li>
|
||||
<li><b>良好</b>:目立つ劣化なし</li>
|
||||
<li><b>使用感あり</b>:多少の折れ・擦れあり</li>
|
||||
<li><b>傷みあり</b>:目立つ傷・汚れ・書き込みあり</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="info-box">
|
||||
<div class="info-title">操作について</div>
|
||||
|
||||
<ul>
|
||||
<li>「詳細表示」ボタンで申請内容の詳細を確認できます。</li>
|
||||
<li>詳細画面から承認または却下を実施します。</li>
|
||||
<li>承認された寄贈申請は図書管理へ登録できます。</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="footer">© 2026 ShareBooks</div>
|
||||
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1353
src/main/resources/templates/book.html
Normal file
1353
src/main/resources/templates/book.html
Normal file
File diff suppressed because it is too large
Load Diff
1203
src/main/resources/templates/bookApproval.html
Normal file
1203
src/main/resources/templates/bookApproval.html
Normal file
File diff suppressed because it is too large
Load Diff
974
src/main/resources/templates/bookInsert.html
Normal file
974
src/main/resources/templates/bookInsert.html
Normal file
@@ -0,0 +1,974 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>【図書】登録内容入力</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Yu Gothic", "Meiryo", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #f5f6fa;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Header
|
||||
========================= */
|
||||
.header {
|
||||
height: 60px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d9dee5;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #1d4075;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
/* 通知 */
|
||||
.notification {
|
||||
position: relative;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.notification:hover {
|
||||
background-color: #f1f5fa;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.notification-badge {
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
background: #d71920;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
/* サインイン中アカウント */
|
||||
.account {
|
||||
font-size: 13px;
|
||||
color: #555;
|
||||
padding: 7px 9px;
|
||||
border-radius: 4px;
|
||||
cursor: default;
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.account:hover {
|
||||
background-color: #f1f5fa;
|
||||
color: #1d4075;
|
||||
}
|
||||
|
||||
/* ログアウト */
|
||||
.logout-btn {
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #d0d7de;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background-color: #f1f5fa;
|
||||
border-color: #1d4075;
|
||||
color: #1d4075;
|
||||
}
|
||||
|
||||
.logout-btn:active {
|
||||
background-color: #e5edf7;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Layout
|
||||
========================= */
|
||||
.wrapper {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 60px);
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Sidebar
|
||||
========================= */
|
||||
.sidebar {
|
||||
width: 220px;
|
||||
background: #002b66;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
padding: 18px;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
.menu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
padding: 16px 20px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.menu li:hover {
|
||||
background: #0c438f;
|
||||
}
|
||||
|
||||
.menu li.active {
|
||||
background: #1659d4;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Main
|
||||
========================= */
|
||||
.main {
|
||||
flex: 1;
|
||||
padding: 25px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Breadcrumb
|
||||
========================= */
|
||||
.breadcrumb {
|
||||
font-size: 12px;
|
||||
color: #6d7b91;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Page title
|
||||
========================= */
|
||||
.page-title {
|
||||
font-size: 42px;
|
||||
color: #173a70;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.required-text {
|
||||
color: #d9534f;
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Card
|
||||
========================= */
|
||||
.card {
|
||||
background: #fff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Form
|
||||
縦積み
|
||||
========================= */
|
||||
.form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Form group
|
||||
========================= */
|
||||
.form-group {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
width: 150px;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #d9534f;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: #555;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
flex: 1;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Input
|
||||
========================= */
|
||||
input[type="text"],
|
||||
input[type="date"],
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: 1px solid #d9dee5;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
background: #fff;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="date"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
outline: none;
|
||||
border-color: #1659d4;
|
||||
box-shadow: 0 0 0 2px rgba(22, 89, 212, .1);
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
background: #f3f5f8;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Help
|
||||
========================= */
|
||||
.help {
|
||||
font-size: 11px;
|
||||
color: #777;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Category
|
||||
========================= */
|
||||
.inline {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.inline select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
white-space: nowrap;
|
||||
padding: 10px 16px;
|
||||
border: 1px solid #d0d7de;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.add-btn:hover {
|
||||
background-color: #f1f5fa;
|
||||
border-color: #1659d4;
|
||||
color: #1659d4;
|
||||
}
|
||||
|
||||
.add-btn:active {
|
||||
background-color: #e5edf7;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Optional section
|
||||
========================= */
|
||||
.optional-section {
|
||||
margin-top: 25px;
|
||||
padding-top: 25px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.optional-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Textarea
|
||||
========================= */
|
||||
textarea {
|
||||
resize: none;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.counter {
|
||||
text-align: right;
|
||||
font-size: 11px;
|
||||
color: #888;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Notice
|
||||
========================= */
|
||||
.notice {
|
||||
margin-top: 20px;
|
||||
padding: 18px;
|
||||
background: #fffaf0;
|
||||
border-top: 1px solid #efe2b5;
|
||||
}
|
||||
|
||||
.notice-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.notice ul {
|
||||
margin-left: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.notice li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Buttons
|
||||
========================= */
|
||||
.button-area {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-width: 140px;
|
||||
padding: 11px 20px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d0d7de;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.1s ease;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #f1f5fa;
|
||||
border-color: #1d4075;
|
||||
color: #1d4075;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(1px);
|
||||
background-color: #e5edf7;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #1659d4;
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #0f47ae;
|
||||
border-color: #0f47ae;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
background: #0c3d96;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Responsive
|
||||
========================= */
|
||||
@media (max-width : 700px) {
|
||||
.header {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.account {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
width: 100%;
|
||||
padding-top: 0;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.inline {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.button-area {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.right-buttons {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.right-buttons .btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Header
|
||||
========================= -->
|
||||
|
||||
<header class="header">
|
||||
|
||||
<div class="logo">
|
||||
📖 ShareBooks
|
||||
</div>
|
||||
|
||||
<c:if test="${not empty errorMessage}">
|
||||
<div style="color: red; margin-bottom: 15px;">${errorMessage}</div>
|
||||
</c:if>
|
||||
|
||||
<div class="header-right">
|
||||
|
||||
<!-- サインイン中アカウント -->
|
||||
<span class="account"> 山田 太郎 さん(管理者) </span>
|
||||
|
||||
<!-- ログアウト -->
|
||||
<form method="post" action="${pageContext.request.contextPath}/logout" style="display: inline;">
|
||||
|
||||
<button type="submit" class="logout-btn" onclick="return confirmLogout()">ログアウト</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Sidebar
|
||||
========================= -->
|
||||
|
||||
<aside class="sidebar">
|
||||
|
||||
<div class="sidebar-title">管理者画面</div>
|
||||
|
||||
<ul class="menu">
|
||||
<li onclick="goTopMenu()">🏠 トップメニュー</li>
|
||||
|
||||
<li class="active">➕ 新規図書登録</li>
|
||||
|
||||
<li onclick="goToBook()">📚 社内図書一覧</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</aside>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Main
|
||||
========================= -->
|
||||
|
||||
<main class="main">
|
||||
|
||||
<div class="breadcrumb">トップメニュー > 新規図書登録 > 新規図書登録内容入力</div>
|
||||
|
||||
|
||||
<h1 class="page-title">新規図書登録内容入力</h1>
|
||||
|
||||
|
||||
<div class="description">新しく図書を登録します。
|
||||
必要事項を入力し、「確認へ」ボタンを押してください。</div>
|
||||
|
||||
|
||||
<div class="required-text">(※)は必須項目です。</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Form
|
||||
========================= -->
|
||||
|
||||
<form method="post" action="${pageContext.request.contextPath}/insertBook">
|
||||
|
||||
|
||||
<div class="card">
|
||||
|
||||
|
||||
<div class="card-header">図書情報</div>
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
|
||||
<!-- =========================
|
||||
必須項目
|
||||
========================= -->
|
||||
|
||||
<div class="form-fields">
|
||||
|
||||
|
||||
<!-- 図書管理ID -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 図書管理ID <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="bookManageId" value="${bookManageId }" readonly>
|
||||
|
||||
<div class="help">※自動採番されます(例:BK0001、BK0002 ...)</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 登録日 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 登録日 </label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="registeredAt" value="${registeredAt }" readonly>
|
||||
|
||||
<div class="help">※自動取得されます</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- タイトル -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> タイトル <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="title" value="${title}" placeholder="タイトルを入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 著者名 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 著者名 <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="author" value="${author}" placeholder="著者名を入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- カテゴリ -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> カテゴリ <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<div class="inline">
|
||||
|
||||
<select name="categoryId">
|
||||
<option value="">選択してください</option>
|
||||
|
||||
<c:forEach var="category" items="${categories}">
|
||||
<option value="${category.bookCategoryId}" <c:if
|
||||
test="${category.bookCategoryId == categoryId}">
|
||||
selected
|
||||
</c:if>>
|
||||
${category.bookCategoryName}</option>
|
||||
</c:forEach>
|
||||
</select>
|
||||
|
||||
|
||||
<!-- <button-->
|
||||
<!-- type="button"-->
|
||||
<!-- class="add-btn">-->
|
||||
|
||||
<!-- + 新規カテゴリ追加-->
|
||||
|
||||
<!-- </button>-->
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- サブカテゴリ -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> サブカテゴリ <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<select name="bookSubcategoryId" id="bookSubcategoryId">
|
||||
|
||||
<option value="">選択してください</option>
|
||||
|
||||
<c:forEach var="subcategory" items="${subcategories}">
|
||||
|
||||
<option value="${subcategory.bookSubcategoryId}"
|
||||
data-category-id="${subcategory.bookCategoryId}" <c:if
|
||||
test="${subcategory.bookSubcategoryId == bookSubcategoryId}">
|
||||
selected
|
||||
</c:if>>
|
||||
${subcategory.bookSubcategoryName}</option>
|
||||
|
||||
</c:forEach>
|
||||
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ISBN -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> ISBN <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="isbn" value="${isbn}" placeholder="例:978-4-1234-5678-9">
|
||||
|
||||
<div class="help">※ハイフン(-)を含む形式で入力してください</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 保管場所 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 保管場所 <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<select name="locationId">
|
||||
|
||||
<option value="">選択してください</option>
|
||||
|
||||
<c:forEach var="location" items="${locations}">
|
||||
|
||||
<option value="${location.locationId}" <c:if
|
||||
test="${location.locationId == locationId}">
|
||||
selected
|
||||
</c:if>>
|
||||
${location.locationName}</option>
|
||||
|
||||
</c:forEach>
|
||||
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 本の状態 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 本の状態 <span class="required"> (※) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<select name="condition">
|
||||
|
||||
<option value="">選択してください</option>
|
||||
|
||||
<option value="1">新品同様:ほぼ未使用</option>
|
||||
|
||||
<option value="2">良好:目立つ傷や汚れ無し</option>
|
||||
|
||||
<option value="3">使用感あり:多少の折れ、擦れあり</option>
|
||||
|
||||
<option value="4">傷みあり:目立つ傷、汚れ、書き込みあり</option>
|
||||
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- =========================
|
||||
任意項目
|
||||
========================= -->
|
||||
|
||||
<div class="optional-section">
|
||||
|
||||
|
||||
<div class="optional-title">任意項目</div>
|
||||
|
||||
|
||||
<div class="form-fields">
|
||||
|
||||
|
||||
<!-- 出版社 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 出版社 <span class="optional"> (任意) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="publisher" value="${publisher}"
|
||||
placeholder="出版社を入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 出版日 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 出版日 <span class="optional"> (任意) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="date" name="publishDate" value="${publishDate}">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 寄贈者 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 寄贈者 <span class="optional"> (任意) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input type="text" name="donorId" value="${donorId}"
|
||||
placeholder="社員ID(半角)を入力してください">
|
||||
|
||||
<div class="help">※寄贈図書の場合に入力してください</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 備考 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label> 備考 <span class="optional"> (任意) </span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<textarea name="description" maxlength="200"
|
||||
placeholder="備考を入力してください(例:付属品の有無、特記事項など)">${description}</textarea>
|
||||
|
||||
<div class="counter">0 / 200</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
注意事項
|
||||
========================= -->
|
||||
|
||||
<div class="notice">
|
||||
|
||||
<div class="notice-title">入力に関する注意</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>図書一覧に表示する内容を入力してください。</li>
|
||||
|
||||
<li>ISBNはハイフン(-)を含む形式で入力してください。</li>
|
||||
|
||||
<li>登録日および図書管理IDは、 登録時に自動で設定されます。</li>
|
||||
|
||||
<li>出版日は任意項目のため、 不明な場合は空欄でも登録できます。</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Buttons
|
||||
========================= -->
|
||||
|
||||
<div class="button-area">
|
||||
|
||||
<a href="${pageContext.request.contextPath}/BookServlet" class="btn"
|
||||
style="display: inline-flex; align-items: center; justify-content: center; text-decoration: none;">
|
||||
図書一覧へ戻る </a>
|
||||
|
||||
|
||||
<div class="right-buttons">
|
||||
|
||||
|
||||
<button type="reset" class="btn">クリア</button>
|
||||
|
||||
|
||||
<button type="submit" class="btn btn-primary">確認へ</button>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</main>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
|
||||
const result = window.confirm("本当にログアウトしてよろしいですか?");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function goTopMenu() {
|
||||
location.href = "${pageContext.request.contextPath}/topmenu.jsp";
|
||||
}
|
||||
|
||||
function goToBook() {
|
||||
location.href = "${pageContext.request.contextPath}/book.jsp";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
759
src/main/resources/templates/lendlist.html
Normal file
759
src/main/resources/templates/lendlist.html
Normal file
@@ -0,0 +1,759 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>貸出中図書一覧</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Yu Gothic", "Meiryo", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #f5f7fb;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* ===== ヘッダー ===== */
|
||||
.header {
|
||||
height: 58px;
|
||||
border-bottom: 1px solid #d8e0e8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 18px 0 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #213d75;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.user {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.bell {
|
||||
font-size: 22px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
right: -5px;
|
||||
background: #e33;
|
||||
color: #fff;
|
||||
border-radius: 9px;
|
||||
font-size: 8px;
|
||||
min-width: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #a8b3c0;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ===== レイアウト ===== */
|
||||
.wrapper {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 60px);
|
||||
}
|
||||
|
||||
/* ===== サイドバー ===== */
|
||||
.sidebar {
|
||||
width: 180px;
|
||||
flex: 0 0 180px;
|
||||
background: #082957;
|
||||
/* topmenu.jspと同一のベース色 */
|
||||
color: #fff;
|
||||
padding: 10px 8px;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 4px 9px 12px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
min-height: 42px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 10px;
|
||||
height: 100%;
|
||||
min-height: 42px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* アクティブ項目およびホバー時の背景色を topmenu.jsp (.side-menu.active) の #1267d9 に変更 */
|
||||
.menu li.active a,
|
||||
.menu a:hover {
|
||||
background: #1267d9;
|
||||
}
|
||||
|
||||
/* 下部の余白エリアもサイドバー本体の背景色と統一 */
|
||||
.blank-menu {
|
||||
margin: 18px 10px;
|
||||
height: 240px;
|
||||
background: #082957;
|
||||
}
|
||||
|
||||
/* ===== メイン ===== */
|
||||
.main {
|
||||
flex: 1;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 42px;
|
||||
color: #173a70;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
/* ===== 検索エリア ===== */
|
||||
.search-area {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.search-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.search-main {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.search-sub {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 12px;
|
||||
color: #173a70;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.field {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.field label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
select {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border: 1px solid #d7dde5;
|
||||
border-radius: 4px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
height: 36px;
|
||||
padding: 0 24px;
|
||||
background: #0e57d9;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
margin-top: 8px;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
border: 1px solid #d0d7de;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ===== テーブル ===== */
|
||||
.result-count {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #f3f6fa;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border-bottom: 1px solid #edf0f2;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
th {
|
||||
color: #173a70;
|
||||
}
|
||||
|
||||
.status {
|
||||
display: inline-block;
|
||||
min-width: 48px;
|
||||
text-align: center;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-normal {
|
||||
background: #dff5df;
|
||||
color: #2f7a2f;
|
||||
}
|
||||
|
||||
.status-delay {
|
||||
background: #e9f1ff;
|
||||
color: #1f5fd7;
|
||||
}
|
||||
|
||||
.overdue {
|
||||
color: #d9534f;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.return-btn {
|
||||
padding: 5px 12px;
|
||||
background: #fff;
|
||||
border: 1px solid #0e57d9;
|
||||
color: #0e57d9;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* ===== ページャ ===== */
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.page-buttons {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 1px solid #d9dee5;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-btn.active {
|
||||
background: #0e57d9;
|
||||
color: #fff;
|
||||
border-color: #0e57d9;
|
||||
}
|
||||
|
||||
/* ===== 案内 ===== */
|
||||
.notice {
|
||||
margin-top: 15px;
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.notice-title {
|
||||
font-weight: bold;
|
||||
color: #173a70;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.notice p {
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
/* ===== 返却ポップアップ(モーダル) ===== */
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
z-index: 1000;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: #fff;
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
width: 420px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #173a70;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 2px solid #e5e7eb;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.modal-info-table {
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.modal-info-table th {
|
||||
width: 40%;
|
||||
background: #f8fafc;
|
||||
padding: 8px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.modal-info-table td {
|
||||
padding: 8px;
|
||||
font-size: 12px;
|
||||
border: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.modal-msg {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.modal-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.btn-yes {
|
||||
padding: 8px 24px;
|
||||
background: #0e57d9;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-no {
|
||||
padding: 8px 24px;
|
||||
background: #e5e7eb;
|
||||
color: #333;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
|
||||
<div class="header-title">
|
||||
<span class="book-icon">📖</span> ShareBooks
|
||||
</div>
|
||||
<div class="header-right">
|
||||
|
||||
<span class="user">
|
||||
<%=session.getAttribute("employeeName")%>(<%=roleName%>)
|
||||
</span>
|
||||
|
||||
<form action="${pageContext.request.contextPath}/logout" method="post"
|
||||
onsubmit="return confirm('ログアウトしますか?');">
|
||||
|
||||
<button type="submit" class="logout">ログアウト</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- サイドメニュー -->
|
||||
<aside class="sidebar">
|
||||
|
||||
<div class="sidebar-title">管理者メニュー</div>
|
||||
|
||||
<ul class="menu">
|
||||
<li><a href="${pageContext.request.contextPath}/topmenu.jsp">⌂
|
||||
トップメニュー</a></li>
|
||||
<li class="active"><a href="${pageContext.request.contextPath}/lendList">📅
|
||||
貸出中備品・図書一覧</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="blank-menu"></div>
|
||||
|
||||
</aside>
|
||||
|
||||
<!-- メインコンテンツ -->
|
||||
<main class="main">
|
||||
|
||||
<div class="breadcrumb">トップメニュー > 貸出中備品・図書一覧</div>
|
||||
|
||||
<h1 class="page-title">貸出中備品・図書一覧</h1>
|
||||
|
||||
<div class="description">現在貸出中の備品および図書の一覧です。</div>
|
||||
|
||||
<!-- 検索条件 -->
|
||||
<form action="${pageContext.request.contextPath}/lendList" method="get">
|
||||
<div class="search-area">
|
||||
|
||||
<div class="search-card search-main">
|
||||
|
||||
<div class="search-title">検索(完全一致)</div>
|
||||
|
||||
<div class="search-row">
|
||||
|
||||
<div class="field">
|
||||
<label>社員ID</label> <input type="text" name="employeeId" placeholder="例)100001"
|
||||
value="<c:out value='${employeeId}'/>">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>図書管理ID</label> <input type="text" name="bookManageId" placeholder="例)B000123"
|
||||
value="<c:out value='${bookManageId}'/>">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>備品ID</label> <input type="text" name="equipmentId" placeholder="例)E000456"
|
||||
value="<c:out value='${equipmentId}'/>">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="search-btn">🔍 検索</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="search-card search-sub">
|
||||
|
||||
<div class="search-title">フィルタ</div>
|
||||
|
||||
<div class="search-row">
|
||||
|
||||
<div class="field">
|
||||
<label>種別</label> <select name="type" onchange="this.form.submit()">
|
||||
<option value="">すべて</option>
|
||||
<option value="equipment" ${type=='equipment' ? 'selected' : '' }>備品</option>
|
||||
<option value="book" ${type=='book' ? 'selected' : '' }>図書</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>返却期限</label> <select name="dueStatus" onchange="this.form.submit()">
|
||||
<option value="">すべて</option>
|
||||
<option value="overdue" ${dueStatus=='overdue' ? 'selected' : '' }>超過</option>
|
||||
<option value="normal" ${dueStatus=='normal' ? 'selected' : '' }>未超過</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button type="button" class="clear-btn"
|
||||
onclick="location.href='${pageContext.request.contextPath}/lendList'">↻
|
||||
クリア</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="search-card" style="width: 220px;">
|
||||
|
||||
<div class="search-title">並び順</div>
|
||||
|
||||
<select name="sortOrder" onchange="this.form.submit()">
|
||||
<option value="emp_asc" ${sortOrder=='emp_asc' ? 'selected' : '' }>社員ID(昇順)</option>
|
||||
<option value="emp_desc" ${sortOrder=='emp_desc' ? 'selected' : '' }>社員ID(降順)</option>
|
||||
<option value="name_asc" ${sortOrder=='name_asc' ? 'selected' : '' }>名前(50音順)</option>
|
||||
<option value="due_asc" ${empty sortOrder || sortOrder=='due_asc' ? 'selected' : '' }>
|
||||
返却予定日(期限が近い順)</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- 検索結果 -->
|
||||
<div class="result-count">
|
||||
検索結果:
|
||||
<c:out value="${empty lendList ? 0 : lendList.size()}" />
|
||||
件
|
||||
</div>
|
||||
|
||||
<div class="table-card">
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>種別</th>
|
||||
<th>社員ID</th>
|
||||
<th>氏名</th>
|
||||
<th>メールアドレス</th>
|
||||
<th>品名 / タイトル</th>
|
||||
<th>管理ID</th>
|
||||
<th>返却予定日</th>
|
||||
<th>超過日数</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<c:forEach var="item" items="${lendList}">
|
||||
<tr>
|
||||
<td><span class="status status-delay">
|
||||
<c:out value="${item.type}" />
|
||||
</span></td>
|
||||
<td>
|
||||
<c:out value="${item.employeeId}" />
|
||||
</td>
|
||||
<td>
|
||||
<c:out value="${item.employeeName}" />
|
||||
</td>
|
||||
<td>
|
||||
<c:out value="${empty item.email ? '-' : item.email}" />
|
||||
</td>
|
||||
<td>
|
||||
<c:out value="${item.title}" />
|
||||
</td>
|
||||
<td>
|
||||
<c:out value="${item.managementId}" />
|
||||
</td>
|
||||
<td>
|
||||
<c:out value="${item.dueDate}" />
|
||||
</td>
|
||||
<td>
|
||||
<c:choose>
|
||||
<c:when test="${item.overdueDays > 0}">
|
||||
<span class="overdue">
|
||||
<c:out value="${item.overdueDays}" />日
|
||||
</span>
|
||||
</c:when>
|
||||
<c:otherwise>-</c:otherwise>
|
||||
</c:choose>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="return-btn" onclick="openReturnModal(
|
||||
'${item.lendId}',
|
||||
'${item.type}',
|
||||
'<c:out value=" ${item.title}" />',
|
||||
'
|
||||
<c:out value="${item.managementId}" />',
|
||||
'${item.employeeId}',
|
||||
'
|
||||
<c:out value="${item.employeeName}" />'
|
||||
)">返却</button>
|
||||
</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
|
||||
<c:if test="${empty lendList}">
|
||||
<tr>
|
||||
<td colspan="9" style="text-align: center;">現在、貸出中の対象はありません。</td>
|
||||
</tr>
|
||||
</c:if>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ページャ -->
|
||||
<div class="pagination">
|
||||
|
||||
<div>
|
||||
1 -
|
||||
<c:out value="${empty lendList ? 0 : lendList.size()}" />
|
||||
件 /
|
||||
<c:out value="${empty lendList ? 0 : lendList.size()}" />
|
||||
件
|
||||
</div>
|
||||
|
||||
<div class="page-buttons">
|
||||
<button class="page-btn"><</button>
|
||||
<button class="page-btn">></button>
|
||||
<button class="page-btn active">1</button>
|
||||
<button class="page-btn">></button>
|
||||
<button class="page-btn">>></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 注意事項 -->
|
||||
<div class="notice">
|
||||
<div class="notice-title">ⓘ 返却について</div>
|
||||
|
||||
<p>
|
||||
「返却」ボタンを押下すると、貸出の返却処理を行います。<br> 返却処理により、在庫数および貸出ステータスが更新されます。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 返却確認モーダル -->
|
||||
<div id="returnModal" class="modal-overlay">
|
||||
<div class="modal-content">
|
||||
<div class="modal-title">返却確認</div>
|
||||
|
||||
<table class="modal-info-table">
|
||||
<tr>
|
||||
<th id="modalItemLabel">タイトル</th>
|
||||
<td id="modalItemTitle"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th id="modalIdLabel">図書管理ID</th>
|
||||
<td id="modalManagementId"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>社員ID</th>
|
||||
<td id="modalEmployeeId"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>社員名</th>
|
||||
<td id="modalEmployeeName"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="modal-msg">上記内容の返却処理を実行します。よろしいですか?</p>
|
||||
|
||||
<form id="returnForm" action="${pageContext.request.contextPath}/returnBook" method="post">
|
||||
<input type="hidden" name="lendId" id="modalLendId"> <input type="hidden" name="type" id="modalType">
|
||||
<div class="modal-buttons">
|
||||
<button type="submit" class="btn-yes">YES</button>
|
||||
<button type="button" class="btn-no" onclick="closeReturnModal()">NO</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openReturnModal(lendId, type, title, managementId, employeeId,
|
||||
employeeName) {
|
||||
document.getElementById('modalLendId').value = lendId;
|
||||
document.getElementById('modalType').value = type;
|
||||
|
||||
// 備品 / 図書 に応じてラベルを変更
|
||||
if (type === '備品') {
|
||||
document.getElementById('modalItemLabel').innerText = '型番名';
|
||||
document.getElementById('modalIdLabel').innerText = '備品ID';
|
||||
} else {
|
||||
document.getElementById('modalItemLabel').innerText = 'タイトル';
|
||||
document.getElementById('modalIdLabel').innerText = '図書管理ID';
|
||||
}
|
||||
|
||||
document.getElementById('modalItemTitle').innerText = title;
|
||||
document.getElementById('modalManagementId').innerText = managementId;
|
||||
document.getElementById('modalEmployeeId').innerText = employeeId;
|
||||
document.getElementById('modalEmployeeName').innerText = employeeName;
|
||||
|
||||
document.getElementById('returnModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
function closeReturnModal() {
|
||||
document.getElementById('returnModal').style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
335
src/main/resources/templates/login.html
Normal file
335
src/main/resources/templates/login.html
Normal file
@@ -0,0 +1,335 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>ログイン - ShareBooks</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: "Hiragino Kaku Gothic ProN", "Yu Gothic", "Meiryo", sans-serif;
|
||||
background: linear-gradient(160deg, #cfe0f5 0%, #e8f0fa 45%, #d8e6f5 100%);
|
||||
}
|
||||
|
||||
/* ヘッダーバー */
|
||||
.header-bar {
|
||||
background-color: #16325c;
|
||||
color: #ffffff;
|
||||
padding: 18px 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-bar svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* 中央エリア */
|
||||
.content-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 56px 16px 40px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: #ffffff;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
padding: 40px 36px 32px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 18px rgba(20, 40, 70, 0.10);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.book-icon-circle {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin: 0 auto 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.book-icon-circle svg {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
color: #1a56c4;
|
||||
}
|
||||
|
||||
.login-card h1 {
|
||||
font-size: 22px;
|
||||
margin: 0 0 8px;
|
||||
color: #1c2733;
|
||||
}
|
||||
|
||||
.login-card p.subtitle {
|
||||
font-size: 13px;
|
||||
color: #6b7686;
|
||||
margin: 0 0 28px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
text-align: left;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #33404f;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.required-badge {
|
||||
background-color: #e5484d;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
padding: 2px 7px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.input-with-icon {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-with-icon svg.left-icon {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #9aa4b2;
|
||||
}
|
||||
|
||||
.input-with-icon input {
|
||||
width: 100%;
|
||||
padding: 11px 12px 11px 36px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #d7dde5;
|
||||
border-radius: 6px;
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
.input-with-icon input:focus {
|
||||
outline: none;
|
||||
border-color: #1a56c4;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.toggle-password {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #9aa4b2;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
margin-top: 6px;
|
||||
background-color: #1a56c4;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.btn-login svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.btn-login:hover {
|
||||
background-color: #15479f;
|
||||
}
|
||||
|
||||
.forgot-text {
|
||||
font-size: 12px;
|
||||
color: #6b7686;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
background-color: #fdecea;
|
||||
color: #c0392b;
|
||||
font-size: 13px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 18px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* ご利用にあたってボックス */
|
||||
.info-box {
|
||||
max-width: 420px;
|
||||
margin: 18px auto 0;
|
||||
background-color: #eaf2fc;
|
||||
border: 1px solid #d3e3f7;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
font-size: 12px;
|
||||
color: #4a5768;
|
||||
}
|
||||
|
||||
.info-box .info-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: bold;
|
||||
color: #1c2733;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.info-box .info-title svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: #1a56c4;
|
||||
}
|
||||
|
||||
.info-box ul {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
}
|
||||
|
||||
.info-box li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="header-bar">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
||||
</svg>
|
||||
ShareBooks
|
||||
</div>
|
||||
|
||||
<div class="content-wrap">
|
||||
<div>
|
||||
<div class="login-card">
|
||||
<div class="book-icon-circle">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h1>ログイン</h1>
|
||||
<p class="subtitle">社員IDとパスワードを入力して、システムにログインしてください。</p>
|
||||
|
||||
<!-- JSP処理なのでコメントアウト-->
|
||||
<!-- <% if (request.getAttribute("errorMessage") !=null) { %>-->
|
||||
<!-- <div class="error-message">-->
|
||||
<!-- <%= request.getAttribute("errorMessage") %>-->
|
||||
<!-- </div>-->
|
||||
<!-- <% } %>-->
|
||||
|
||||
<form method="post" action="LoginServlet">
|
||||
<div class="form-group">
|
||||
<label for="employeeId">社員ID <span class="required-badge">必須</span></label>
|
||||
<div class="input-with-icon">
|
||||
<svg class="left-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="12" cy="7" r="4" />
|
||||
</svg>
|
||||
<input type="text" id="employeeId" name="employeeId"
|
||||
placeholder="社員IDを入力してください(例:123456)" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">パスワード <span class="required-badge">必須</span></label>
|
||||
<div class="input-with-icon">
|
||||
<svg class="left-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" />
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
||||
</svg>
|
||||
<input type="password" id="password" name="password" placeholder="パスワードを入力してください"
|
||||
required>
|
||||
<button type="button" class="toggle-password" onclick="togglePassword()">
|
||||
<svg id="eyeIcon" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-login">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" />
|
||||
<polyline points="10 17 15 12 10 7" />
|
||||
<line x1="15" y1="12" x2="3" y2="12" />
|
||||
</svg>
|
||||
ログイン
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p class="forgot-text">パスワードお忘れの方は管理者までご連絡ください</p>
|
||||
</div>
|
||||
|
||||
<div class="info-box">
|
||||
<div class="info-title">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<line x1="12" y1="16" x2="12" y2="12" />
|
||||
<line x1="12" y1="8" x2="12.01" y2="8" />
|
||||
</svg>
|
||||
ご利用にあたって
|
||||
</div>
|
||||
<ul>
|
||||
<li>当システムの利用は、当社の業務に関連する方に限定されています。</li>
|
||||
<li>不正なアクセスや利用は、社内規程に基づき厳正に対処します。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function togglePassword() {
|
||||
const input = document.getElementById('password');
|
||||
input.type = (input.type === 'password') ? 'text' : 'password';
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
857
src/main/resources/templates/old_JSP/book_approval_confirm.jsp
Normal file
857
src/main/resources/templates/old_JSP/book_approval_confirm.jsp
Normal file
@@ -0,0 +1,857 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>寄贈申請内容確認</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Yu Gothic", "Meiryo", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #f5f7fa;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
ヘッダー
|
||||
========================= */
|
||||
|
||||
.header {
|
||||
height: 60px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #1b3768;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.notification {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.notification:hover {
|
||||
background: #f0f4fa;
|
||||
}
|
||||
|
||||
.notification-badge {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background: #dc2626;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
.account {
|
||||
padding: 8px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
.account:hover {
|
||||
background: #f0f4fa;
|
||||
color: #1659d4;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
padding: 8px 15px;
|
||||
background: #fff;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s,
|
||||
border-color 0.2s,
|
||||
color 0.2s;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background: #f0f4fa;
|
||||
border-color: #1659d4;
|
||||
color: #1659d4;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
レイアウト
|
||||
========================= */
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 60px);
|
||||
}
|
||||
|
||||
/* =========================
|
||||
サイドメニュー
|
||||
========================= */
|
||||
|
||||
.sidebar {
|
||||
width: 220px;
|
||||
background: #002b66;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
padding: 18px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid rgba(255,255,255,.1);
|
||||
}
|
||||
|
||||
.menu {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu li {
|
||||
padding: 16px 20px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.menu li:hover {
|
||||
background: #0d477f;
|
||||
}
|
||||
|
||||
.menu li.active {
|
||||
background: #1158d8;
|
||||
border-radius: 4px;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
メイン
|
||||
========================= */
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 38px;
|
||||
color: #173a70;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.required-note {
|
||||
color: #d9534f;
|
||||
font-size: 12px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
カード
|
||||
========================= */
|
||||
|
||||
.card {
|
||||
background: #fff;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
color: #1f3a64;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
フォーム
|
||||
========================= */
|
||||
|
||||
.form-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
width: 140px;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
flex: 1;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #d9534f;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: #555;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="date"],
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: 1px solid #d6dbe3;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
font-size: 13px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="date"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
outline: none;
|
||||
border-color: #1659d4;
|
||||
box-shadow: 0 0 0 2px rgba(22, 89, 212, 0.1);
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.help {
|
||||
font-size: 11px;
|
||||
color: #6b7280;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.counter {
|
||||
text-align: right;
|
||||
font-size: 11px;
|
||||
color: #888;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
必須・任意項目の区切り
|
||||
========================= */
|
||||
|
||||
.optional-section {
|
||||
margin-top: 25px;
|
||||
padding-top: 22px;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.optional-section-title {
|
||||
font-weight: bold;
|
||||
color: #1f3a64;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
ボタン
|
||||
========================= */
|
||||
|
||||
.button-area {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-width: 120px;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d1d5db;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.2s,
|
||||
border-color 0.2s,
|
||||
color 0.2s;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #f0f4fa;
|
||||
border-color: #1659d4;
|
||||
color: #1659d4;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #1158d8;
|
||||
border: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #0d47b5;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.right-btns {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
フッター
|
||||
========================= */
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
レスポンシブ
|
||||
========================= */
|
||||
|
||||
@media (max-width: 700px) {
|
||||
|
||||
.header {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.account {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
width: 100%;
|
||||
padding-top: 0;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.input-area {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.button-area {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.right-btns {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
|
||||
.sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.right-btns {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
|
||||
<div class="logo">
|
||||
📖 ShareBooks
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
|
||||
<!-- サインイン中アカウント -->
|
||||
<span class="account">
|
||||
山田 太郎 さん(一般ユーザ)
|
||||
</span>
|
||||
|
||||
<!-- ログアウト -->
|
||||
<button type="button" class="logout-btn">
|
||||
ログアウト
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- =========================
|
||||
サイドメニュー
|
||||
========================= -->
|
||||
|
||||
<aside class="sidebar">
|
||||
|
||||
<div class="sidebar-title">
|
||||
一般メニュー
|
||||
</div>
|
||||
|
||||
<ul class="menu">
|
||||
|
||||
<li>
|
||||
🏠 トップメニュー
|
||||
</li>
|
||||
|
||||
<li class="active">
|
||||
新規図書申請
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</aside>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
メイン
|
||||
========================= -->
|
||||
|
||||
<main class="main">
|
||||
|
||||
<div class="breadcrumb">
|
||||
トップメニュー > 新規図書申請>申請内容確認
|
||||
</div>
|
||||
|
||||
<h1 class="page-title">
|
||||
寄贈申請内容確認
|
||||
</h1>
|
||||
|
||||
<div class="description">
|
||||
入力した内容に間違いがないかご確認ください。よろしければ「申請する」ボタンを押してください。
|
||||
</div>
|
||||
|
||||
<div class="required-note">
|
||||
(※)は必須項目です。
|
||||
</div>
|
||||
|
||||
|
||||
<form action="BookDonationConfirmServlet" method="post">
|
||||
|
||||
<div class="card">
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<!-- =========================
|
||||
申請者情報
|
||||
========================= -->
|
||||
|
||||
<div class="section-title">
|
||||
申請者情報(ログイン中のアカウント情報)
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
社員ID
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value="123456"
|
||||
readonly>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
部署
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value="システム開発部"
|
||||
readonly>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
氏名
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
value="山田 太郎"
|
||||
readonly>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
<hr style="border:1px solid #edf0f2;">
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
必須項目
|
||||
========================= -->
|
||||
|
||||
<div class="section-title">
|
||||
本の情報(必須項目)
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
|
||||
<!-- タイトル -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
<span class="required">(※)</span>
|
||||
タイトル
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name="title"
|
||||
placeholder="タイトルを入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 著者名 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
<span class="required">(※)</span>
|
||||
著者名
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name="author"
|
||||
placeholder="著者名を入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 本の状態 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
<span class="required">(※)</span>
|
||||
本の状態
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<select name="bookCondition">
|
||||
|
||||
<option value="">
|
||||
選択してください
|
||||
</option>
|
||||
|
||||
<option value="0">
|
||||
0:不明
|
||||
</option>
|
||||
|
||||
<option value="1">
|
||||
1:新品同様・ほぼ未使用
|
||||
</option>
|
||||
|
||||
<option value="2">
|
||||
2:良好・目立つ傷や汚れ無し
|
||||
</option>
|
||||
|
||||
<option value="3">
|
||||
3:使用感あり・多少の折れ、擦れあり
|
||||
</option>
|
||||
|
||||
<option value="4">
|
||||
4:傷みあり・目立つ傷、汚れ、書き込みあり
|
||||
</option>
|
||||
|
||||
</select>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
任意項目
|
||||
========================= -->
|
||||
|
||||
<div class="optional-section">
|
||||
|
||||
<div class="optional-section-title">
|
||||
本の情報(任意項目)
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-grid">
|
||||
|
||||
<!-- 出版社 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
出版社
|
||||
<span class="optional">(任意)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name="publisher"
|
||||
placeholder="出版社を入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ISBN -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
ISBN
|
||||
<span class="optional">(任意)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="text"
|
||||
name="isbn"
|
||||
placeholder="ISBNがある場合は入力してください">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="help">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 出版日 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
出版日
|
||||
<span class="optional">(任意)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<input
|
||||
type="date"
|
||||
name="publishDate">
|
||||
|
||||
<div class="help">
|
||||
※出版日が分かる場合に入力してください。
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 備考 -->
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<label>
|
||||
備考
|
||||
<span class="optional">(任意)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-area">
|
||||
|
||||
<textarea
|
||||
name="remarks"
|
||||
placeholder="付属品の有無(CD/DVD等)や、本の概要が分かるAmazon等のURLなどをご記入ください"></textarea>
|
||||
|
||||
<div class="counter">
|
||||
0 / 300
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
ボタン
|
||||
========================= -->
|
||||
|
||||
<div class="button-area">
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn">
|
||||
|
||||
トップメニューへ戻る
|
||||
|
||||
</button>
|
||||
|
||||
|
||||
<div class="right-btns">
|
||||
|
||||
<button
|
||||
type="reset"
|
||||
class="btn">
|
||||
|
||||
修正
|
||||
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary">
|
||||
|
||||
確定
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
© 2026 社内備品・図書管理システム
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
762
src/main/resources/templates/old_JSP/book_insert_confirm.jsp
Normal file
762
src/main/resources/templates/old_JSP/book_insert_confirm.jsp
Normal file
@@ -0,0 +1,762 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>登録内容確認</title>
|
||||
|
||||
<style>
|
||||
|
||||
*{
|
||||
margin:0;
|
||||
padding:0;
|
||||
box-sizing:border-box;
|
||||
font-family:"Yu Gothic","Meiryo",sans-serif;
|
||||
}
|
||||
|
||||
body{
|
||||
background:#f5f7fa;
|
||||
color:#333;
|
||||
}
|
||||
|
||||
/* ヘッダー */
|
||||
|
||||
.header{
|
||||
height:60px;
|
||||
background:#fff;
|
||||
border-bottom:1px solid #e5e7eb;
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
padding:0 20px;
|
||||
}
|
||||
|
||||
.logo{
|
||||
font-size:18px;
|
||||
font-weight:bold;
|
||||
color:#173a70;
|
||||
}
|
||||
|
||||
.header-right{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:20px;
|
||||
}
|
||||
|
||||
.logout-btn{
|
||||
padding:8px 16px;
|
||||
border:1px solid #d0d7de;
|
||||
background:#fff;
|
||||
border-radius:4px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
/* レイアウト */
|
||||
|
||||
.wrapper{
|
||||
display:flex;
|
||||
min-height:calc(100vh - 60px);
|
||||
}
|
||||
|
||||
/* サイドバー */
|
||||
|
||||
.sidebar{
|
||||
width:220px;
|
||||
background:#002b66;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.sidebar-title{
|
||||
padding:18px;
|
||||
border-bottom:1px solid rgba(255,255,255,.1);
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
.menu{
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
.menu li{
|
||||
padding:16px 20px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transition:
|
||||
background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.menu li:hover {
|
||||
background: #0c438f;
|
||||
}
|
||||
|
||||
.menu li.active{
|
||||
background: #1659d4;
|
||||
}
|
||||
|
||||
/* メイン */
|
||||
|
||||
.main{
|
||||
flex:1;
|
||||
padding:24px;
|
||||
}
|
||||
|
||||
.breadcrumb{
|
||||
font-size:12px;
|
||||
color:#6b7280;
|
||||
margin-bottom:18px;
|
||||
}
|
||||
|
||||
.page-title{
|
||||
font-size:42px;
|
||||
font-weight:bold;
|
||||
color:#173a70;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
.description{
|
||||
font-size:14px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
/* カード */
|
||||
|
||||
.card{
|
||||
background:#fff;
|
||||
border:1px solid #e5e7eb;
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.card-header{
|
||||
padding:14px 18px;
|
||||
border-bottom:1px solid #e5e7eb;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.content{
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
/* 確認テーブル */
|
||||
|
||||
.confirm-table{
|
||||
width:100%;
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
.confirm-table th,
|
||||
.confirm-table td{
|
||||
padding:16px 12px;
|
||||
border-bottom:1px solid #edf0f2;
|
||||
text-align:left;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.confirm-table th{
|
||||
width:15%;
|
||||
color:#1f3a64;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.confirm-table td{
|
||||
width:35%;
|
||||
}
|
||||
|
||||
.help-text{
|
||||
display:block;
|
||||
margin-top:5px;
|
||||
font-size:11px;
|
||||
color:#777;
|
||||
}
|
||||
|
||||
/* 確認事項 */
|
||||
|
||||
.notice-box{
|
||||
margin-top:18px;
|
||||
background:#fff9ea;
|
||||
border-top:1px solid #efdfaa;
|
||||
padding:18px;
|
||||
}
|
||||
|
||||
.notice-title{
|
||||
font-weight:bold;
|
||||
margin-bottom:10px;
|
||||
color:#173a70;
|
||||
}
|
||||
|
||||
.notice-box ul{
|
||||
margin-left:18px;
|
||||
}
|
||||
|
||||
.notice-box li{
|
||||
margin-bottom:8px;
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
/* ボタン */
|
||||
|
||||
.button-area{
|
||||
margin-top:18px;
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.btn{
|
||||
min-width:120px;
|
||||
padding:10px 20px;
|
||||
border-radius:4px;
|
||||
border:1px solid #d0d7de;
|
||||
background:#fff;
|
||||
cursor:pointer;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.btn-primary{
|
||||
background:#1158d8;
|
||||
color:#fff;
|
||||
border:none;
|
||||
}
|
||||
|
||||
.right-buttons{
|
||||
display:flex;
|
||||
gap:12px;
|
||||
}
|
||||
|
||||
.footer{
|
||||
text-align:center;
|
||||
color:#666;
|
||||
font-size:12px;
|
||||
margin-top:28px;
|
||||
}
|
||||
|
||||
/* 登録完了ポップアップ */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.modal {
|
||||
width: 460px;
|
||||
background: #fff;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.modal-message {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #173a70;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.modal-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.modal-buttons form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modal-btn {
|
||||
min-width: 150px;
|
||||
padding: 11px 20px;
|
||||
|
||||
border: 1px solid #d0d7de;
|
||||
border-radius: 4px;
|
||||
|
||||
background: #fff;
|
||||
color: #333;
|
||||
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-btn:hover {
|
||||
background: #f1f5fa;
|
||||
border-color: #1659d4;
|
||||
color: #1659d4;
|
||||
}
|
||||
|
||||
.modal-btn-primary {
|
||||
background: #1158d8;
|
||||
border-color: #1158d8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.modal-btn-primary:hover {
|
||||
background: #0d47b5;
|
||||
border-color: #0d47b5;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header class="header">
|
||||
|
||||
<div class="logo">
|
||||
📖 ShareBooks
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
|
||||
<span>
|
||||
山田 太郎 さん(管理者)
|
||||
</span>
|
||||
|
||||
<form method="post"
|
||||
action="${pageContext.request.contextPath}/logout"
|
||||
style="display:inline;">
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="logout-btn"
|
||||
onclick="return confirmLogout()">
|
||||
ログアウト
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- =========================
|
||||
Sidebar
|
||||
========================= -->
|
||||
|
||||
<aside class="sidebar">
|
||||
|
||||
<div class="sidebar-title">
|
||||
管理者画面
|
||||
</div>
|
||||
|
||||
<ul class="menu">
|
||||
|
||||
<li onclick="goTopMenu()">
|
||||
🏠 トップメニュー
|
||||
</li>
|
||||
|
||||
<li class="active">
|
||||
➕ 新規図書登録
|
||||
</li>
|
||||
|
||||
<li onclick="goBook()">
|
||||
📚 社内図書一覧
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</aside>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Main
|
||||
========================= -->
|
||||
|
||||
<main class="main">
|
||||
|
||||
<div class="breadcrumb">
|
||||
トップメニュー > 新規図書登録 > 図書登録内容確認
|
||||
</div>
|
||||
|
||||
|
||||
<h1 class="page-title">
|
||||
図書登録内容確認
|
||||
</h1>
|
||||
|
||||
|
||||
<div class="description">
|
||||
入力した内容に間違いがないかご確認ください。
|
||||
よろしければ「登録する」ボタンを押してください。
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
登録処理用Form
|
||||
========================= -->
|
||||
|
||||
<form method="post"
|
||||
action="${pageContext.request.contextPath}/insertBook">
|
||||
|
||||
<div class="card">
|
||||
|
||||
<div class="card-header">
|
||||
図書情報
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content">
|
||||
|
||||
<table class="confirm-table">
|
||||
|
||||
<!-- =========================
|
||||
図書管理ID
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>図書管理ID</th>
|
||||
<td>
|
||||
${book.bookManageId}
|
||||
|
||||
<span class="help-text">
|
||||
※自動採番されます(例:BK0001、BK0002、...)
|
||||
</span>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="bookManageId"
|
||||
value="${book.bookManageId}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
登録日
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>登録日</th>
|
||||
<td>
|
||||
${registeredAt}
|
||||
|
||||
<span class="help-text">
|
||||
※自動取得されます
|
||||
</span>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="registeredAt"
|
||||
value="${registeredAt}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
タイトル
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>タイトル</th>
|
||||
<td>
|
||||
${book.title}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="title"
|
||||
value="${book.title}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
著者名
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>著者名</th>
|
||||
<td>
|
||||
${book.author}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="author"
|
||||
value="${book.author}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
カテゴリ
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>カテゴリ</th>
|
||||
<td>
|
||||
${book.categoryName}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="categoryId"
|
||||
value="${book.categoryId}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
サブカテゴリ
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>サブカテゴリ</th>
|
||||
<td>
|
||||
${book.subcategoryName}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="bookSubcategoryId"
|
||||
value="${book.bookSubcategoryId}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
ISBN
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>ISBN</th>
|
||||
<td>
|
||||
${book.isbn}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="isbn"
|
||||
value="${book.isbn}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
出版社
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>出版社</th>
|
||||
<td>
|
||||
${book.publisher}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="publisher"
|
||||
value="${book.publisher}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
出版日
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>出版日</th>
|
||||
<td>
|
||||
${book.publicationDate}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="publishDate"
|
||||
value="${book.publicationDate}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
保管場所
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>保管場所</th>
|
||||
<td>
|
||||
${book.locationName}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="locationId"
|
||||
value="${book.locationId}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
寄贈者
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>寄贈者(任意)</th>
|
||||
<td>
|
||||
${book.donorId}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="donorId"
|
||||
value="${book.donorId}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
備考
|
||||
========================= -->
|
||||
<tr>
|
||||
<th>備考(任意)</th>
|
||||
<td>
|
||||
${book.description}
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="description"
|
||||
value="${book.description}">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<!-- =========================
|
||||
確認事項
|
||||
========================= -->
|
||||
|
||||
<div class="notice-box">
|
||||
|
||||
<div class="notice-title">
|
||||
確認事項
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
登録後、図書一覧に表示されます。
|
||||
</li>
|
||||
|
||||
<li>
|
||||
登録内容は、図書の管理や検索に利用されますので、
|
||||
正確に登録してください。
|
||||
</li>
|
||||
|
||||
<li>
|
||||
登録後に内容を変更する場合は、
|
||||
図書情報編集画面から行ってください。
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =========================
|
||||
Buttons
|
||||
========================= -->
|
||||
|
||||
<div class="button-area">
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn"
|
||||
onclick="history.back();">
|
||||
|
||||
入力画面へ戻る
|
||||
|
||||
</button>
|
||||
|
||||
|
||||
<div class="right-buttons">
|
||||
|
||||
<button
|
||||
type="reset"
|
||||
class="btn">
|
||||
|
||||
クリア
|
||||
|
||||
</button>
|
||||
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
name="action"
|
||||
value="register"
|
||||
class="btn btn-primary">
|
||||
|
||||
登録する
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
© 2026 社内備品・図書管理システム
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<% if (request.getAttribute("registerSuccess") != null) { %>
|
||||
|
||||
<div id="registerModal" class="modal-overlay">
|
||||
|
||||
<div class="modal">
|
||||
|
||||
<div class="modal-message">
|
||||
新規図書の登録が完了しました!
|
||||
</div>
|
||||
|
||||
<div class="modal-buttons">
|
||||
|
||||
<!-- 続けて追加 -->
|
||||
<form method="get"
|
||||
action="${pageContext.request.contextPath}/insertBook">
|
||||
|
||||
<button type="submit" class="modal-btn">
|
||||
続けて追加
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
<!-- 図書一覧へ戻る -->
|
||||
<form method="get"
|
||||
action="${pageContext.request.contextPath}/BookServlet">
|
||||
|
||||
<button type="submit"
|
||||
class="modal-btn modal-btn-primary">
|
||||
図書一覧へ戻る
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<% } %>
|
||||
|
||||
<script>
|
||||
function confirmLogout(){
|
||||
|
||||
const result = window.confirm("本当にログアウトしてよろしいですか?");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function goTopMenu() {
|
||||
location.href = "${pageContext.request.contextPath}/topmenu.jsp";
|
||||
}
|
||||
|
||||
function goBook() {
|
||||
location.href = "${pageContext.request.contextPath}/book.jsp";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
729
src/main/resources/templates/old_JSP/book_lend.jsp
Normal file
729
src/main/resources/templates/old_JSP/book_lend.jsp
Normal file
@@ -0,0 +1,729 @@
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ page import="bookequ_manage_system.entity.Account"%>
|
||||
<%@ page import="bookequ_manage_system.entity.Book"%>
|
||||
|
||||
<%@ page import="java.util.List"%>
|
||||
<%-- EmployeeクラスまたはAccountクラスのパッケージを指定 --%>
|
||||
<%@ page import="bookequ_manage_system.entity.Account"%>
|
||||
|
||||
<%
|
||||
// サーブレットから渡された社員リストを取得
|
||||
List<Account> employeeList = (List<Account>) request.getAttribute("employeeList");
|
||||
%>
|
||||
|
||||
<%
|
||||
/*
|
||||
* LoginServletで保存されたAccountをセッションから取得する。
|
||||
* JSPには暗黙的に session が用意されているため、
|
||||
* HttpSession session = ... のような宣言はしない。
|
||||
*/
|
||||
if (session.getAttribute("account") == null) {
|
||||
response.sendRedirect(request.getContextPath() + "/login.jsp");
|
||||
return;
|
||||
}
|
||||
|
||||
Account account = (Account) session.getAttribute("account");
|
||||
|
||||
/*
|
||||
* Account.java の adminFlag を利用する。
|
||||
* 1 = 管理者
|
||||
* 0 = 一般ユーザ
|
||||
*/
|
||||
boolean isAdmin = account.getAdminFlag() == 1;
|
||||
int employeeId = account.getEmployeeId();
|
||||
String roleName = isAdmin ? "管理者" : "一般ユーザ";
|
||||
|
||||
/*
|
||||
* LoginServletでセッションに保存した社員名を取得する。
|
||||
* topmenu.jsp / book.jsp と同じ employeeName を使用する。
|
||||
* 社員名がセッションにない場合は社員IDを表示する。
|
||||
*/
|
||||
Object employeeNameObject = session.getAttribute("employeeName");
|
||||
String employeeName;
|
||||
|
||||
if (employeeNameObject != null && !employeeNameObject.toString().trim().isEmpty()) {
|
||||
employeeName = employeeNameObject.toString();
|
||||
} else {
|
||||
employeeName = "社員ID:" + employeeId;
|
||||
}
|
||||
|
||||
/*
|
||||
* BookLendServletから request.setAttribute("book", book) で渡された
|
||||
* 貸出対象の図書情報を受け取る。
|
||||
*/
|
||||
Book book = (Book) request.getAttribute("book");
|
||||
|
||||
String bookManageId = "";
|
||||
String title = "";
|
||||
String author = "";
|
||||
String isbn = "";
|
||||
|
||||
if (book != null) {
|
||||
bookManageId = book.getBookManageId() != null ? book.getBookManageId() : "";
|
||||
title = book.getTitle() != null ? book.getTitle() : "";
|
||||
author = book.getAuthor() != null ? book.getAuthor() : "";
|
||||
isbn = (book.getIsbn() != null && !book.getIsbn().trim().isEmpty()) ? book.getIsbn() : "-";
|
||||
}
|
||||
%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>図書貸出処理</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Yu Gothic", "Meiryo", sans-serif;
|
||||
color: #18243a;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
button, input, select {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* ===== ヘッダー:topmenu.jsp / book.jsp と統一 ===== */
|
||||
.header {
|
||||
height: 56px;
|
||||
border-bottom: 1px solid #d8e0e8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 18px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 21px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.book-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.bell {
|
||||
font-size: 21px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -6px;
|
||||
background: #e33;
|
||||
color: #fff;
|
||||
border-radius: 9px;
|
||||
min-width: 12px;
|
||||
height: 12px;
|
||||
line-height: 12px;
|
||||
text-align: center;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.user {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #a8b3c0;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logout:hover {
|
||||
background: #f2f5f8;
|
||||
}
|
||||
|
||||
/* ===== レイアウト ===== */
|
||||
.layout {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
/* ===== サイドバー:book.jsp と統一 ===== */
|
||||
.sidebar {
|
||||
width: 180px;
|
||||
flex: 0 0 180px;
|
||||
background: #082957;
|
||||
color: #fff;
|
||||
padding: 10px 7px;
|
||||
}
|
||||
|
||||
.side-label {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin: 3px 7px 10px;
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
min-height: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
padding: 0 7px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.side-menu:hover {
|
||||
background: #104c91;
|
||||
}
|
||||
|
||||
.side-menu.active {
|
||||
background: #1267d9;
|
||||
}
|
||||
|
||||
.side-icon {
|
||||
font-size: 15px;
|
||||
width: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ===== メイン ===== */
|
||||
.content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 16px 20px 30px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 12px;
|
||||
color: #657184;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.breadcrumb span {
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 26px;
|
||||
margin: 0 0 4px;
|
||||
color: #143a70;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #4d596b;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
|
||||
/* ===== カード ===== */
|
||||
.card {
|
||||
background: #fff;
|
||||
border: 1px solid #e0e5eb;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 14px;
|
||||
box-shadow: 0 1px 4px rgba(30, 52, 77, 0.06);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 10px 13px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid #e0e5eb;
|
||||
background: #fafbfd;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
/* ===== 図書情報 ===== */
|
||||
.info-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.info-table th, .info-table td {
|
||||
border: 1px solid #e0e5eb;
|
||||
padding: 9px 12px;
|
||||
text-align: left;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.info-table th {
|
||||
width: 160px;
|
||||
background: #f5f7fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* ===== 入力欄 ===== */
|
||||
.form-row {
|
||||
margin-bottom: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-row label {
|
||||
width: 110px;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
input[type="text"], input[type="date"], select {
|
||||
width: 320px;
|
||||
height: 38px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
input:focus, select:focus {
|
||||
outline: none;
|
||||
border-color: #1267d9;
|
||||
box-shadow: 0 0 0 2px rgba(18, 103, 217, 0.10);
|
||||
}
|
||||
|
||||
.loan-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 24px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.loan-box {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.loan-box label {
|
||||
display: block;
|
||||
margin-bottom: 7px;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.loan-box input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #e5484d;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.note {
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
margin-top: 5px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #e5484d;
|
||||
margin-top: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.warning-area {
|
||||
background-color: #fff8e8;
|
||||
padding: 12px 15px;
|
||||
border-top: 1px solid #f0e1a1;
|
||||
color: #555;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.warning-area ul {
|
||||
margin: 5px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== ボタン ===== */
|
||||
.button-area {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-height: 36px;
|
||||
padding: 7px 18px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #c8d0da;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #f3f6f9;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #1267d9;
|
||||
color: #fff;
|
||||
border: 1px solid #1267d9;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #0d58bd;
|
||||
}
|
||||
|
||||
.right-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* ===== レスポンシブ ===== */
|
||||
@media ( max-width : 900px) {
|
||||
.header-right {
|
||||
gap: 8px;
|
||||
}
|
||||
.user {
|
||||
font-size: 12px;
|
||||
}
|
||||
.loan-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media ( max-width : 650px) {
|
||||
.sidebar {
|
||||
width: 150px;
|
||||
flex-basis: 150px;
|
||||
}
|
||||
.header-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.bell, .user {
|
||||
display: none;
|
||||
}
|
||||
.content {
|
||||
padding: 12px;
|
||||
}
|
||||
.form-row {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.form-row label {
|
||||
width: auto;
|
||||
}
|
||||
input[type="text"], input[type="date"], select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- ===== ヘッダー ===== -->
|
||||
<header class="header">
|
||||
<div class="header-title">
|
||||
<span class="book-icon">📖</span> ShareBooks
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
|
||||
<!-- topmenu.jsp / book.jsp と同じセッションの社員名を表示 -->
|
||||
<span class="user"><%=employeeName%>(<%=roleName%>)</span>
|
||||
|
||||
<!-- ログアウト確認後、/logout → セッション破棄 → login.jsp を想定 -->
|
||||
<form action="${pageContext.request.contextPath}/logout"
|
||||
method="post" onsubmit="return confirm('ログアウトしますか?');">
|
||||
<button type="submit" class="logout">ログアウト</button>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="layout">
|
||||
|
||||
<!-- ===== サイドバー ===== -->
|
||||
<aside class="sidebar">
|
||||
<div class="side-label">
|
||||
<%=isAdmin ? "共通画面" : "一般メニュー"%>
|
||||
</div>
|
||||
|
||||
<!-- トップメニュー → topmenu.jsp -->
|
||||
<a class="side-menu"
|
||||
href="${pageContext.request.contextPath}/topmenu.jsp"> <span
|
||||
class="side-icon">⌂</span> トップメニュー
|
||||
</a>
|
||||
|
||||
<%
|
||||
if (isAdmin) {
|
||||
%>
|
||||
<!-- 管理者のみ新規図書登録を表示(book.jsp と同じ構成) -->
|
||||
<a class="side-menu"
|
||||
href="${pageContext.request.contextPath}/book/registration"> <span
|
||||
class="side-icon">⊞</span> 新規図書登録
|
||||
</a>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
|
||||
<!-- 社内図書一覧 → BookServlet -->
|
||||
<a class="side-menu active"
|
||||
href="${pageContext.request.contextPath}/BookServlet"> <span
|
||||
class="side-icon">📖</span> 社内図書一覧
|
||||
</a>
|
||||
</aside>
|
||||
|
||||
<!-- ===== メイン ===== -->
|
||||
<main class="content">
|
||||
|
||||
<div class="breadcrumb">
|
||||
<a href="${pageContext.request.contextPath}/topmenu.jsp">トップメニュー</a>
|
||||
<span>›</span> <a
|
||||
href="${pageContext.request.contextPath}/BookServlet">社内図書一覧</a> <span>›</span>
|
||||
図書貸出処理
|
||||
</div>
|
||||
|
||||
<h1 class="title">図書貸出処理</h1>
|
||||
|
||||
<p class="description">以下の図書を貸出します。貸出先と貸出日・返却予定日を入力してください。</p>
|
||||
|
||||
<!-- ===== DB更新用の form エリア(ここから開始) ===== -->
|
||||
<form id="loanForm"
|
||||
action="${pageContext.request.contextPath}/book/loan" method="post">
|
||||
|
||||
<!-- サーブレットへ送信する隠し図書ID(数値IDおよび管理ID) -->
|
||||
<input type="hidden" name="bookId"
|
||||
value="<%=book != null ? book.getBookId() : ""%>"> <input
|
||||
type="hidden" name="bookManageId" value="<%=bookManageId%>">
|
||||
|
||||
<!-- ===== 図書情報 ===== -->
|
||||
<div class="card">
|
||||
<div class="card-header">図書情報</div>
|
||||
|
||||
<div class="card-body">
|
||||
<table class="info-table">
|
||||
<tr>
|
||||
<th>図書管理ID</th>
|
||||
<td><%=bookManageId%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>タイトル</th>
|
||||
<td><%=title%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>著者名</th>
|
||||
<td><%=author%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ISBN</th>
|
||||
<td><%=isbn%></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 社員情報 ===== -->
|
||||
<div class="card">
|
||||
<div class="card-header">社員情報</div>
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="form-row">
|
||||
<label for="employeeSelect">社員ID</label> <select
|
||||
id="employeeSelect" name="employeeId"
|
||||
onchange="updateEmployeeName()">
|
||||
<option value="">社員IDを選択してください</option>
|
||||
<%
|
||||
if (employeeList != null) {
|
||||
for (Account emp : employeeList) {
|
||||
%>
|
||||
<option value="<%=emp.getEmployeeId()%>"
|
||||
data-name="<%=emp.getEmployeeName()%>">
|
||||
<%=emp.getEmployeeId()%>
|
||||
</option>
|
||||
<%
|
||||
}
|
||||
}
|
||||
%>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label for="employeeName">社員名</label> <input type="text"
|
||||
id="employeeName" value="" placeholder="社員名が表示されます" readonly>
|
||||
</div>
|
||||
|
||||
<hr
|
||||
style="margin: 18px 0; border: 0; border-top: 1px solid #e5e9ef;">
|
||||
|
||||
<div class="loan-section">
|
||||
|
||||
<div class="loan-box">
|
||||
<label> 貸出日 <span class="required">(自動取得)</span>
|
||||
</label> <input type="date" id="loanDate" name="loanDate" value="">
|
||||
<div class="note">※ 現在の日付が自動で設定されます。</div>
|
||||
</div>
|
||||
|
||||
<div class="loan-box">
|
||||
<label> 貸出期間日数 <span class="required">(任意)</span>
|
||||
</label> <input type="text" id="loanDays" placeholder="日数を入力してください">
|
||||
<div class="note">※ 数値(1以上)で入力してください。</div>
|
||||
</div>
|
||||
|
||||
<div class="loan-box">
|
||||
<label> 返却予定日 <span class="required">(必須)</span>
|
||||
</label> <input type="date" id="returnDate" name="returnDate">
|
||||
<div class="note">※ カレンダーから日付を選択してください。</div>
|
||||
<div class="error">※ 現在の日付より前は選択できません。</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="warning-area">
|
||||
<strong>注意事項</strong>
|
||||
<ul>
|
||||
<li>貸出処理を行うと、対象の図書のステータスが「貸出中」に変更されます。</li>
|
||||
<li>返却予定日を必ず指定してください。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="button-area">
|
||||
<a class="btn"
|
||||
href="${pageContext.request.contextPath}/BookServlet">図書一覧へ戻る</a>
|
||||
|
||||
<div class="right-buttons">
|
||||
<button type="button" class="btn" onclick="clearForm()">クリア</button>
|
||||
<button type="button" class="btn btn-primary"
|
||||
onclick="submitLoan()">貸出する</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<!-- ===== DB更新用の form エリア(ここまで) ===== -->
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 社員ID選択時に社員名を自動セット ===== */
|
||||
function updateEmployeeName() {
|
||||
const select = document.getElementById('employeeSelect');
|
||||
const selectedOption = select.options[select.selectedIndex];
|
||||
|
||||
// selectされたoptionタグから data-name 属性の値(社員名)を取得
|
||||
const name = selectedOption.getAttribute('data-name');
|
||||
|
||||
// 社員名欄に反映(未選択の場合は空文字)
|
||||
document.getElementById('employeeName').value = name ? name : '';
|
||||
}
|
||||
/* ===== 貸出日を現在日に設定 ===== */
|
||||
(function() {
|
||||
const today = new Date();
|
||||
const yyyy = today.getFullYear();
|
||||
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(today.getDate()).padStart(2, '0');
|
||||
const todayString = yyyy + '-' + mm + '-' + dd;
|
||||
|
||||
const loanDate = document.getElementById('loanDate');
|
||||
const returnDate = document.getElementById('returnDate');
|
||||
|
||||
loanDate.value = todayString;
|
||||
returnDate.min = todayString;
|
||||
})();
|
||||
|
||||
/* ===== 貸出期間日数から返却予定日を計算 ===== */
|
||||
document.getElementById('loanDays')
|
||||
.addEventListener(
|
||||
'input',
|
||||
function() {
|
||||
const days = parseInt(this.value, 10);
|
||||
const loanDateValue = document
|
||||
.getElementById('loanDate').value;
|
||||
|
||||
if (Number.isNaN(days) || days < 1
|
||||
|| !loanDateValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
const date = new Date(loanDateValue + 'T00:00:00');
|
||||
date.setDate(date.getDate() + days);
|
||||
|
||||
const yyyy = date.getFullYear();
|
||||
const mm = String(date.getMonth() + 1).padStart(2,
|
||||
'0');
|
||||
const dd = String(date.getDate()).padStart(2, '0');
|
||||
|
||||
document.getElementById('returnDate').value = yyyy
|
||||
+ '-' + mm + '-' + dd;
|
||||
});
|
||||
|
||||
/* ===== クリア ===== */
|
||||
function clearForm() {
|
||||
document.getElementById('employeeSelect').selectedIndex = 0;
|
||||
document.getElementById('employeeName').value = '';
|
||||
document.getElementById('loanDays').value = '';
|
||||
document.getElementById('returnDate').value = '';
|
||||
|
||||
const today = new Date();
|
||||
const yyyy = today.getFullYear();
|
||||
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(today.getDate()).padStart(2, '0');
|
||||
document.getElementById('loanDate').value = yyyy + '-' + mm + '-'
|
||||
+ dd;
|
||||
}
|
||||
|
||||
/* ===== 貸出ボタン ===== */
|
||||
function submitLoan() {
|
||||
const employeeId = document.getElementById('employeeSelect').value;
|
||||
const returnDate = document.getElementById('returnDate').value;
|
||||
|
||||
if (!employeeId) {
|
||||
alert('社員IDを選択してください。');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!returnDate) {
|
||||
alert('返却予定日を入力してください。');
|
||||
return;
|
||||
}
|
||||
|
||||
if (confirm('この図書を貸出しますか?')) {
|
||||
// OK選択時にフォーム送信を実行し、DB処理へ遷移
|
||||
document.getElementById('loanForm').submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
753
src/main/resources/templates/old_JSP/book_update.jsp
Normal file
753
src/main/resources/templates/old_JSP/book_update.jsp
Normal file
@@ -0,0 +1,753 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<%@ page import="bookequ_manage_system.entity.Account"%>
|
||||
<%@ page import="bookequ_manage_system.entity.Book"%>
|
||||
<%@ page import="java.text.SimpleDateFormat"%>
|
||||
|
||||
<%
|
||||
if (session.getAttribute("account") == null) {
|
||||
response.sendRedirect(request.getContextPath() + "/login.jsp");
|
||||
return;
|
||||
}
|
||||
|
||||
Account account = (Account) session.getAttribute("account");
|
||||
boolean isAdmin = account.getAdminFlag() == 1;
|
||||
int employeeId = account.getEmployeeId();
|
||||
String roleName = isAdmin ? "管理者" : "一般ユーザ";
|
||||
|
||||
// サーブレットから受け取ったBookオブジェクト
|
||||
Book book = (Book) request.getAttribute("book");
|
||||
if (book == null) {
|
||||
book = new Book();
|
||||
}
|
||||
|
||||
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||
SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy/MM/dd HH:mm");
|
||||
%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>【図書】情報更新入力</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
font-family: "Noto Sans JP", "Yu Gothic", "YuGothic", "Meiryo", Arial,
|
||||
sans-serif;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
height: 58px;
|
||||
border-bottom: 1px solid #d8e0e8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 18px 0 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.user {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.bell {
|
||||
font-size: 22px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
right: -5px;
|
||||
background: #e33;
|
||||
color: #fff;
|
||||
border-radius: 9px;
|
||||
font-size: 8px;
|
||||
min-width: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #a8b3c0;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Main layout */
|
||||
.main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
width: 116px;
|
||||
flex: 0 0 150px;
|
||||
background: #002d5b;
|
||||
color: #fff;
|
||||
padding-top: 17px;
|
||||
}
|
||||
|
||||
.side-title {
|
||||
padding: 0 12px 10px;
|
||||
font-size: 8px;
|
||||
color: #d9e4f0;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 12px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu-item.active {
|
||||
background: #1264b4;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Content */
|
||||
.content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 17px 14px 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 8px;
|
||||
color: #6f8094;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.breadcrumb span {
|
||||
margin: 0 5px;
|
||||
color: #9aa4ae;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 2px 0 13px;
|
||||
font-size: 9px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
/* Form card */
|
||||
.form-card {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 3px;
|
||||
padding: 13px 11px 15px;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, .02);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin: 0 0 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.system-info-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
column-gap: 34px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.input-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.optional-fields {
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: grid;
|
||||
grid-template-columns: 76px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #e53935;
|
||||
font-size: 8px;
|
||||
margin-left: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: #333;
|
||||
font-size: 8px;
|
||||
margin-left: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.control {
|
||||
width: 100%;
|
||||
height: 28px;
|
||||
padding: 0 9px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
font-size: 9px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.control:focus {
|
||||
border-color: #2d6fb7;
|
||||
box-shadow: 0 0 0 2px rgba(45, 111, 183, .08);
|
||||
}
|
||||
|
||||
.control[readonly] {
|
||||
background: #f3f5f8;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
select.control {
|
||||
appearance: auto;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
input[type="date"].control {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.with-note {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.with-note .control {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.note {
|
||||
flex: 0 0 auto;
|
||||
color: #777;
|
||||
font-size: 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Memo */
|
||||
.memo-section {
|
||||
margin-top: 16px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 3px;
|
||||
padding: 12px 11px 14px;
|
||||
}
|
||||
|
||||
.memo-row {
|
||||
display: grid;
|
||||
grid-template-columns: 76px minmax(0, 1fr) 82px;
|
||||
gap: 8px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
textarea.control {
|
||||
height: 60px;
|
||||
resize: vertical;
|
||||
padding: 8px 9px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.memo-note {
|
||||
color: #777;
|
||||
font-size: 8px;
|
||||
padding-top: 7px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Bottom area */
|
||||
.bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
min-width: 82px;
|
||||
height: 30px;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.clear-button, .confirm-button {
|
||||
height: 30px;
|
||||
min-width: 70px;
|
||||
border-radius: 3px;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.clear-button {
|
||||
border: 1px solid #c7c7c7;
|
||||
background: #fff;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.confirm-button {
|
||||
min-width: 86px;
|
||||
border: 1px solid #005bb5;
|
||||
background: #0967c3;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.confirm-button:hover {
|
||||
background: #0759aa;
|
||||
}
|
||||
|
||||
.clear-button:hover, .back-button:hover {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.help {
|
||||
margin-top: 7px;
|
||||
font-size: 8px;
|
||||
color: #3975ad;
|
||||
}
|
||||
|
||||
.help::before {
|
||||
content: "●";
|
||||
font-size: 5px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page">
|
||||
<header class="header">
|
||||
<div class="header-title">
|
||||
<span class="book-icon">📖</span> ShareBooks
|
||||
</div>
|
||||
<div class="header-right">
|
||||
|
||||
<span class="user">
|
||||
<%=session.getAttribute("employeeName")%>(<%=roleName%>)
|
||||
</span>
|
||||
|
||||
<form action="${pageContext.request.contextPath}/logout"
|
||||
method="post" onsubmit="return confirm('ログアウトしますか?');">
|
||||
<button type="submit" class="logout">ログアウト</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="main">
|
||||
<aside class="sidebar">
|
||||
<div class="side-title">管理者画面</div>
|
||||
<div class="menu-item"
|
||||
onclick="location.href='${pageContext.request.contextPath}/topmenu.jsp';"
|
||||
style="cursor: pointer;">
|
||||
<span class="menu-icon">🏠</span><span>トップメニュー</span>
|
||||
</div>
|
||||
<div class="menu-item active"
|
||||
onclick="location.href='${pageContext.request.contextPath}/BookServlet';"
|
||||
style="cursor: pointer;">
|
||||
<span class="menu-icon">📖</span><span>社内図書一覧</span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="content">
|
||||
<div class="breadcrumb">
|
||||
トップメニュー <span>›</span> 社内図書一覧 <span>›</span> 図書情報更新入力
|
||||
</div>
|
||||
<h1 class="page-title">図書情報更新入力</h1>
|
||||
<p class="description">図書の情報を編集してください。変更しない項目はそのままにしてください。</p>
|
||||
|
||||
<form id="bookForm"
|
||||
action="${pageContext.request.contextPath}/book/updateConfirm"
|
||||
method="post">
|
||||
<section class="form-card">
|
||||
<h2 class="section-title">図書基本情報</h2>
|
||||
|
||||
<div class="system-info-row">
|
||||
<div class="field">
|
||||
<label class="label" for="bookManagementId">図書管理ID</label>
|
||||
<div class="with-note">
|
||||
<input id="bookManagementId" name="bookManagementId"
|
||||
type="text" class="control"
|
||||
value="<%=book.getBookManageId() != null ? book.getBookManageId() : ""%>"
|
||||
readonly> <span class="note">※変更できません</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="registeredAt">登録日時</label>
|
||||
<div class="with-note">
|
||||
<input id="registeredAt" name="registeredAt" type="text"
|
||||
class="control"
|
||||
value="<%=book.getCreatedAt() != null ? sdfDateTime.format(book.getCreatedAt()) : ""%>"
|
||||
readonly> <span class="note">※変更できません</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="updatedAt">更新日時</label>
|
||||
<div class="with-note">
|
||||
<input id="updatedAt" name="updatedAt" type="text"
|
||||
class="control"
|
||||
value="<%=book.getUpdatedAt() != null ? sdfDateTime.format(book.getUpdatedAt()) : ""%>"
|
||||
readonly> <span class="note">※変更できません</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-fields">
|
||||
<div class="field">
|
||||
<label class="label" for="isbn">ISBN<span
|
||||
class="required">(必須)</span></label> <input id="isbn" name="isbn"
|
||||
type="text" class="control"
|
||||
value="<%=book.getIsbn() != null ? book.getIsbn() : ""%>"
|
||||
required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="title">タイトル<span
|
||||
class="required">(必須)</span></label> <input id="title" name="title"
|
||||
type="text" class="control"
|
||||
value="<%=book.getTitle() != null ? book.getTitle() : ""%>"
|
||||
required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="author">著者名<span
|
||||
class="required">(必須)</span></label> <input id="author" name="author"
|
||||
type="text" class="control"
|
||||
value="<%=book.getAuthor() != null ? book.getAuthor() : ""%>"
|
||||
required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="category">カテゴリ<span
|
||||
class="required">(必須)</span></label>
|
||||
<select id="category" name="category" class="control" onchange="updateSubCategories()" required>
|
||||
<%
|
||||
String cat = (book.getCategoryName() != null) ? book.getCategoryName() : "";
|
||||
%>
|
||||
<option value="1" <%="AI・データ分析".equals(cat) || "1".equals(cat) ? "selected" : ""%>>AI・データ分析</option>
|
||||
<option value="2" <%="クラウド".equals(cat) || "2".equals(cat) ? "selected" : ""%>>クラウド</option>
|
||||
<option value="3" <%="プログラミング".equals(cat) || "3".equals(cat) ? "selected" : ""%>>プログラミング</option>
|
||||
<option value="4" <%="ネットワーク".equals(cat) || "4".equals(cat) ? "selected" : ""%>>ネットワーク</option>
|
||||
<option value="5" <%="Web技術".equals(cat) || "5".equals(cat) ? "selected" : ""%>>Web技術</option>
|
||||
<option value="6" <%="データベース".equals(cat) || "6".equals(cat) ? "selected" : ""%>>データベース</option>
|
||||
<option value="7" <%="ITマネジメント".equals(cat) || "7".equals(cat) ? "selected" : ""%>>ITマネジメント</option>
|
||||
<option value="8" <%="コンピュータ基礎".equals(cat) || "8".equals(cat) ? "selected" : ""%>>コンピュータ基礎</option>
|
||||
<option value="9" <%="セキュリティ".equals(cat) || "9".equals(cat) ? "selected" : ""%>>セキュリティ</option>
|
||||
<option value="10" <%="IT資格".equals(cat) || "10".equals(cat) ? "selected" : ""%>>IT資格</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="subCategory">サブカテゴリ<span
|
||||
class="required">(必須)</span></label>
|
||||
<select id="subCategory" name="subCategory" class="control" required>
|
||||
<!-- JavaScriptで動的生成 -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="location">保管場所<span
|
||||
class="required">(必須)</span></label> <select id="location"
|
||||
name="location" class="control" required>
|
||||
<%
|
||||
String loc = book.getLocationName() != null ? book.getLocationName() : "1";
|
||||
%>
|
||||
<option value="1" <%="1".equals(loc) || "未確定".equals(loc) ? "selected" : ""%>>未確定</option>
|
||||
<option value="2" <%="2".equals(loc) || "開発エリア書棚".equals(loc) ? "selected" : ""%>>開発エリア書棚</option>
|
||||
<option value="3" <%="3".equals(loc) || "会議室前ラック".equals(loc) ? "selected" : ""%>>会議室前ラック</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="statusText">貸出状態</label>
|
||||
<div class="with-note">
|
||||
<%
|
||||
int st = book.getBookStatus();
|
||||
String statusLabel = "貸出可";
|
||||
if (st == 1) statusLabel = "貸出中";
|
||||
else if (st == 2) statusLabel = "利用停止";
|
||||
%>
|
||||
<input id="statusText" type="text" class="control" value="<%=statusLabel%>" readonly>
|
||||
<input id="status" type="hidden" name="status" value="<%=statusLabel%>">
|
||||
<span class="note">※変更できません</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="bookCondition">本の状態<span
|
||||
class="required">(必須)</span></label> <select id="bookCondition"
|
||||
name="bookCondition" class="control" required>
|
||||
<%
|
||||
int cond = book.getCondition();
|
||||
%>
|
||||
<option value="1" <%=cond == 1 ? "selected" : ""%>>新品同様 : ほぼ未使用</option>
|
||||
<option value="2" <%=cond == 2 ? "selected" : ""%>>良好 : 目立つ傷や汚れ無し</option>
|
||||
<option value="3" <%=cond == 3 ? "selected" : ""%>>使用感あり : 多少の折れ、擦れあり</option>
|
||||
<option value="4" <%=cond == 4 ? "selected" : ""%>>傷みあり : 目立つ傷、汚れ、書き込みあり</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-fields optional-fields">
|
||||
<div class="field">
|
||||
<label class="label" for="publisher">出版社<span
|
||||
class="optional">(任意)</span></label> <input id="publisher"
|
||||
name="publisher" type="text" class="control"
|
||||
value="<%=book.getPublisher() != null ? book.getPublisher() : ""%>">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="publishedDate">出版日<span
|
||||
class="optional">(任意)</span></label> <input id="publishedDate"
|
||||
name="publishedDate" type="date" class="control"
|
||||
value="<%=book.getPublicationDate() != null ? sdfDate.format(book.getPublicationDate()) : ""%>">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="donor">寄贈者ID<span
|
||||
class="optional">(任意)</span></label> <input id="donor" name="donor"
|
||||
type="text" class="control"
|
||||
value="<%=book.getDonorName() != null ? book.getDonorName() : ""%>">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="url">URL<span class="optional">(任意)</span></label>
|
||||
<div class="with-note">
|
||||
<input id="url" name="url" type="url" class="control" value="">
|
||||
<span class="note">※任意の場合は空欄でも可</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="memo-section">
|
||||
<div class="memo-row">
|
||||
<label class="label" for="memo">備考<span class="optional">(任意)</span></label>
|
||||
<textarea id="memo" name="memo" class="control"><%=book.getDescription() != null ? book.getDescription() : ""%></textarea>
|
||||
<span class="memo-note">※任意の場合は空欄でも可</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="bottom">
|
||||
<button type="button" class="back-button"
|
||||
onclick="location.href='${pageContext.request.contextPath}/BookServlet';">図書一覧へ戻る</button>
|
||||
<div class="actions">
|
||||
<button type="reset" class="clear-button" onclick="setTimeout(updateSubCategories, 10);">クリア</button>
|
||||
<button type="button" class="confirm-button"
|
||||
onclick="confirmUpdate();">確認へ</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help">「確認へ」ボタンを押すと、入力内容の確認画面に進みます。</div>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 画像1・2のDBテーブル構造に対応するマスタデータ
|
||||
const subCategories = {
|
||||
"1": [
|
||||
{ id: 1, name: "人工知能・機械学習" },
|
||||
{ id: 2, name: "統計・データ分析" },
|
||||
{ id: 3, name: "自然言語処理・生成AI" }
|
||||
],
|
||||
"2": [
|
||||
{ id: 4, name: "AWS・クラウド基盤" },
|
||||
{ id: 5, name: "クラウドサービス" },
|
||||
{ id: 6, name: "クラウドアーキテクチャ・運用" },
|
||||
{ id: 7, name: "コンテナ・FinOps" }
|
||||
],
|
||||
"3": [
|
||||
{ id: 8, name: "Java・C#・C言語" },
|
||||
{ id: 9, name: "Web・スクリプト言語" },
|
||||
{ id: 10, name: "モダン言語" },
|
||||
{ id: 11, name: "アルゴリズム・設計" }
|
||||
],
|
||||
"4": [
|
||||
{ id: 12, name: "TCP/IP・プロトコル" },
|
||||
{ id: 13, name: "ネットワーク構築・運用" },
|
||||
{ id: 14, name: "無線・DNS・HTTP" },
|
||||
{ id: 15, name: "ネットワークセキュリティ・Linux" }
|
||||
],
|
||||
"5": [
|
||||
{ id: 16, name: "Web基礎・HTML/CSS" },
|
||||
{ id: 17, name: "JavaScript・Node.js・React" },
|
||||
{ id: 18, name: "Webデザイン・アクセシビリティ" },
|
||||
{ id: 19, name: "Web API・セキュリティ" }
|
||||
],
|
||||
"6": [
|
||||
{ id: 20, name: "SQL基礎・リファレンス" },
|
||||
{ id: 21, name: "データベース設計・モデリング" },
|
||||
{ id: 22, name: "SQLチューニング・分析" },
|
||||
{ id: 23, name: "DBスペシャリスト・実践" }
|
||||
],
|
||||
"7": [
|
||||
{ id: 24, name: "プロジェクト・アジャイル管理" },
|
||||
{ id: 25, name: "ITサービス・開発管理" },
|
||||
{ id: 26, name: "品質・テスト・要件定義" }
|
||||
],
|
||||
"8": [
|
||||
{ id: 27, name: "コンピュータ入門・アーキテクチャ" },
|
||||
{ id: 28, name: "OS・Linux" },
|
||||
{ id: 29, name: "プログラム・データ構造" },
|
||||
{ id: 30, name: "情報理論・ネットワーク" },
|
||||
{ id: 31, name: "論理回路・システム" }
|
||||
],
|
||||
"9": [
|
||||
{ id: 32, name: "情報セキュリティ・Web防御" },
|
||||
{ id: 33, name: "ネットワーク・サイバー防御" },
|
||||
{ id: 34, name: "認証・ゼロトラスト" },
|
||||
{ id: 35, name: "暗号・インシデント対応" },
|
||||
{ id: 36, name: "セキュリティ管理・開発" }
|
||||
],
|
||||
"10": [
|
||||
{ id: 37, name: "ITパスポート・基本情報" },
|
||||
{ id: 38, name: "高度情報処理試験" },
|
||||
{ id: 39, name: "情報セキュリティ系資格" }
|
||||
]
|
||||
};
|
||||
|
||||
// サーブレット側で保持している現在のサブカテゴリー値
|
||||
const currentSubCat = "<%=(book.getSubcategoryName() != null) ? book.getSubcategoryName() : ""%>";
|
||||
|
||||
function updateSubCategories() {
|
||||
const catSelect = document.getElementById("category");
|
||||
const subSelect = document.getElementById("subCategory");
|
||||
const selectedCat = catSelect.value;
|
||||
|
||||
subSelect.innerHTML = "";
|
||||
|
||||
const options = subCategories[selectedCat] || [];
|
||||
options.forEach(item => {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = item.id;
|
||||
opt.textContent = item.name;
|
||||
if (currentSubCat === String(item.id) || currentSubCat === item.name) {
|
||||
opt.selected = true;
|
||||
}
|
||||
subSelect.appendChild(opt);
|
||||
});
|
||||
}
|
||||
|
||||
// 初期表示時の初期化処理
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
updateSubCategories();
|
||||
});
|
||||
|
||||
function confirmUpdate() {
|
||||
const requiredFields = [ document.getElementById("isbn"),
|
||||
document.getElementById("title"),
|
||||
document.getElementById("author"),
|
||||
document.getElementById("category"),
|
||||
document.getElementById("subCategory"),
|
||||
document.getElementById("location"),
|
||||
document.getElementById("status"),
|
||||
document.getElementById("bookCondition") ];
|
||||
|
||||
const empty = requiredFields.some(function(field) {
|
||||
return !field.value.trim();
|
||||
});
|
||||
|
||||
if (empty) {
|
||||
alert("必須項目を入力してください。");
|
||||
return;
|
||||
}
|
||||
|
||||
const isbn = document.getElementById("isbn").value.replace(
|
||||
/[-\s]/g, "");
|
||||
if (!/^(?:\d{10}|\d{13})$/.test(isbn)) {
|
||||
alert("ISBNは10桁または13桁で入力してください。");
|
||||
return;
|
||||
}
|
||||
|
||||
const url = document.getElementById("url").value.trim();
|
||||
if (url !== "") {
|
||||
try {
|
||||
new URL(url);
|
||||
} catch (e) {
|
||||
alert("URLの形式が正しくありません。");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("bookForm").submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
767
src/main/resources/templates/old_JSP/book_update_confirm.jsp
Normal file
767
src/main/resources/templates/old_JSP/book_update_confirm.jsp
Normal file
@@ -0,0 +1,767 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
||||
pageEncoding="UTF-8"%>
|
||||
<%@ page import="bookequ_manage_system.entity.Book"%>
|
||||
<%@ page import="java.text.SimpleDateFormat"%>
|
||||
<%@ page import="java.util.Map"%>
|
||||
<%@ page import="java.util.HashMap"%>
|
||||
|
||||
<%
|
||||
Book book = (Book) request.getAttribute("book");
|
||||
if (book == null) {
|
||||
book = new Book();
|
||||
}
|
||||
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy/MM/dd");
|
||||
|
||||
// 表示用カテゴリーマップ
|
||||
Map<String, String> categoryMap = new HashMap<>();
|
||||
categoryMap.put("1", "AI・データ分析");
|
||||
categoryMap.put("2", "クラウド");
|
||||
categoryMap.put("3", "プログラミング");
|
||||
categoryMap.put("4", "ネットワーク");
|
||||
categoryMap.put("5", "Web技術");
|
||||
categoryMap.put("6", "データベース");
|
||||
categoryMap.put("7", "ITマネジメント");
|
||||
categoryMap.put("8", "コンピュータ基礎");
|
||||
categoryMap.put("9", "セキュリティ");
|
||||
categoryMap.put("10", "IT資格");
|
||||
|
||||
// 表示用サブカテゴリーマップ
|
||||
Map<String, String> subCategoryMap = new HashMap<>();
|
||||
subCategoryMap.put("1", "人工知能・機械学習");
|
||||
subCategoryMap.put("2", "統計・データ分析");
|
||||
subCategoryMap.put("3", "自然言語処理・生成AI");
|
||||
subCategoryMap.put("4", "AWS・クラウド基盤");
|
||||
subCategoryMap.put("5", "クラウドサービス");
|
||||
subCategoryMap.put("6", "クラウドアーキテクチャ・運用");
|
||||
subCategoryMap.put("7", "コンテナ・FinOps");
|
||||
subCategoryMap.put("8", "Java・C#・C言語");
|
||||
subCategoryMap.put("9", "Web・スクリプト言語");
|
||||
subCategoryMap.put("10", "モダン言語");
|
||||
subCategoryMap.put("11", "アルゴリズム・設計");
|
||||
subCategoryMap.put("12", "TCP/IP・プロトコル");
|
||||
subCategoryMap.put("13", "ネットワーク構築・運用");
|
||||
subCategoryMap.put("14", "無線・DNS・HTTP");
|
||||
subCategoryMap.put("15", "ネットワークセキュリティ・Linux");
|
||||
subCategoryMap.put("16", "Web基礎・HTML/CSS");
|
||||
subCategoryMap.put("17", "JavaScript・Node.js・React");
|
||||
subCategoryMap.put("18", "Webデザイン・アクセシビリティ");
|
||||
subCategoryMap.put("19", "Web API・セキュリティ");
|
||||
subCategoryMap.put("20", "SQL基礎・リファレンス");
|
||||
subCategoryMap.put("21", "データベース設計・モデリング");
|
||||
subCategoryMap.put("22", "SQLチューニング・分析");
|
||||
subCategoryMap.put("23", "DBスペシャリスト・実践");
|
||||
subCategoryMap.put("24", "プロジェクト・アジャイル管理");
|
||||
subCategoryMap.put("25", "ITサービス・開発管理");
|
||||
subCategoryMap.put("26", "品質・テスト・要件定義");
|
||||
subCategoryMap.put("27", "コンピュータ入門・アーキテクチャ");
|
||||
subCategoryMap.put("28", "OS・Linux");
|
||||
subCategoryMap.put("29", "プログラム・データ構造");
|
||||
subCategoryMap.put("30", "情報理論・ネットワーク");
|
||||
subCategoryMap.put("31", "論理回路・システム");
|
||||
subCategoryMap.put("32", "情報セキュリティ・Web防御");
|
||||
subCategoryMap.put("33", "ネットワーク・サイバー防御");
|
||||
subCategoryMap.put("34", "認証・ゼロトラスト");
|
||||
subCategoryMap.put("35", "暗号・インシデント対応");
|
||||
subCategoryMap.put("36", "セキュリティ管理・開発");
|
||||
subCategoryMap.put("37", "ITパスポート・基本情報");
|
||||
subCategoryMap.put("38", "高度情報処理試験");
|
||||
subCategoryMap.put("39", "情報セキュリティ系資格");
|
||||
|
||||
// 表示用 保管場所マップ
|
||||
Map<String, String> locationMap = new HashMap<>();
|
||||
locationMap.put("1", "未確定");
|
||||
locationMap.put("2", "開発エリア書棚");
|
||||
locationMap.put("3", "会議室前ラック");
|
||||
|
||||
// 表示用 貸出状態マップ
|
||||
Map<Integer, String> statusMap = new HashMap<>();
|
||||
statusMap.put(0, "貸出可");
|
||||
statusMap.put(1, "貸出中");
|
||||
statusMap.put(2, "利用停止");
|
||||
|
||||
// 表示用 本の状態マップ
|
||||
Map<Integer, String> conditionMap = new HashMap<>();
|
||||
conditionMap.put(1, "新品同様 : ほぼ未使用");
|
||||
conditionMap.put(2, "良好 : 目立つ傷や汚れ無し");
|
||||
conditionMap.put(3, "使用感あり : 多少の折れ、擦れあり");
|
||||
conditionMap.put(4, "傷みあり : 目立つ傷、汚れ、書き込みあり");
|
||||
|
||||
// 表示用名称の取得
|
||||
String displayCategory = categoryMap.getOrDefault(book.getCategoryName(), book.getCategoryName());
|
||||
String displaySubCategory = subCategoryMap.getOrDefault(book.getSubcategoryName(), book.getSubcategoryName());
|
||||
String displayLocation = locationMap.getOrDefault(book.getLocationName(), book.getLocationName());
|
||||
String displayStatus = statusMap.getOrDefault(book.getBookStatus(), String.valueOf(book.getBookStatus()));
|
||||
String displayCondition = conditionMap.getOrDefault(book.getCondition(), String.valueOf(book.getCondition()));
|
||||
%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>【図書】更新内容確認</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
font-family: "Noto Sans JP", "Yu Gothic", "YuGothic", "Meiryo", Arial,
|
||||
sans-serif;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
height: 56px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 14px 0 17px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid #294b85;
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.logo-icon::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: -2px;
|
||||
height: 20px;
|
||||
border-left: 1px solid #294b85;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 17px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 11px;
|
||||
color: #555;
|
||||
white-space: nowrap;
|
||||
padding: 6px 8px;
|
||||
border-radius: 3px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Main layout */
|
||||
.main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
min-height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
width: 116px;
|
||||
flex: 0 0 150px;
|
||||
background: #002d5b;
|
||||
color: #fff;
|
||||
padding-top: 17px;
|
||||
}
|
||||
|
||||
.side-title {
|
||||
padding: 0 12px 10px;
|
||||
font-size: 8px;
|
||||
color: #d9e4f0;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 12px;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-item.active {
|
||||
background: #1264b4;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Content */
|
||||
.content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 17px 14px 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 8px;
|
||||
color: #6f8094;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.breadcrumb span {
|
||||
margin: 0 5px;
|
||||
color: #9aa4ae;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 2px 0 13px;
|
||||
font-size: 9px;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
/* Form card */
|
||||
.form-card {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 3px;
|
||||
padding: 13px 11px 15px;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, .02);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin: 0 0 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.system-info-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
column-gap: 34px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.input-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.optional-fields {
|
||||
margin-top: 14px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: grid;
|
||||
grid-template-columns: 76px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #e53935;
|
||||
font-size: 8px;
|
||||
margin-left: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: #333;
|
||||
font-size: 8px;
|
||||
margin-left: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.control {
|
||||
width: 100%;
|
||||
min-height: 28px;
|
||||
padding: 6px 9px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
background: #f3f5f8;
|
||||
color: #555;
|
||||
font-size: 9px;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.with-note {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.with-note .control {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.note {
|
||||
flex: 0 0 auto;
|
||||
color: #777;
|
||||
font-size: 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Memo */
|
||||
.memo-section {
|
||||
margin-top: 16px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 3px;
|
||||
padding: 12px 11px 14px;
|
||||
}
|
||||
|
||||
.memo-row {
|
||||
display: grid;
|
||||
grid-template-columns: 76px minmax(0, 1fr) 82px;
|
||||
gap: 8px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.memo-value {
|
||||
min-height: 60px;
|
||||
padding: 8px 9px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
background: #f3f5f8;
|
||||
color: #555;
|
||||
font-size: 9px;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.memo-note {
|
||||
color: #777;
|
||||
font-size: 8px;
|
||||
padding-top: 7px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Bottom area */
|
||||
.bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
min-width: 82px;
|
||||
height: 30px;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.register-button {
|
||||
height: 30px;
|
||||
min-width: 86px;
|
||||
border: 1px solid #005bb5;
|
||||
border-radius: 3px;
|
||||
background: #0967c3;
|
||||
color: #fff;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Modal Popup Styles */
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
z-index: 1000;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
width: 500px;
|
||||
max-width: 90%;
|
||||
max-height: 85vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 12px 16px;
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.modal-body-title {
|
||||
margin-bottom: 12px;
|
||||
color: #555;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.modal-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
border: 1px solid #eee;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.modal-item {
|
||||
display: grid;
|
||||
grid-template-columns: 100px 1fr;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.modal-label {
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.modal-val {
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 12px 16px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.modal-cancel-btn {
|
||||
height: 30px;
|
||||
min-width: 80px;
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
color: #444;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-confirm-btn {
|
||||
height: 30px;
|
||||
min-width: 80px;
|
||||
border: 1px solid #005bb5;
|
||||
border-radius: 3px;
|
||||
background: #0967c3;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<header class="header">
|
||||
<div class="logo">
|
||||
<span class="logo-icon"></span><span>📖 ShareBooks</span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
|
||||
<div class="user-name">ログイン中</div>
|
||||
|
||||
<button type="button" class="logout">
|
||||
ログアウト
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</header>
|
||||
|
||||
<div class="main">
|
||||
<aside class="sidebar">
|
||||
<div class="side-title">管理者画面</div>
|
||||
<div class="menu-item">
|
||||
<span class="menu-icon">🏠</span><span>トップメニュー</span>
|
||||
</div>
|
||||
<div class="menu-item active">
|
||||
<span class="menu-icon">📖</span><span>社内図書一覧</span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="content">
|
||||
<div class="breadcrumb">
|
||||
トップメニュー <span>›</span> 社内図書一覧 <span>›</span> 図書情報更新入力 <span>›</span>
|
||||
図書情報更新内容確認
|
||||
</div>
|
||||
<h1 class="page-title">図書情報更新内容確認</h1>
|
||||
<p class="description">入力した内容をご確認ください。内容に問題がなければ「登録する」ボタンを押してください。</p>
|
||||
|
||||
<form id="executeUpdateForm"
|
||||
action="${pageContext.request.contextPath}/book/updateExecute"
|
||||
method="post">
|
||||
<!-- DB更新用 hidden パラメータ -->
|
||||
<input type="hidden" name="bookManagementId"
|
||||
value="<%=book.getBookManageId() != null ? book.getBookManageId() : ""%>">
|
||||
<input type="hidden" name="isbn"
|
||||
value="<%=book.getIsbn() != null ? book.getIsbn() : ""%>">
|
||||
<input type="hidden" name="title"
|
||||
value="<%=book.getTitle() != null ? book.getTitle() : ""%>">
|
||||
<input type="hidden" name="author"
|
||||
value="<%=book.getAuthor() != null ? book.getAuthor() : ""%>">
|
||||
<input type="hidden" name="category"
|
||||
value="<%=book.getCategoryName() != null ? book.getCategoryName() : ""%>">
|
||||
<input type="hidden" name="subCategory"
|
||||
value="<%=book.getSubcategoryName() != null ? book.getSubcategoryName() : ""%>">
|
||||
<input type="hidden" name="location"
|
||||
value="<%=book.getLocationName() != null ? book.getLocationName() : ""%>">
|
||||
<input type="hidden" name="status"
|
||||
value="<%=book.getBookStatus()%>"> <input type="hidden"
|
||||
name="bookCondition" value="<%=book.getCondition()%>"> <input
|
||||
type="hidden" name="publisher"
|
||||
value="<%=book.getPublisher() != null ? book.getPublisher() : ""%>">
|
||||
<input type="hidden" name="publicationDate"
|
||||
value="<%=book.getPublicationDate() != null ? book.getPublicationDate() : ""%>">
|
||||
<input type="hidden" name="donor"
|
||||
value="<%=book.getDonorName() != null ? book.getDonorName() : ""%>">
|
||||
<input type="hidden" name="url" value=""> <input
|
||||
type="hidden" name="memo"
|
||||
value="<%=book.getDescription() != null ? book.getDescription() : ""%>">
|
||||
|
||||
<section class="form-card">
|
||||
<h2 class="section-title">図書基本情報</h2>
|
||||
|
||||
<div class="system-info-row">
|
||||
<div class="field">
|
||||
<label class="label">図書管理ID</label>
|
||||
<div class="with-note">
|
||||
<div class="control"><%=book.getBookManageId() != null ? book.getBookManageId() : ""%></div>
|
||||
<span class="note">※変更できません</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-fields">
|
||||
<div class="field">
|
||||
<label class="label">ISBN<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=book.getIsbn() != null ? book.getIsbn() : ""%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">タイトル<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=book.getTitle() != null ? book.getTitle() : ""%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">著者名<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=book.getAuthor() != null ? book.getAuthor() : ""%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">カテゴリ<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=displayCategory%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">サブカテゴリ<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=displaySubCategory%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">保管場所<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=displayLocation%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">貸出状態<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=displayStatus%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">本の状態<span class="required">(必須)</span></label>
|
||||
<div class="control"><%=displayCondition%></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-fields optional-fields">
|
||||
<div class="field">
|
||||
<label class="label">出版社<span class="optional">(任意)</span></label>
|
||||
<div class="control"><%=book.getPublisher() != null ? book.getPublisher() : ""%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">出版日<span class="optional">(任意)</span></label>
|
||||
<div class="control"><%=book.getPublicationDate() != null ? sdfDate.format(book.getPublicationDate()) : ""%></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">寄贈者ID<span class="optional">(任意)</span></label>
|
||||
<div class="control"><%=book.getDonorName() != null ? book.getDonorName() : ""%></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="memo-section">
|
||||
<div class="memo-row">
|
||||
<label class="label">備考<span class="optional">(任意)</span></label>
|
||||
<div class="memo-value"><%=book.getDescription() != null ? book.getDescription() : ""%></div>
|
||||
<span class="memo-note">※任意の場合は空欄でも可</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="bottom">
|
||||
<button type="button" class="back-button"
|
||||
onclick="history.back();">入力画面へ戻る</button>
|
||||
<div class="actions">
|
||||
<button type="button" class="register-button"
|
||||
onclick="openModal()">登録する</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 更新確認ポップアップ(モーダル) -->
|
||||
<div id="confirmModal" class="modal-overlay">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">更新内容の最終確認</div>
|
||||
<div class="modal-body">
|
||||
<p class="modal-body-title">以下の内容で情報を更新します。よろしいですか?</p>
|
||||
<div class="modal-list">
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">図書管理ID:</span> <span class="modal-val"><%=book.getBookManageId() != null ? book.getBookManageId() : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">ISBN:</span> <span class="modal-val"><%=book.getIsbn() != null ? book.getIsbn() : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">タイトル:</span> <span class="modal-val"><%=book.getTitle() != null ? book.getTitle() : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">著者名:</span> <span class="modal-val"><%=book.getAuthor() != null ? book.getAuthor() : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">カテゴリ:</span> <span class="modal-val"><%=displayCategory%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">サブカテゴリ:</span> <span class="modal-val"><%=displaySubCategory%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">保管場所:</span> <span class="modal-val"><%=displayLocation%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">貸出状態:</span> <span class="modal-val"><%=displayStatus%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">本の状態:</span> <span class="modal-val"><%=displayCondition%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">出版社:</span> <span class="modal-val"><%=book.getPublisher() != null ? book.getPublisher() : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">出版日:</span> <span class="modal-val"><%=book.getPublicationDate() != null ? sdfDate.format(book.getPublicationDate()) : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">寄贈者ID:</span> <span class="modal-val"><%=book.getDonorName() != null ? book.getDonorName() : ""%></span>
|
||||
</div>
|
||||
<div class="modal-item">
|
||||
<span class="modal-label">備考:</span> <span class="modal-val"><%=book.getDescription() != null ? book.getDescription() : ""%></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="modal-cancel-btn"
|
||||
onclick="closeModal()">キャンセル</button>
|
||||
<button type="button" class="modal-confirm-btn"
|
||||
onclick="submitForm()">更新</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openModal() {
|
||||
document.getElementById("confirmModal").style.display = "flex";
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById("confirmModal").style.display = "none";
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
document.getElementById("executeUpdateForm").submit();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
940
src/main/resources/templates/passwordChange.html
Normal file
940
src/main/resources/templates/passwordChange.html
Normal file
@@ -0,0 +1,940 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>パスワード再設定 | 社内備品・図書管理システム</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Hiragino Kaku Gothic ProN", "Yu Gothic", "Meiryo",
|
||||
sans-serif;
|
||||
background-color: #f4f6f9;
|
||||
color: #33404f;
|
||||
}
|
||||
|
||||
/* ===== ヘッダー ===== */
|
||||
.header-bar {
|
||||
background-color: #fff;
|
||||
padding: 14px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-left svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.bell-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bell-wrap svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.bell-badge {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: -6px;
|
||||
background-color: #e5484d;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #a8b3c0;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ===== 全体レイアウト ===== */
|
||||
.layout {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 52px);
|
||||
}
|
||||
|
||||
/* ===== サイドバー ===== */
|
||||
.sidebar {
|
||||
width: 210px;
|
||||
background-color: #16325c;
|
||||
color: #cdd9ea;
|
||||
padding: 18px 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar .section-label {
|
||||
font-size: 11px;
|
||||
color: #8ea2c0;
|
||||
padding: 6px 20px;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #cdd9ea;
|
||||
text-decoration: none;
|
||||
padding: 11px 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sidebar a svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.sidebar a.active {
|
||||
background-color: #1a56c4;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.sidebar a:hover:not(.active) {
|
||||
background-color: #1e3a66;
|
||||
}
|
||||
|
||||
/* ===== メインエリア ===== */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
padding: 24px 32px;
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
font-size: 12px;
|
||||
color: #8892a0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.breadcrumb a {
|
||||
color: #8892a0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 22px;
|
||||
margin: 0 0 6px;
|
||||
color: #1c2733;
|
||||
}
|
||||
|
||||
.page-desc {
|
||||
font-size: 13px;
|
||||
color: #6b7686;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
.required-note {
|
||||
font-size: 12px;
|
||||
color: #c0392b;
|
||||
margin: 0 0 18px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
font-size: 13px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background-color: #fdecea;
|
||||
color: #c0392b;
|
||||
border: 1px solid #f5c6c6;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: #eafaf0;
|
||||
color: #1e7e42;
|
||||
border: 1px solid #b7ecc9;
|
||||
}
|
||||
|
||||
.content-columns {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.right-column {
|
||||
width: 260px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ===== 入力カード ===== */
|
||||
.form-card {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 24px 26px;
|
||||
box-shadow: 0 2px 10px rgba(20, 40, 70, 0.06);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-card h2 {
|
||||
font-size: 14px;
|
||||
margin: 0 0 18px;
|
||||
color: #1c2733;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #33404f;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.form-group label .req {
|
||||
color: #c0392b;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.input-with-icon {
|
||||
position: relative;
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
.input-with-icon input {
|
||||
width: 100%;
|
||||
padding: 10px 36px 10px 12px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #d7dde5;
|
||||
border-radius: 6px;
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
.input-with-icon input:focus {
|
||||
outline: none;
|
||||
border-color: #1a56c4;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.toggle-password {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #9aa4b2;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.field-hint {
|
||||
font-size: 11px;
|
||||
color: #8892a0;
|
||||
margin: 6px 0 0;
|
||||
}
|
||||
|
||||
/* ===== 注意事項 ===== */
|
||||
.notice-box {
|
||||
background-color: #fdf6e3;
|
||||
border: 1px solid #f0e0ad;
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
}
|
||||
|
||||
.notice-box .notice-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
color: #8a6d1f;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.notice-box .notice-title svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.notice-box ul {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
font-size: 12px;
|
||||
color: #6b5c2e;
|
||||
}
|
||||
|
||||
.notice-box li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* ===== 右側:パスワード制約 ===== */
|
||||
.constraint-panel {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 10px rgba(20, 40, 70, 0.06);
|
||||
}
|
||||
|
||||
.constraint-panel .panel-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
color: #1c2733;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.constraint-panel .panel-title svg {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
color: #1a56c4;
|
||||
}
|
||||
|
||||
.group-label {
|
||||
font-size: 11px;
|
||||
color: #8892a0;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.chars-value {
|
||||
font-size: 13px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.constraint-panel hr {
|
||||
border: none;
|
||||
border-top: 1px dashed #e2e6ec;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.constraint-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.constraint-list li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
.constraint-list svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: #2e9e5b;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.example-box {
|
||||
background-color: #eef4fc;
|
||||
border-radius: 6px;
|
||||
padding: 10px 12px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.example-label {
|
||||
font-size: 11px;
|
||||
color: #6b7686;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.example-value {
|
||||
font-family: "Consolas", monospace;
|
||||
font-size: 13px;
|
||||
color: #1c2733;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.example-note {
|
||||
font-size: 10px;
|
||||
color: #8892a0;
|
||||
}
|
||||
|
||||
/* ===== ボタン ===== */
|
||||
.button-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 13px;
|
||||
padding: 10px 20px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #d7dde5;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: #ffffff;
|
||||
color: #33404f;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #1a56c4;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #15479f;
|
||||
}
|
||||
|
||||
.btn-group-right {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* ===== フッター ===== */
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
color: #9aa4b2;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
/* ===== ポップアップ ===== */
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.45);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-overlay.show {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal {
|
||||
width: 400px;
|
||||
max-width: 90%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
padding: 28px;
|
||||
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.2);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #1c2733;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.modal-message {
|
||||
font-size: 13px;
|
||||
color: #5f6b7a;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 24px;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.modal-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.modal-buttons button {
|
||||
min-width: 90px;
|
||||
padding: 9px 18px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.modal-cancel {
|
||||
background-color: #ffffff;
|
||||
color: #33404f;
|
||||
border: 1px solid #d7dde5;
|
||||
}
|
||||
|
||||
.modal-confirm {
|
||||
background-color: #1a56c4;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.modal-error .modal-title {
|
||||
color: #c0392b;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- ヘッダー -->
|
||||
<div class="header-bar">
|
||||
|
||||
<div class="header-left">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
|
||||
</svg>
|
||||
社内備品・図書管理システム
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
|
||||
<span class="user">
|
||||
<%=session.getAttribute("employeeName")%>(<%=roleName%>)
|
||||
</span>
|
||||
|
||||
<form action="${pageContext.request.contextPath}/logout"
|
||||
method="post" onsubmit="return confirm('ログアウトしますか?');">
|
||||
|
||||
<button type="submit" class="logout">
|
||||
ログアウト
|
||||
</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- パスワード変更完了後、セッションを破棄してログイン画面へ戻すための隠しフォーム -->
|
||||
<form id="logoutAfterPasswordChangeForm" method="post"
|
||||
action="${pageContext.request.contextPath}/logout"
|
||||
style="display: none;"></form>
|
||||
|
||||
|
||||
<div class="layout">
|
||||
|
||||
<!-- サイドバー -->
|
||||
<div class="sidebar">
|
||||
|
||||
<div class="section-label">共通画面</div>
|
||||
|
||||
<a class="side-menu"
|
||||
href="${pageContext.request.contextPath}/topmenu.jsp"> トップメニュー </a>
|
||||
|
||||
<a href="#" class="active"> パスワード再設定 </a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- メイン -->
|
||||
<div class="main-area">
|
||||
|
||||
<div class="breadcrumb">
|
||||
<a href="#">トップメニュー</a> > パスワード再設定
|
||||
</div>
|
||||
|
||||
<h1 class="page-title">パスワード再設定</h1>
|
||||
|
||||
<p class="page-desc">現在のパスワードと新しいパスワードを入力し、「確定」ボタンを押してください。</p>
|
||||
|
||||
<p class="required-note">(※)は必須項目です。</p>
|
||||
|
||||
<%
|
||||
if (errorMessage != null) {
|
||||
%>
|
||||
<div class="alert alert-error"><%=errorMessage%></div>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
|
||||
<%
|
||||
if (successMessage != null) {
|
||||
%>
|
||||
<div class="alert alert-success"><%=successMessage%></div>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
|
||||
|
||||
<div class="content-columns">
|
||||
|
||||
<!-- 左カラム -->
|
||||
<div class="left-column">
|
||||
|
||||
<div class="form-card">
|
||||
|
||||
<h2>パスワード再設定入力</h2>
|
||||
|
||||
<form id="pwForm" method="post"
|
||||
action="${pageContext.request.contextPath}/PasswordChangeServlet">
|
||||
|
||||
|
||||
<!-- 現在のパスワード -->
|
||||
<div class="form-group">
|
||||
|
||||
<label for="currentPassword"> 現在のパスワード <span class="req">(※)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-with-icon">
|
||||
|
||||
<input type="password" id="currentPassword"
|
||||
name="currentPassword" autocomplete="current-password"
|
||||
placeholder="現在のパスワードを入力してください">
|
||||
|
||||
<button type="button" class="toggle-password"
|
||||
onclick="togglePassword('currentPassword')">
|
||||
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<path
|
||||
d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
|
||||
</svg>
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 新しいパスワード -->
|
||||
<div class="form-group">
|
||||
|
||||
<label for="newPassword"> 新しいパスワード <span class="req">(※)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-with-icon">
|
||||
|
||||
<input type="password" id="newPassword" name="newPassword"
|
||||
autocomplete="new-password" placeholder="新しいパスワードを入力してください">
|
||||
|
||||
<button type="button" class="toggle-password"
|
||||
onclick="togglePassword('newPassword')">
|
||||
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<path
|
||||
d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
|
||||
</svg>
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<p class="field-hint">※ 半角英数字・記号を含む8文字以上16文字以下で入力してください。</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 確認用パスワード -->
|
||||
<div class="form-group">
|
||||
</from>
|
||||
|
||||
<label for="confirmPassword"> 新しいパスワードの確認 <span
|
||||
class="req">(※)</span>
|
||||
</label>
|
||||
|
||||
<div class="input-with-icon">
|
||||
|
||||
<input type="password" id="confirmPassword"
|
||||
name="confirmPassword" autocomplete="new-password"
|
||||
placeholder="新しいパスワードをもう一度入力してください">
|
||||
|
||||
<button type="button" class="toggle-password"
|
||||
onclick="togglePassword('confirmPassword')">
|
||||
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
|
||||
<path
|
||||
d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
|
||||
</svg>
|
||||
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<p class="field-hint">※ 確認のため、もう一度新しいパスワードを入力してください。</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 注意事項 -->
|
||||
<div class="notice-box">
|
||||
|
||||
<div class="notice-title">注意事項</div>
|
||||
|
||||
<ul>
|
||||
<li>「確定」ボタンを押した時点で、入力内容のチェックが行われます。</li>
|
||||
<li>エラーがある場合は、該当するメッセージをポップアップで表示します。</li>
|
||||
<li>エラーがない場合は、確認のポップアップが表示されます。</li>
|
||||
<li>パスワードを変更した後は、再度ログインしてください。</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ボタン -->
|
||||
<div class="button-row">
|
||||
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="goTopMenu()">トップメニューへ戻る</button>
|
||||
|
||||
<div class="btn-group-right">
|
||||
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="clearForm()">クリア</button>
|
||||
|
||||
<button type="button" class="btn btn-primary"
|
||||
onclick="showConfirmPopup()">確定</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 右カラム -->
|
||||
<div class="right-column">
|
||||
|
||||
<div class="constraint-panel">
|
||||
|
||||
<div class="panel-title">パスワードの制約</div>
|
||||
|
||||
<div class="group-label">使用可能文字</div>
|
||||
|
||||
<div class="chars-value">半角英数字・記号</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="group-label">制約</div>
|
||||
|
||||
<ul class="constraint-list">
|
||||
|
||||
<li>✓ 8文字以上16文字以下</li>
|
||||
<li>✓ 1つ以上の小文字を使用</li>
|
||||
<li>✓ 1つ以上の大文字を使用</li>
|
||||
<li>✓ 1つ以上の数字を使用</li>
|
||||
<li>✓ 1つ以上の記号を使用</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="example-box">
|
||||
|
||||
<div class="example-label">設定例</div>
|
||||
|
||||
<div class="example-value">Abcdef12!</div>
|
||||
|
||||
<div class="example-note">(9文字、英字大小・数字・記号を含む)</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">© 2024 社内備品・図書管理システム</div>
|
||||
|
||||
|
||||
<!-- ===== ポップアップ ===== -->
|
||||
|
||||
<div id="modalOverlay" class="modal-overlay">
|
||||
|
||||
<div class="modal">
|
||||
|
||||
<div id="modalTitle" class="modal-title">パスワードを更新してよろしいですか?</div>
|
||||
|
||||
<div id="modalMessage" class="modal-message">入力したパスワードを更新します。</div>
|
||||
|
||||
<div class="modal-buttons">
|
||||
|
||||
<button type="button" id="modalCancel" class="modal-cancel"
|
||||
onclick="closePopup()">いいえ</button>
|
||||
|
||||
<button type="button" id="modalConfirm" class="modal-confirm"
|
||||
onclick="confirmUpdate()">はい</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
/* パスワード表示・非表示 */
|
||||
function togglePassword(id) {
|
||||
const input = document.getElementById(id);
|
||||
input.type = (input.type === "password") ? "text" : "password";
|
||||
}
|
||||
|
||||
/* 入力欄をクリア */
|
||||
function clearForm() {
|
||||
document.getElementById("currentPassword").value = "";
|
||||
document.getElementById("newPassword").value = "";
|
||||
document.getElementById("confirmPassword").value = "";
|
||||
}
|
||||
|
||||
/* ポップアップを表示 */
|
||||
function openPopup(title, message, mode, onConfirm) {
|
||||
|
||||
document.getElementById("modalTitle").textContent = title;
|
||||
document.getElementById("modalMessage").textContent = message;
|
||||
|
||||
const cancelButton = document.getElementById("modalCancel");
|
||||
const confirmButton = document.getElementById("modalConfirm");
|
||||
|
||||
if (mode === "error") {
|
||||
cancelButton.style.display = "none";
|
||||
confirmButton.textContent = "閉じる";
|
||||
confirmButton.onclick = closePopup;
|
||||
} else {
|
||||
cancelButton.style.display = "inline-block";
|
||||
confirmButton.textContent = "はい";
|
||||
confirmButton.onclick = onConfirm || closePopup;
|
||||
}
|
||||
|
||||
document.getElementById("modalOverlay").classList.add("show");
|
||||
}
|
||||
|
||||
/* ポップアップを閉じる */
|
||||
function closePopup() {
|
||||
document.getElementById("modalOverlay").classList.remove("show");
|
||||
}
|
||||
|
||||
/* 確定ボタン:ここではDBに聞かなくても分かる項目だけをチェックする */
|
||||
function showConfirmPopup() {
|
||||
|
||||
const currentPassword = document.getElementById("currentPassword").value;
|
||||
const newPassword = document.getElementById("newPassword").value;
|
||||
const confirmPassword = document.getElementById("confirmPassword").value;
|
||||
|
||||
if (currentPassword === "") {
|
||||
openPopup("入力エラー", "現在のパスワードを入力してください。", "error");
|
||||
return;
|
||||
}
|
||||
if (newPassword === "") {
|
||||
openPopup("入力エラー", "新しいパスワードを入力してください。", "error");
|
||||
return;
|
||||
}
|
||||
if (confirmPassword === "") {
|
||||
openPopup("入力エラー", "新しいパスワードの確認を入力してください。", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,16}$/;
|
||||
if (!passwordPattern.test(newPassword)) {
|
||||
openPopup("入力エラー", "パスワードの制約を満たしていません。", "error");
|
||||
return;
|
||||
}
|
||||
if (currentPassword === newPassword) {
|
||||
openPopup("入力エラー", "現在のパスワードと異なるパスワードを設定してください。", "error");
|
||||
return;
|
||||
}
|
||||
if (newPassword !== confirmPassword) {
|
||||
openPopup("入力エラー", "新しいパスワードと確認用パスワードが一致しません。", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
// ここまでの判定はOK。現在のパスワードが正しいかはサーバーでしか分からないので、
|
||||
// 確認後に通常のフォーム送信でサーバーに任せる。
|
||||
openPopup(
|
||||
"パスワードを更新してよろしいですか?",
|
||||
"入力したパスワードに更新します。",
|
||||
"confirm",
|
||||
function () {
|
||||
document.getElementById("pwForm").submit();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/* トップメニューへ戻る */
|
||||
function goTopMenu() {
|
||||
location.href = "${pageContext.request.contextPath}/topmenu.jsp";
|
||||
}
|
||||
|
||||
/* ページを開いた直後、サーバー側の結果に応じて自動的にポップアップ表示する */
|
||||
window.addEventListener("DOMContentLoaded", function () {
|
||||
<%if (errorMessage != null) {%>
|
||||
openPopup("入力エラー", "<%=errorMessage%>
|
||||
", "error");
|
||||
<%} else if (successMessage != null) {%>
|
||||
openPopup(
|
||||
"更新完了",
|
||||
"パスワードを更新しました。\nログイン画面に戻ります。",
|
||||
"confirm",
|
||||
function() {
|
||||
// 既存のログアウト処理(セッション破棄+login.jspへ遷移)をそのまま利用する
|
||||
document
|
||||
.getElementById(
|
||||
"logoutAfterPasswordChangeForm")
|
||||
.submit();
|
||||
});
|
||||
document.getElementById("modalCancel").style.display = "none";
|
||||
document.getElementById("modalConfirm").textContent = "閉じる";
|
||||
<%}%>
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
652
src/main/resources/templates/topmenu.html
Normal file
652
src/main/resources/templates/topmenu.html
Normal file
@@ -0,0 +1,652 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>トップメニュー - ShareBooks</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Yu Gothic", "Meiryo", sans-serif;
|
||||
color: #18243a;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* ===== ヘッダー ===== */
|
||||
.header {
|
||||
height: 58px;
|
||||
border-bottom: 1px solid #d8e0e8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 18px 0 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.book-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.user {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.bell {
|
||||
font-size: 22px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
right: -5px;
|
||||
background: #e33;
|
||||
color: #fff;
|
||||
border-radius: 9px;
|
||||
font-size: 8px;
|
||||
min-width: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #a8b3c0;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ===== レイアウト ===== */
|
||||
.layout {
|
||||
display: flex;
|
||||
min-height: calc(100vh - 100px);
|
||||
}
|
||||
|
||||
/* ===== サイドバー ===== */
|
||||
.sidebar {
|
||||
width: 180px;
|
||||
flex: 0 0 180px;
|
||||
background: #082957;
|
||||
color: #fff;
|
||||
padding: 10px 8px;
|
||||
}
|
||||
|
||||
.side-label {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 4px 9px 12px;
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
min-height: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.side-menu.active {
|
||||
background: #1267d9;
|
||||
}
|
||||
|
||||
.side-icon {
|
||||
font-size: 18px;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ===== メイン ===== */
|
||||
.content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 16px 20px 15px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 26px;
|
||||
margin: 0 0 3px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #4d596b;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.menu-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.card {
|
||||
height: 181px;
|
||||
border: 1px solid #e0e5eb;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 7px #1e344d12;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 16px 10px;
|
||||
transition: .15s;
|
||||
}
|
||||
|
||||
.card:hover,
|
||||
.system-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px #1e344d22;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 59px;
|
||||
height: 59px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.blue {
|
||||
background: #e6f0ff;
|
||||
color: #3175d2;
|
||||
}
|
||||
|
||||
.green {
|
||||
background: #e8f7ea;
|
||||
color: #55a768;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background: #fff5d8;
|
||||
color: #c39b31;
|
||||
}
|
||||
|
||||
.purple {
|
||||
background: #f1eaff;
|
||||
color: #8a68ca;
|
||||
}
|
||||
|
||||
.orange {
|
||||
background: #fff0e3;
|
||||
color: #e3974e;
|
||||
}
|
||||
|
||||
.red {
|
||||
background: #fde9eb;
|
||||
color: #d77a82;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
font-size: 13px;
|
||||
margin: 0 0 6px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.card p {
|
||||
font-size: 11px;
|
||||
line-height: 1.45;
|
||||
color: #5b6575;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 9px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* ===== システム管理 ===== */
|
||||
.system-section {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.system-card {
|
||||
width: 265px;
|
||||
height: 96px;
|
||||
border: 1px solid #e0e5eb;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 7px #1e344d12;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
transition: .15s;
|
||||
}
|
||||
|
||||
.system-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
background: #e8f1ff;
|
||||
color: #3978d2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 25px;
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.system-card h3 {
|
||||
font-size: 13px;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
.system-card p {
|
||||
font-size: 10px;
|
||||
color: #5b6575;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ===== お知らせ ===== */
|
||||
.notice-section {
|
||||
margin-top: 15px;
|
||||
border-top: 1px solid #e4e8ee;
|
||||
padding-top: 9px;
|
||||
}
|
||||
|
||||
.notice-heading {
|
||||
display: flex;
|
||||
gap: 7px;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.notice-heading h2 {
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.count {
|
||||
background: #e84242;
|
||||
color: #fff;
|
||||
border-radius: 10px;
|
||||
font-size: 9px;
|
||||
padding: 2px 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notice-box {
|
||||
border: 1px solid #e1e6ec;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.notice {
|
||||
min-height: 36px;
|
||||
display: grid;
|
||||
grid-template-columns: 72px 270px 1fr 125px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 12px;
|
||||
border-bottom: 1px solid #edf0f3;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.notice:last-child {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.type {
|
||||
min-width: 51px;
|
||||
width: max-content;
|
||||
padding: 3px 5px;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.danger {
|
||||
background: #fde6e4;
|
||||
color: #d9362e;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background: #fff0d9;
|
||||
color: #dc7b11;
|
||||
}
|
||||
|
||||
.success {
|
||||
background: #e7f7e9;
|
||||
color: #36924a;
|
||||
}
|
||||
|
||||
.message,
|
||||
.target {
|
||||
font-weight: bold;
|
||||
color: #39465a;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.date {
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ===== フッター ===== */
|
||||
.footer {
|
||||
height: 42px;
|
||||
border-top: 1px solid #dfe4ea;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #687386;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/* ===== レスポンシブ ===== */
|
||||
@media (max-width : 1100px) {
|
||||
.menu-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.menu-grid.user-grid {
|
||||
grid-template-columns: repeat(3, minmax(200px, 250px));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width : 700px) {
|
||||
.user {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 160px;
|
||||
flex-basis: 160px;
|
||||
}
|
||||
|
||||
.menu-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.menu-grid.user-grid {
|
||||
grid-template-columns: repeat(2, minmax(200px, 250px));
|
||||
}
|
||||
|
||||
.notice {
|
||||
grid-template-columns: 60px 1fr;
|
||||
height: auto;
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
.target,
|
||||
.date {
|
||||
grid-column: 2;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width : 480px) {
|
||||
.layout {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menu-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.menu-grid.user-grid {
|
||||
grid-template-columns: minmax(220px, 250px);
|
||||
}
|
||||
|
||||
.system-card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- ===== ヘッダー ===== -->
|
||||
<header class="header">
|
||||
|
||||
<div class="header-title">
|
||||
<span class="book-icon">📖</span> ShareBooks
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
|
||||
<span class="user">
|
||||
<%=session.getAttribute("employeeName")%>(<%=roleName%>)
|
||||
</span>
|
||||
|
||||
<!-- <form action="${pageContext.request.contextPath}/logout" method="post"-->
|
||||
<!-- onsubmit="return confirm('ログアウトしますか?');">-->
|
||||
|
||||
<a th:href="@{/logout}" class="btn" method="post" onsubmit="return confirm('ログアウトしますか?');">
|
||||
|
||||
<button type="submit" class="logout">ログアウト</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="layout">
|
||||
|
||||
<!-- ===== サイドバー ===== -->
|
||||
<aside class="sidebar">
|
||||
|
||||
<div class="side-label">
|
||||
<%=isAdmin ? "共通画面" : "一般メニュー" %>
|
||||
</div>
|
||||
|
||||
<a class="side-menu active" href="${pageContext.request.contextPath}/topmenu.jsp"> <span
|
||||
class="side-icon">⌂</span> トップメニュー
|
||||
</a>
|
||||
|
||||
</aside>
|
||||
|
||||
<!-- ===== メイン ===== -->
|
||||
<main class="content">
|
||||
|
||||
<h1 class="title">トップメニュー</h1>
|
||||
|
||||
<!-- ===== 重要なお知らせ ===== -->
|
||||
<section class="notice-section">
|
||||
|
||||
<div class="notice-heading">
|
||||
<h2>重要なお知らせ</h2>
|
||||
<span class="count">1件</span>
|
||||
</div>
|
||||
|
||||
<div class="notice-box">
|
||||
|
||||
<div class="notice">
|
||||
<span class="type danger">返却期限</span> <span class="message">
|
||||
返却期限が超過している図書があります。 </span> <span class="target"> 対象図書: </span> <span class="date">
|
||||
2026/09/16 09:10 </span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 超過お知らせと下の文言は1行分空けたい -->
|
||||
|
||||
<section>
|
||||
|
||||
<h2 class="section-title">各一覧メニュー</h2>
|
||||
|
||||
<div class="menu-grid <%=isAdmin ? " admin-grid" : "user-grid" %>">
|
||||
|
||||
<!-- ===== 共通:社内図書一覧 ===== -->
|
||||
|
||||
<!-- <a class="card" href="${pageContext.request.contextPath}/BookServlet">-->
|
||||
<a th:href="@{/book}" class="btn">
|
||||
|
||||
<div class="icon green">📖</div>
|
||||
|
||||
<h3>社内図書一覧</h3>
|
||||
|
||||
<p>
|
||||
登録されている図書の<br> 一覧を表示します。
|
||||
</p> <span class="arrow">›</span>
|
||||
</a>
|
||||
|
||||
<!-- ===== 管理者のみ ===== -->
|
||||
<% if (isAdmin) { %>
|
||||
|
||||
<!-- <a class="card" href="${pageContext.request.contextPath}/lendList">-->
|
||||
|
||||
<a th:href="@{/lendlist}" class="btn">
|
||||
<div class="icon orange">📅</div>
|
||||
|
||||
<h3>
|
||||
※管理者機能<br> 貸出中図書一覧
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
貸出中の備品・図書の<br> 一覧を表示します。
|
||||
</p>
|
||||
|
||||
<span class="arrow"></span>
|
||||
</a>
|
||||
|
||||
<!-- <a class="card" href="${pageContext.request.contextPath}/approvalReceive">-->
|
||||
|
||||
<a th:href="@{/approvalReceive}" class="btn">
|
||||
<div class="icon red">▱</div>
|
||||
|
||||
<h3>
|
||||
※管理者機能<br> 寄贈申請受信ボックス
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
図書寄贈申請の<br> 受信一覧を確認します。
|
||||
</p>
|
||||
|
||||
<span class="arrow">›</span>
|
||||
|
||||
</a>
|
||||
|
||||
<% } %>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="section-title">寄贈申請・新規登録メニュー</h2>
|
||||
|
||||
<div class="menu-grid <%=isAdmin ? " admin-grid" : "user-grid" %>">
|
||||
|
||||
<!-- ===== 共通:寄贈申請 ===== -->
|
||||
<!-- <a class="card" href="${pageContext.request.contextPath}/bookApproval">-->
|
||||
|
||||
<a th:href="@{/bookApproval}" class="btn">
|
||||
|
||||
<div class="icon yellow">📗</div>
|
||||
|
||||
<h3>寄贈申請</h3>
|
||||
|
||||
<p>
|
||||
図書の寄贈申請を<br> 行います。
|
||||
</p> <span class="arrow">›</span>
|
||||
</a>
|
||||
|
||||
<!-- ===== 管理者のみ ===== -->
|
||||
|
||||
<% if (isAdmin) { %>
|
||||
|
||||
<!-- <a class="card" href="${pageContext.request.contextPath}/insertBook">-->
|
||||
|
||||
<a th:href="@{/bookInsert}" class="btn">
|
||||
|
||||
<div class="icon yellow">📗</div>
|
||||
|
||||
<h3>
|
||||
※管理者機能<br> 新規図書登録
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
図書の新規登録を<br> 行います。
|
||||
</p> <span class="arrow">›</span>
|
||||
</a>
|
||||
|
||||
<% } %>
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<!-- ===== パスワード再設定 ===== -->
|
||||
<section class="system-section <%=isAdmin ? " admin-system" : "user-system" %>">
|
||||
|
||||
<h2 class="section-title">システム管理メニュー</h2>
|
||||
|
||||
<!-- <a class="system-card" href="passwordChange.jsp">-->
|
||||
|
||||
<a th:href="@{/passwordChange}" class="btn">
|
||||
|
||||
<div class="system-icon">🔑</div>
|
||||
|
||||
<div>
|
||||
<h3>パスワード再設定</h3>
|
||||
<p>現在のパスワードを変更します。</p>
|
||||
</div> <span class="arrow">›</span>
|
||||
|
||||
</a>
|
||||
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="footer"> © 2026 社内備品・図書管理システム </footer>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user