Contents
admin_attendance.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>出勤状況一覧</title>
</head>
<body>
<h1>出勤状況一覧</h1>
<a href="admin_requests.html">▶ 申請管理ページへ</a>
<table border="1">
<thead>
<tr>
<th>名前</th>
<th>メールアドレス</th>
<th>出勤状況</th>
<th>詳細</th>
</tr>
</thead>
<tbody id="userList"></tbody>
</table>
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.11.0/firebase-app.js";
import {
getFirestore, collection, getDocs, query, where, orderBy, limit
} from "https://www.gstatic.com/firebasejs/10.11.0/firebase-firestore.js";
const firebaseConfig = {
apiKey: "あなたのAPIキー",
authDomain: "あなたのプロジェクトID.firebaseapp.com",
projectId: "あなたのプロジェクトID",
storageBucket: "あなたのプロジェクトID.appspot.com",
messagingSenderId: "送信者ID",
appId: "アプリID"
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
async function loadUsers() {
const userList = document.getElementById("userList");
userList.innerHTML = "";
const usersSnapshot = await getDocs(collection(db, "users"));
for (const docSnap of usersSnapshot.docs) {
const user = docSnap.data();
const uid = docSnap.id;
let status = "不明";
const attendanceQuery = query(
collection(db, "attendance"),
where("uid", "==", uid),
orderBy("timestamp", "desc"),
limit(1)
);
const attendanceSnapshot = await getDocs(attendanceQuery);
if (!attendanceSnapshot.empty) {
const last = attendanceSnapshot.docs[0].data();
const lastTimestamp = last.timestamp.toDate();
const now = new Date();
const isSameDay =
lastTimestamp.getFullYear() === now.getFullYear() &&
lastTimestamp.getMonth() === now.getMonth() &&
lastTimestamp.getDate() === now.getDate();
status = (last.type === "出勤" && isSameDay) ? "出勤中" : "退勤済み";
}
const detailLink = `<a href="user_detail.html?uid=${uid}&name=${encodeURIComponent(user.name)}" target="_blank">詳細</a>`;
const row = `
<tr>
<td>${user.name}</td>
<td>${user.email}</td>
<td>${status}</td>
<td>${detailLink}</td>
</tr>
`;
userList.innerHTML += row;
}
}
window.onload = () => {
loadUsers();
};
</script>
</body>
</html>
✅ 現在の機能まとめ
このHTMLは、Firebase Firestoreを使ってユーザーの出勤状況一覧を表示する管理用ページです。
機能 | 内容 |
---|---|
Firebase連携 | users と attendance コレクションを読み込む |
出勤状況判定 | 本日中の最新の「出勤」記録があれば「出勤中」、なければ「退勤済み」表示 |
ユーザー一覧表示 | 名前・メール・出勤状況・詳細リンクをテーブルに表示 |
詳細リンク | user_detail.html に uid と name をクエリパラメータで送信 |
🧠 解説ポイント
1. users
コレクションの読み込み
const usersSnapshot = await getDocs(collection(db, "users"));
全ユーザーの一覧を取得。
2. 各ユーザーの最新出退勤情報の取得
const attendanceQuery = query(
collection(db, "attendance"),
where("uid", "==", uid),
orderBy("timestamp", "desc"),
limit(1)
);
- 該当ユーザーの最新の出退勤記録(1件)を取得。
timestamp
による降順ソート +limit(1)
により「最新」を取得。
3. 出勤中か退勤済みかの判定
const isSameDay =
lastTimestamp.getFullYear() === now.getFullYear() &&
lastTimestamp.getMonth() === now.getMonth() &&
lastTimestamp.getDate() === now.getDate();
status = (last.type === "出勤" && isSameDay) ? "出勤中" : "退勤済み";
- 本日中の「出勤」記録なら「出勤中」
- それ以外(古い or 「退勤」記録)は「退勤済み」
4. 詳細ページリンク
<a href="user_detail.html?uid=${uid}&name=${encodeURIComponent(user.name)}" target="_blank">詳細</a>
- ユーザーIDと名前をパラメータとして送信
target="_blank"
で別タブ表示
admin_requests.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>申請管理</title>
</head>
<body>
<h1>申請管理ページ</h1>
<a href="admin_attendance.html">▶ 出勤状況一覧ページへ</a>
<h2>申請中のもののみ表示</h2>
<table border="1">
<thead>
<tr>
<th>氏名</th>
<th>申請日</th>
<th>種類</th>
<th>理由</th>
<th>操作</th>
</tr>
</thead>
<tbody id="adminRequestBody"></tbody>
</table>
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.11.0/firebase-app.js";
import {
getFirestore, collection, getDocs, query, where, orderBy, updateDoc, doc
} from "https://www.gstatic.com/firebasejs/10.11.0/firebase-firestore.js";
const firebaseConfig = {
apiKey: "あなたのAPIキー",
authDomain: "あなたのプロジェクトID.firebaseapp.com",
projectId: "あなたのプロジェクトID",
storageBucket: "あなたのプロジェクトID.appspot.com",
messagingSenderId: "送信者ID",
appId: "アプリID"
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
async function getUserMap() {
const map = {};
const usersSnapshot = await getDocs(collection(db, "users"));
usersSnapshot.forEach(doc => {
map[doc.id] = doc.data().name;
});
return map;
}
async function loadAdminRequests() {
const tbody = document.getElementById("adminRequestBody");
tbody.innerHTML = "";
const userMap = await getUserMap();
const q = query(
collection(db, "applications"),
where("status", "==", "申請中"),
orderBy("timestamp", "desc")
);
const snapshot = await getDocs(q);
for (const docSnap of snapshot.docs) {
const data = docSnap.data();
const id = docSnap.id;
const date = data.timestamp?.toDate?.() || new Date();
const userName = userMap[data.uid] || "不明";
const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${String(date.getMinutes()).padStart(2, '0')}`;
const row = `
<tr id="admin-request-${id}">
<td>${userName}</td>
<td>${formattedDate}</td>
<td>${data.type}</td>
<td>${data.reason || "なし"}</td>
<td>
<button onclick="adminUpdateStatus('${id}', '許可')">許可</button>
<button onclick="adminUpdateStatus('${id}', '却下')">却下</button>
</td>
</tr>
`;
tbody.innerHTML += row;
}
}
window.adminUpdateStatus = async function(id, status) {
const ref = doc(db, "applications", id);
await updateDoc(ref, { status });
const row = document.getElementById(`admin-request-${id}`);
if (row) row.remove();
alert(`ステータスを「${status}」に更新しました`);
};
window.onload = () => {
loadAdminRequests();
};
</script>
</body>
</html>
✅ 現在の機能まとめ
このHTMLは、Firebase Firestore の applications
コレクションから申請中の申請だけを表示し、管理者が許可・却下の操作を行える「申請管理ページ」です。
項目 | 内容 |
---|---|
表示対象 | status が「申請中」の申請のみ |
表示情報 | 氏名・申請日・申請種別・理由・操作(許可/却下) |
操作 | ボタンを押すと status を Firestore 上で更新し、画面から該当行を削除 |
ユーザー名取得 | users コレクションから全ユーザー名を取得し、UIDで照合して名前を表示 |
🧠 解説ポイント
1. ユーザーID→名前のマッピング(getUserMap
)
const map = {};
usersSnapshot.forEach(doc => {
map[doc.id] = doc.data().name;
});
- Firestore の
users
コレクションを全件取得して、 uid => 名前
のオブジェクトを作成。
2. 申請データの読み込み(loadAdminRequests
)
const q = query(
collection(db, "applications"),
where("status", "==", "申請中"),
orderBy("timestamp", "desc")
);
- 申請中のものだけを抽出し、申請日降順で表示。
3. ステータス変更(adminUpdateStatus
)
await updateDoc(ref, { status });
- Firestoreの該当申請ドキュメントを更新。
- DOMから該当行を削除。
- アラートで通知。