0605
This commit is contained in:
parent
450f4d99cc
commit
64c51eb2fc
193
Backstage/access_detail.html
Normal file
193
Backstage/access_detail.html
Normal file
@ -0,0 +1,193 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-Hant">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>居民單日進出詳細紀錄</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h2>居民單日進出詳細紀錄</h2>
|
||||
<a href="resident_log_list.html" class="btn btn-outline-secondary">返回列表</a>
|
||||
</div>
|
||||
|
||||
<div id="recordSummary" class="card mb-3">
|
||||
<div class="card-header">
|
||||
基本資訊
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item"><strong>居民姓名:</strong> <span id="detailName"></span></li>
|
||||
<li class="list-group-item"><strong>日期:</strong> <span id="detailDate"></span></li>
|
||||
<li class="list-group-item"><strong>紀錄 ID:</strong> <span id="detailLogId"></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-4">進出事件列表</h4>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>事件類型</th>
|
||||
<th>時間</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="accessEventsTableBody">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="nextReturnHint" class="mt-3 alert alert-info" style="display: none;">
|
||||
</div>
|
||||
|
||||
<div id="notFoundMessage" class="alert alert-warning mt-3" style="display: none;">
|
||||
找不到指定的紀錄,或該紀錄沒有詳細的進出事件。
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
const detailedAccessLogs = [
|
||||
{
|
||||
logId: 1, residentName: "張XX", date: "2022-06-05",
|
||||
accessEvents: [
|
||||
{ type: "進入", time: "09:15:30" }, { type: "離開", time: "10:45:10" },
|
||||
{ type: "進入", time: "11:00:00" }, { type: "離開", time: "11:24:05" },
|
||||
{ type: "進入", time: "16:02:18" }, { type: "離開", time: "17:30:00" } // 最後是離開
|
||||
]
|
||||
},
|
||||
{
|
||||
logId: 2, residentName: "李XX", date: "2022-05-30",
|
||||
accessEvents: [
|
||||
{ type: "離開", time: "01:00:00" }, { type: "進入", time: "02:30:00" },
|
||||
{ type: "離開", time: "06:17:23" }, { type: "進入", time: "09:00:00" },
|
||||
{ type: "離開", time: "10:00:00" }, { type: "進入", time: "11:05:32" } // 最後是進入
|
||||
]
|
||||
},
|
||||
{
|
||||
logId: 3, residentName: "黃XX", date: "2022-05-27",
|
||||
accessEvents: [
|
||||
{ type: "進入", time: "00:58:52" }, { type: "離開", time: "08:30:00" },
|
||||
{ type: "進入", time: "12:00:00" }, { type: "離開", time: "13:00:00" },
|
||||
{ type: "進入", time: "15:00:00" }, { type: "離開", time: "16:15:54" } // 最後是離開
|
||||
]
|
||||
},
|
||||
{ // 張XX 在 2022-06-05 離開後,於 2022-06-13 返回
|
||||
logId: 4, residentName: "張XX", date: "2022-06-13",
|
||||
accessEvents: [
|
||||
{ type: "進入", time: "03:08:27" }, { type: "離開", time: "10:00:00" },
|
||||
{ type: "進入", time: "18:06:35" }, { type: "離開", time: "20:00:00" }
|
||||
]
|
||||
},
|
||||
{
|
||||
logId: 5, residentName: "王小明", date: "2022-06-14",
|
||||
accessEvents: [
|
||||
{ type: "進入", time: "09:00:00" }, { type: "離開", time: "12:30:00" },
|
||||
{ type: "進入", time: "13:30:00" }, { type: "離開", time: "17:00:00" } // 最後是離開
|
||||
]
|
||||
},
|
||||
{ logId: 6, residentName: "林美麗", date: "2022-06-14", accessEvents: [] },
|
||||
{
|
||||
logId: 7, residentName: "陳大文", date: "2022-06-15",
|
||||
accessEvents: [{ type: "進入", time: "08:15:45" }, { type: "離開", time: "12:20:30" }] // 最後是離開
|
||||
},
|
||||
{ // 陳大文 在 2022-06-15 離開後,於 2022-06-16 返回
|
||||
logId: 9, residentName: "陳大文", date: "2022-06-16",
|
||||
accessEvents: [{ type: "進入", time: "09:00:00" }]
|
||||
},
|
||||
{
|
||||
logId: 8, residentName: "李XX", date: "2022-06-15",
|
||||
accessEvents: [
|
||||
{ type: "進入", time: "14:00:00" }, { type: "離開", time: "15:30:00" },
|
||||
{ type: "進入", time: "16:00:00" }, { type: "離開", time: "19:00:00" } // 最後是離開
|
||||
]
|
||||
},
|
||||
{ // 李XX 在 2022-06-15 19:00:00 離開後,於 2022-06-17 20:00:00 返回 (長途)
|
||||
logId: 10, residentName: "李XX", date: "2022-06-17",
|
||||
accessEvents: [{ type: "進入", time: "20:00:00" }]
|
||||
}
|
||||
];
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const currentLogId = parseInt(urlParams.get('id'));
|
||||
|
||||
if (isNaN(currentLogId)) {
|
||||
showNotFound();
|
||||
return;
|
||||
}
|
||||
|
||||
const currentLogEntry = detailedAccessLogs.find(log => log.logId === currentLogId);
|
||||
|
||||
if (currentLogEntry) {
|
||||
document.getElementById('detailLogId').textContent = currentLogEntry.logId;
|
||||
document.getElementById('detailName').textContent = currentLogEntry.residentName;
|
||||
document.getElementById('detailDate').textContent = currentLogEntry.date;
|
||||
|
||||
const eventsTableBody = document.getElementById('accessEventsTableBody');
|
||||
eventsTableBody.innerHTML = '';
|
||||
|
||||
if (currentLogEntry.accessEvents && currentLogEntry.accessEvents.length > 0) {
|
||||
currentLogEntry.accessEvents.forEach((event, index) => {
|
||||
const row = eventsTableBody.insertRow();
|
||||
row.insertCell().textContent = index + 1;
|
||||
row.insertCell().textContent = event.type;
|
||||
row.insertCell().textContent = event.time;
|
||||
});
|
||||
|
||||
// --- 新增:檢查並提示下次返回時間 ---
|
||||
const lastEvent = currentLogEntry.accessEvents[currentLogEntry.accessEvents.length - 1];
|
||||
if (lastEvent.type === "離開") {
|
||||
const lastEventTimestampStr = currentLogEntry.date + "T" + lastEvent.time;
|
||||
let nextEntryEvent = null;
|
||||
|
||||
for (const log of detailedAccessLogs) {
|
||||
if (log.residentName === currentLogEntry.residentName) {
|
||||
for (const event of log.accessEvents) {
|
||||
const eventTimestampStr = log.date + "T" + event.time;
|
||||
if (eventTimestampStr > lastEventTimestampStr && event.type === "進入") {
|
||||
if (!nextEntryEvent || eventTimestampStr < (nextEntryEvent.date + "T" + nextEntryEvent.time)) {
|
||||
nextEntryEvent = {
|
||||
logId: log.logId,
|
||||
date: log.date,
|
||||
time: event.time,
|
||||
type: event.type
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nextEntryEvent) {
|
||||
const hintDiv = document.getElementById('nextReturnHint');
|
||||
hintDiv.innerHTML = `居民 (<Strong>${currentLogEntry.residentName}</Strong>) 下次返回時間為:<strong>${nextEntryEvent.date} ${nextEntryEvent.time}</strong>。
|
||||
(詳見 <a href="access_detail.html?id=${nextEntryEvent.logId}">該日(${nextEntryEvent.date})記錄</a>)`;
|
||||
hintDiv.style.display = 'block';
|
||||
}
|
||||
}
|
||||
// --- 提示功能結束 ---
|
||||
|
||||
} else {
|
||||
const row = eventsTableBody.insertRow();
|
||||
const cell = row.insertCell();
|
||||
cell.colSpan = 3;
|
||||
cell.textContent = '本日無詳細進出事件記錄。';
|
||||
cell.classList.add('text-center', 'text-muted');
|
||||
}
|
||||
} else {
|
||||
showNotFound();
|
||||
}
|
||||
});
|
||||
|
||||
function showNotFound() {
|
||||
document.getElementById('recordSummary').style.display = 'none';
|
||||
document.querySelector('h4').style.display = 'none';
|
||||
document.querySelector('table').style.display = 'none';
|
||||
document.getElementById('nextReturnHint').style.display = 'none';
|
||||
document.getElementById('notFoundMessage').style.display = 'block';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
144
Backstage/access_management.html
Normal file
144
Backstage/access_management.html
Normal file
@ -0,0 +1,144 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-Hant">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>居民進出紀錄</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between mb-3 align-items-center">
|
||||
<h2>居民進出紀錄</h2>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-3 align-items-end">
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<label for="searchName" class="form-label">居民姓名</label>
|
||||
<input type="text" id="searchName" class="form-control" placeholder="搜尋居民姓名">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<label for="searchStartDate" class="form-label">起始日期</label>
|
||||
<input type="date" id="searchStartDate" class="form-control">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<label for="searchEndDate" class="form-label">結束日期</label>
|
||||
<input type="date" id="searchEndDate" class="form-control">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="searchRecords()">搜尋</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>居民</th>
|
||||
<th>日期</th>
|
||||
<th>最後進入時間</th>
|
||||
<th>最後出去時間</th>
|
||||
<th>本日進出次數</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="recordTable"></tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>第 <span id="currentPage">1</span> 頁,共 <span id="totalPages">1</span> 頁</div>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-outline-secondary me-1" id="prevBtn">上一頁</button>
|
||||
<button class="btn btn-sm btn-outline-secondary" id="nextBtn">下一頁</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
const records = [
|
||||
{ id: 1, name: "張XX", date: "2022-06-05", lastEntryTime: "16:02:18", lastExitTime: "11:24:05", accessCount: 3 },
|
||||
{ id: 2, name: "李XX", date: "2022-05-30", lastEntryTime: "11:05:32", lastExitTime: "06:17:23", accessCount: 3 },
|
||||
{ id: 3, name: "黃XX", date: "2022-05-27", lastEntryTime: "00:58:52", lastExitTime: "16:15:54", accessCount: 3 },
|
||||
{ id: 4, name: "張XX", date: "2022-06-13", lastEntryTime: "18:06:35", lastExitTime: "03:08:27", accessCount: 2 },
|
||||
{ id: 5, name: "王小明", date: "2022-06-14", lastEntryTime: "09:00:00", lastExitTime: "17:00:00", accessCount: 2 },
|
||||
{ id: 6, name: "林美麗", date: "2022-06-14", lastEntryTime: "10:30:15", lastExitTime: "18:30:00", accessCount: 2 },
|
||||
{ id: 7, name: "陳大文", date: "2022-06-15", lastEntryTime: "08:15:45", lastExitTime: "12:20:30", accessCount: 1 },
|
||||
{ id: 8, name: "李XX", date: "2022-06-15", lastEntryTime: "14:00:00", lastExitTime: "19:00:00", accessCount: 4 }
|
||||
];
|
||||
|
||||
let currentPage = 1;
|
||||
const pageSize = 5;
|
||||
let filteredRecords = [...records];
|
||||
|
||||
function renderTable() {
|
||||
const tbody = document.getElementById("recordTable");
|
||||
tbody.innerHTML = "";
|
||||
const start = (currentPage - 1) * pageSize;
|
||||
const pageData = filteredRecords.slice(start, start + pageSize);
|
||||
|
||||
pageData.forEach(r => {
|
||||
tbody.innerHTML += `
|
||||
<tr>
|
||||
<td>${r.name}</td>
|
||||
<td>${r.date}</td>
|
||||
<td>${r.lastEntryTime}</td>
|
||||
<td>${r.lastExitTime}</td>
|
||||
<td>${r.accessCount}</td>
|
||||
<td><a href="access_detail.html?id=${r.id}" class="btn btn-outline-secondary btn-sm">查看</a></td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
const totalPages = Math.ceil(filteredRecords.length / pageSize) || 1;
|
||||
document.getElementById("currentPage").textContent = currentPage;
|
||||
document.getElementById("totalPages").textContent = totalPages;
|
||||
document.getElementById("prevBtn").disabled = currentPage === 1;
|
||||
document.getElementById("nextBtn").disabled = currentPage === totalPages;
|
||||
}
|
||||
|
||||
document.getElementById("prevBtn").onclick = () => {
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
renderTable();
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById("nextBtn").onclick = () => {
|
||||
const totalPages = Math.ceil(filteredRecords.length / pageSize);
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
renderTable();
|
||||
}
|
||||
};
|
||||
|
||||
function searchRecords() {
|
||||
const nameKey = document.getElementById("searchName").value.trim().toLowerCase();
|
||||
const startDateKey = document.getElementById("searchStartDate").value;
|
||||
const endDateKey = document.getElementById("searchEndDate").value;
|
||||
|
||||
filteredRecords = records.filter(r => {
|
||||
const nameMatch = r.name.toLowerCase().includes(nameKey);
|
||||
|
||||
let dateMatch = true;
|
||||
if (startDateKey && endDateKey) {
|
||||
dateMatch = r.date >= startDateKey && r.date <= endDateKey;
|
||||
} else if (startDateKey) {
|
||||
dateMatch = r.date >= startDateKey;
|
||||
} else if (endDateKey) {
|
||||
dateMatch = r.date <= endDateKey;
|
||||
}
|
||||
|
||||
return nameMatch && dateMatch;
|
||||
});
|
||||
|
||||
currentPage = 1;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
// Modal 相關的 JavaScript 已被移除
|
||||
// document.getElementById("modalSearchInput").addEventListener("input", function () { ... });
|
||||
|
||||
renderTable();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -29,20 +29,18 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top-banner">
|
||||
<button class="signin-btn">簽到</button>
|
||||
</div>
|
||||
<div class="top-banner"></div>
|
||||
<div class="dashboard-content-grid">
|
||||
<div class="left-panel">
|
||||
<div class="card">
|
||||
<div style="font-weight: bold; color: #3b8eea; margin-bottom: 10px;">居民進出</div>
|
||||
<table class="table">
|
||||
<thead><tr><th></th><th>居民</th><th>出入棟</th><th>日期</th><th>進入時間</th><th>出去時間</th><th>本日進出次數</th><th></th></tr></thead>
|
||||
<thead><tr><th></th><th>居民</th><th>日期</th><th>最後進入時間</th><th>最後出去時間</th><th>本日進出次數</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td></td><td>張XX</td><td>A棟</td><td>2022-06-05</td><td>16:02:18</td><td>11:24:05</td><td>3</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>李XX</td><td>B棟</td><td>2022-05-30</td><td>11:05:32</td><td>06:17:23</td><td>3</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>黃XX</td><td>A棟</td><td>2022-05-27</td><td>00:58:52</td><td>16:15:54</td><td>3</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>張XX</td><td>A棟</td><td>2022-06-13</td><td>18:06:35</td><td>03:08:27</td><td>2</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>張XX</td><td>2022-06-05</td><td>16:02:18</td><td>11:24:05</td><td>3</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>李XX</td><td>2022-05-30</td><td>11:05:32</td><td>06:17:23</td><td>3</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>黃XX</td><td>2022-05-27</td><td>00:58:52</td><td>16:15:54</td><td>3</td><td><a href="#">查看</a></td></tr>
|
||||
<tr><td></td><td>張XX</td><td>2022-06-13</td><td>18:06:35</td><td>03:08:27</td><td>2</td><td><a href="#">查看</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -86,7 +84,7 @@
|
||||
data: {
|
||||
labels: ['4/30', '5/1', '5/2', '5/3', '5/4', '5/5', '5/6'],
|
||||
datasets: [{
|
||||
label: '進出人數',
|
||||
label: '進出人次',
|
||||
data: [12, 19, 3, 5, 2, 8, 10],
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.5)',
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
|
@ -85,6 +85,7 @@
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">狀態</label>
|
||||
<select class="form-select" id="status" required>
|
||||
<option value="未到貨">未到貨</option>
|
||||
<option value="待領取" selected>待領取</option>
|
||||
<option value="已領取">已領取</option>
|
||||
<option value="已退回">已退回</option>
|
||||
|
@ -84,9 +84,10 @@
|
||||
<input type="text" class="form-control" id="packageNumber" placeholder="輸入包裹追蹤編號" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="mb-3">
|
||||
<label for="status" class="form-label">狀態</label>
|
||||
<select class="form-select" id="status" required>
|
||||
<option value="未到貨">未到貨</option>
|
||||
<option value="待領取">待領取</option>
|
||||
<option value="已領取">已領取</option>
|
||||
<option value="已退回">已退回</option>
|
||||
|
@ -38,6 +38,7 @@
|
||||
<div class="col-sm-6 col-md-2 col-lg-2">
|
||||
<select id="searchStatus" class="form-select">
|
||||
<option value="">所有狀態</option>
|
||||
<option value="未到貨">未到貨</option>
|
||||
<option value="待領取">待領取</option>
|
||||
<option value="已領取">已領取</option>
|
||||
<option value="已退回">已退回</option>
|
||||
@ -119,6 +120,9 @@
|
||||
let statusBadgeClass = 'bg-secondary'; // Default badge
|
||||
let statusText = pkg.status;
|
||||
switch (pkg.status) {
|
||||
case '未到貨':
|
||||
statusBadgeClass = 'bg-info text-dark'; // Badge for "Not Arrived"
|
||||
break;
|
||||
case '待領取':
|
||||
statusBadgeClass = 'bg-warning text-dark';
|
||||
break;
|
||||
|
@ -1,67 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-Hant">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>水電報修列表</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
/* 只針對狀態欄位中的 badge 進行字體放大 */
|
||||
.status-badge {
|
||||
font-size: 0.9rem;
|
||||
padding: 0.6em 0.9em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between mb-3">
|
||||
<h2>水電報修列表</h2>
|
||||
</div>
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-sm-6 col-md-3 col-lg-2">
|
||||
<input type="text" id="searchName" class="form-control" placeholder="搜尋姓名">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-2">
|
||||
<input type="text" id="searchroom" class="form-control" placeholder="搜尋 房號">
|
||||
</div>
|
||||
<div class="col-6 col-md-2 col-lg-2">
|
||||
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="window.alert('依據查詢關鍵字列出');">搜尋</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>報修類型</th>
|
||||
<th>住戶姓名</th>
|
||||
<th>房號</th>
|
||||
<th>報修說明</th>
|
||||
<th>送出時間</th>
|
||||
<th>狀態</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>水管漏水</td>
|
||||
<td>王小明</td>
|
||||
<th>C2C</th>
|
||||
<td>廚房水管滴水不止</td>
|
||||
<td>2025-05-20 10:15</td>
|
||||
<td><span class="badge bg-warning text-dark status-badge">待處理</span></td>
|
||||
<td><a href="repair_edit.html?id=1" class="btn btn-outline-secondary btn-sm">查看 / 編輯</a></td>
|
||||
</tr>
|
||||
<!-- 更多資料列可依照實際情況加上 -->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>第 <span>1</span> 頁,共 <span>1</span> 頁</div>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-outline-secondary me-1">上一頁</button>
|
||||
<button class="btn btn-sm btn-outline-secondary">下一頁</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -5,11 +5,38 @@
|
||||
<title>編輯報修資料</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
.suggestions-container {
|
||||
position: relative;
|
||||
}
|
||||
.suggestions-box {
|
||||
position: absolute;
|
||||
border: 1px solid #ced4da;
|
||||
border-top: none;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
.suggestion-item {
|
||||
padding: 0.5rem 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.suggestion-item:hover, .suggestion-item.active {
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
.suggestions-box:empty {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<h2 class="mb-4">報修詳情</h2>
|
||||
<form>
|
||||
<form id="editRepairForm">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">報修類型</label>
|
||||
<input type="text" class="form-control" value="水管漏水" disabled>
|
||||
@ -32,6 +59,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 suggestions-container">
|
||||
<label for="repairVendor" class="form-label">報修廠商 (可輸入搜尋)</label>
|
||||
<input type="text" class="form-control" id="repairVendor" placeholder="輸入廠商名稱開始搜尋" autocomplete="off">
|
||||
<div id="suggestionsBoxRepairVendor" class="suggestions-box"></div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="notes" class="form-label">備註</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="3" placeholder="輸入其他備註事項 (選填)"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="costInput" class="form-label">維修費用(元)</label>
|
||||
<input type="number" class="form-control" id="costInput" name="cost" value="0" min="0" step="1" placeholder="例如:500">
|
||||
@ -39,7 +77,7 @@
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="statusSelect" class="form-label">狀態</label>
|
||||
<select id="statusSelect" class="form-select">
|
||||
<select id="statusSelect" name="status" class="form-select">
|
||||
<option value="待處理" selected>待處理</option>
|
||||
<option value="已報修">已報修</option>
|
||||
<option value="處理中">處理中</option>
|
||||
@ -51,5 +89,129 @@
|
||||
<a href="repair_list.html" class="btn btn-secondary ms-2">返回列表</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const allRepairVendors = [
|
||||
"AAA水電維修公司", "快修宅水電工程", "水管速通中心", "專業抓漏防水工程", "BBB冷氣空調維修",
|
||||
"安心家電維修站", "智慧家庭設備安裝", "社區指定水電行 (陳師傅)", "燈具照明專家 (李老闆)", "其他廠商"
|
||||
];
|
||||
|
||||
const repairVendorInput = document.getElementById('repairVendor');
|
||||
const suggestionsBoxRepairVendor = document.getElementById('suggestionsBoxRepairVendor');
|
||||
|
||||
function setupSuggestions(inputElement, suggestionsBoxElement, sourceArray) {
|
||||
let currentActiveIndex = -1;
|
||||
inputElement.addEventListener('input', function() {
|
||||
const inputText = this.value.toLowerCase();
|
||||
suggestionsBoxElement.innerHTML = '';
|
||||
currentActiveIndex = -1;
|
||||
if (inputText.length === 0) {
|
||||
suggestionsBoxElement.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
const filteredItems = sourceArray.filter(item =>
|
||||
item.toLowerCase().includes(inputText)
|
||||
);
|
||||
if (filteredItems.length > 0) {
|
||||
filteredItems.forEach((itemText, index) => {
|
||||
const item = document.createElement('div');
|
||||
item.classList.add('suggestion-item');
|
||||
item.textContent = itemText;
|
||||
item.addEventListener('click', function() {
|
||||
inputElement.value = itemText;
|
||||
suggestionsBoxElement.innerHTML = '';
|
||||
suggestionsBoxElement.style.display = 'none';
|
||||
});
|
||||
item.setAttribute('data-index', index);
|
||||
suggestionsBoxElement.appendChild(item);
|
||||
});
|
||||
suggestionsBoxElement.style.display = 'block';
|
||||
} else {
|
||||
suggestionsBoxElement.style.display = 'none';
|
||||
}
|
||||
});
|
||||
inputElement.addEventListener('keydown', function(e) {
|
||||
const items = suggestionsBoxElement.querySelectorAll('.suggestion-item');
|
||||
if (items.length === 0 || suggestionsBoxElement.style.display === 'none') return;
|
||||
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
currentActiveIndex = (currentActiveIndex + 1) % items.length;
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
currentActiveIndex = (currentActiveIndex - 1 + items.length) % items.length;
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (currentActiveIndex > -1 && items[currentActiveIndex]) {
|
||||
items[currentActiveIndex].click();
|
||||
}
|
||||
// If no suggestion is active, Enter will be handled by the form's default behavior or main submit button.
|
||||
return;
|
||||
} else if (e.key === 'Escape') {
|
||||
suggestionsBoxElement.innerHTML = '';
|
||||
suggestionsBoxElement.style.display = 'none';
|
||||
currentActiveIndex = -1;
|
||||
}
|
||||
updateActiveSuggestion(items, currentActiveIndex);
|
||||
});
|
||||
}
|
||||
|
||||
function updateActiveSuggestion(items, activeIndex) {
|
||||
items.forEach(item => item.classList.remove('active'));
|
||||
if (items[activeIndex]) {
|
||||
items[activeIndex].classList.add('active');
|
||||
items[activeIndex].scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
}
|
||||
|
||||
setupSuggestions(repairVendorInput, suggestionsBoxRepairVendor, allRepairVendors);
|
||||
|
||||
document.addEventListener('click', function(event) {
|
||||
const suggestionInputs = [repairVendorInput]; // Add other suggestion inputs here if you have more
|
||||
const suggestionBoxes = [suggestionsBoxRepairVendor]; // Add other suggestion boxes here
|
||||
|
||||
let clickedInsideASuggestionArea = false;
|
||||
for (let i = 0; i < suggestionInputs.length; i++) {
|
||||
if ((suggestionInputs[i] && suggestionInputs[i].contains(event.target)) ||
|
||||
(suggestionBoxes[i] && suggestionBoxes[i].contains(event.target))) {
|
||||
clickedInsideASuggestionArea = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!clickedInsideASuggestionArea) {
|
||||
suggestionBoxes.forEach(box => {
|
||||
if (box) {
|
||||
box.innerHTML = '';
|
||||
box.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Optional: Add form submission handling if needed, similar to visitor_edit.html
|
||||
document.getElementById('editRepairForm').addEventListener('submit', function(event) {
|
||||
event.preventDefault(); // Prevent default form submission for now
|
||||
|
||||
const repairData = {
|
||||
repairType: document.querySelector('input[value="水管漏水"]').value, // Example: how to get disabled field value
|
||||
residentName: document.querySelector('input[value="王小明"]').value, // Example
|
||||
description: document.querySelector('textarea[disabled]').value, // Example
|
||||
repairVendor: repairVendorInput.value,
|
||||
notes: document.getElementById('notes').value,
|
||||
cost: document.getElementById('costInput').value,
|
||||
status: document.getElementById('statusSelect').value,
|
||||
// Add other fields as needed
|
||||
};
|
||||
|
||||
console.log("儲存的報修資料:", repairData);
|
||||
alert("報修資料已儲存 (詳見控制台)!\n廠商: " + repairData.repairVendor + "\n備註: " + repairData.notes);
|
||||
// Here you would typically send the data to a server or update localStorage
|
||||
// For example, to redirect:
|
||||
// window.location.href = 'repair_list.html';
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
144
Backstage/resident_log_list.html
Normal file
144
Backstage/resident_log_list.html
Normal file
@ -0,0 +1,144 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-Hant">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>居民進出紀錄</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-between mb-3 align-items-center">
|
||||
<h2>居民進出紀錄</h2>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-3 align-items-end">
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<label for="searchName" class="form-label">居民姓名</label>
|
||||
<input type="text" id="searchName" class="form-control" placeholder="搜尋居民姓名">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<label for="searchStartDate" class="form-label">起始日期</label>
|
||||
<input type="date" id="searchStartDate" class="form-control">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<label for="searchEndDate" class="form-label">結束日期</label>
|
||||
<input type="date" id="searchEndDate" class="form-control">
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||
<button class="btn btn-outline-primary w-100 rounded-pill" onclick="searchRecords()">搜尋</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>居民</th>
|
||||
<th>日期</th>
|
||||
<th>最後進入時間</th>
|
||||
<th>最後出去時間</th>
|
||||
<th>本日進出次數</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="recordTable"></tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>第 <span id="currentPage">1</span> 頁,共 <span id="totalPages">1</span> 頁</div>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-outline-secondary me-1" id="prevBtn">上一頁</button>
|
||||
<button class="btn btn-sm btn-outline-secondary" id="nextBtn">下一頁</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
const records = [
|
||||
{ id: 1, name: "張XX", date: "2022-06-05", lastEntryTime: "16:02:18", lastExitTime: "11:24:05", accessCount: 3 },
|
||||
{ id: 2, name: "李XX", date: "2022-05-30", lastEntryTime: "11:05:32", lastExitTime: "06:17:23", accessCount: 3 },
|
||||
{ id: 3, name: "黃XX", date: "2022-05-27", lastEntryTime: "00:58:52", lastExitTime: "16:15:54", accessCount: 3 },
|
||||
{ id: 4, name: "張XX", date: "2022-06-13", lastEntryTime: "18:06:35", lastExitTime: "03:08:27", accessCount: 2 },
|
||||
{ id: 5, name: "王小明", date: "2022-06-14", lastEntryTime: "09:00:00", lastExitTime: "17:00:00", accessCount: 2 },
|
||||
{ id: 6, name: "林美麗", date: "2022-06-14", lastEntryTime: "10:30:15", lastExitTime: "18:30:00", accessCount: 2 },
|
||||
{ id: 7, name: "陳大文", date: "2022-06-15", lastEntryTime: "08:15:45", lastExitTime: "12:20:30", accessCount: 1 },
|
||||
{ id: 8, name: "李XX", date: "2022-06-15", lastEntryTime: "14:00:00", lastExitTime: "19:00:00", accessCount: 4 }
|
||||
];
|
||||
|
||||
let currentPage = 1;
|
||||
const pageSize = 5;
|
||||
let filteredRecords = [...records];
|
||||
|
||||
function renderTable() {
|
||||
const tbody = document.getElementById("recordTable");
|
||||
tbody.innerHTML = "";
|
||||
const start = (currentPage - 1) * pageSize;
|
||||
const pageData = filteredRecords.slice(start, start + pageSize);
|
||||
|
||||
pageData.forEach(r => {
|
||||
tbody.innerHTML += `
|
||||
<tr>
|
||||
<td>${r.name}</td>
|
||||
<td>${r.date}</td>
|
||||
<td>${r.lastEntryTime}</td>
|
||||
<td>${r.lastExitTime}</td>
|
||||
<td>${r.accessCount}</td>
|
||||
<td><a href="access_detail.html?id=${r.id}" class="btn btn-outline-secondary btn-sm">查看</a></td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
|
||||
const totalPages = Math.ceil(filteredRecords.length / pageSize) || 1;
|
||||
document.getElementById("currentPage").textContent = currentPage;
|
||||
document.getElementById("totalPages").textContent = totalPages;
|
||||
document.getElementById("prevBtn").disabled = currentPage === 1;
|
||||
document.getElementById("nextBtn").disabled = currentPage === totalPages;
|
||||
}
|
||||
|
||||
document.getElementById("prevBtn").onclick = () => {
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
renderTable();
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById("nextBtn").onclick = () => {
|
||||
const totalPages = Math.ceil(filteredRecords.length / pageSize);
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
renderTable();
|
||||
}
|
||||
};
|
||||
|
||||
function searchRecords() {
|
||||
const nameKey = document.getElementById("searchName").value.trim().toLowerCase();
|
||||
const startDateKey = document.getElementById("searchStartDate").value;
|
||||
const endDateKey = document.getElementById("searchEndDate").value;
|
||||
|
||||
filteredRecords = records.filter(r => {
|
||||
const nameMatch = r.name.toLowerCase().includes(nameKey);
|
||||
|
||||
let dateMatch = true;
|
||||
if (startDateKey && endDateKey) {
|
||||
dateMatch = r.date >= startDateKey && r.date <= endDateKey;
|
||||
} else if (startDateKey) {
|
||||
dateMatch = r.date >= startDateKey;
|
||||
} else if (endDateKey) {
|
||||
dateMatch = r.date <= endDateKey;
|
||||
}
|
||||
|
||||
return nameMatch && dateMatch;
|
||||
});
|
||||
|
||||
currentPage = 1;
|
||||
renderTable();
|
||||
}
|
||||
|
||||
// Modal 相關的 JavaScript 已被移除
|
||||
// document.getElementById("modalSearchInput").addEventListener("input", function () { ... });
|
||||
|
||||
renderTable();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -179,7 +179,7 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li onclick="requestNavigation('some_page1.html', this)">出入管理</li>
|
||||
<li onclick="requestNavigation('resident_log_list.html', this)">出入管理</li>
|
||||
<li class="has-submenu">
|
||||
<div class="submenu-toggle" onclick="toggleSubmenu(this)">
|
||||
<span>居民訊息</span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user