Supervisor update3
This commit is contained in:
BIN
rog/.DS_Store
vendored
BIN
rog/.DS_Store
vendored
Binary file not shown.
@ -60,7 +60,7 @@
|
|||||||
<div class="text-sm text-gray-500">判定</div>
|
<div class="text-sm text-gray-500">判定</div>
|
||||||
<div id="validate" class="font-semibold text-blue-600"></div>
|
<div id="validate" class="font-semibold text-blue-600"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||||
<div class="bg-gray-50 p-4 rounded-lg">
|
<div class="bg-gray-50 p-4 rounded-lg">
|
||||||
@ -86,7 +86,7 @@
|
|||||||
<table class="min-w-full divide-y divide-gray-200">
|
<table class="min-w-full divide-y divide-gray-200">
|
||||||
<thead class="bg-gray-50">
|
<thead class="bg-gray-50">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="w-8"></th> <!-- ハンバーガーアイコン用 -->
|
<th class="w-8"></th> <!-- ハンバーガーアイコン用 -->
|
||||||
<th class="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase">走行順</th>
|
<th class="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase">走行順</th>
|
||||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">規定写真</th>
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">規定写真</th>
|
||||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">撮影写真</th>
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">撮影写真</th>
|
||||||
@ -95,7 +95,7 @@
|
|||||||
<th class="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase">通過審査</th>
|
<th class="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase">通過審査</th>
|
||||||
<th class="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase">買物</th>
|
<th class="px-2 py-3 text-left text-xs font-medium text-gray-500 uppercase">買物</th>
|
||||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">獲得点数</th>
|
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">獲得点数</th>
|
||||||
<th class="w-8"></th> <!-- 削除ボタン用 -->
|
<th class="w-8"></th> <!-- 削除ボタン用 -->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="checkinList" class="bg-white divide-y divide-gray-200">
|
<tbody id="checkinList" class="bg-white divide-y divide-gray-200">
|
||||||
@ -106,9 +106,9 @@
|
|||||||
|
|
||||||
<!-- アクションボタン -->
|
<!-- アクションボタン -->
|
||||||
<div class="mt-6 flex justify-end space-x-4">
|
<div class="mt-6 flex justify-end space-x-4">
|
||||||
<button onclick="showAddCPModal()" class="px-4 py-2 bg-blue-500 text-white rounded">
|
<button onclick="showAddCPModal()" class="px-4 py-2 bg-blue-500 text-white rounded">
|
||||||
新規CP追加
|
新規CP追加
|
||||||
</button>
|
</button>
|
||||||
<button id="saveButton" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
<button id="saveButton" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
|
||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
@ -120,7 +120,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// APIのベースURLを環境に応じて設定
|
// APIのベースURLを環境に応じて設定
|
||||||
const API_BASE_URL = '/api';
|
const API_BASE_URL = '/api';
|
||||||
|
|
||||||
async function login(email, password) {
|
async function login(email, password) {
|
||||||
@ -286,20 +286,22 @@
|
|||||||
const zekkenNumber = zekkenNumberSelect.value
|
const zekkenNumber = zekkenNumberSelect.value
|
||||||
|
|
||||||
// イベントとチェックインデータを取得
|
// イベントとチェックインデータを取得
|
||||||
fetch(`${API_BASE_URL}/get_team_info/${eventCode}`,{
|
fetch(`${API_BASE_URL}/get_team_info/${eventCode}`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`,
|
'Authorization': `Token ${getAuthToken()}`,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(team => {
|
.then(team => {
|
||||||
if (team.self_rogaining) {
|
if (team.self_rogaining) {
|
||||||
// セルフロゲイニングの場合
|
// セルフロゲイニングの場合
|
||||||
fetch(`${API_BASE_URL}/checkins/${zekkenNumber}/${eventCode}/`,
|
fetch(`${API_BASE_URL}/checkins/${zekkenNumber}/${eventCode}/`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`,
|
'Authorization': `Token ${getAuthToken()}`,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
}
|
}
|
||||||
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(checkins => {
|
.then(checkins => {
|
||||||
const startCheckin = checkins.find(c => c.cp_number === -1);
|
const startCheckin = checkins.find(c => c.cp_number === -1);
|
||||||
@ -311,8 +313,8 @@
|
|||||||
updateValidation(timeDiff, maxTime);
|
updateValidation(timeDiff, maxTime);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
} else {
|
} else {
|
||||||
// 通常のロゲイニングの場合
|
// 通常のロゲイニングの場合
|
||||||
const startTime = new Date(event.start_datetime);
|
const startTime = new Date(event.start_datetime);
|
||||||
@ -331,15 +333,11 @@
|
|||||||
|
|
||||||
display.classList.remove('hidden');
|
display.classList.remove('hidden');
|
||||||
input.classList.add('hidden');
|
input.classList.add('hidden');
|
||||||
|
|
||||||
|
|
||||||
// 判定を入れる
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判定の更新を行う補助関数
|
// 判定の更新を行う補助関数
|
||||||
function updateValidation(timeDiff, maxTime) {
|
function updateValidation(timeDiff, maxTime) {
|
||||||
console.log('updateValidation',timeDiff,' > ',maxTime)
|
console.log('updateValidation',timeDiff,' > ',maxTime)
|
||||||
const validateElement = document.getElementById('validate');
|
const validateElement = document.getElementById('validate');
|
||||||
if (validateElement) {
|
if (validateElement) {
|
||||||
if (timeDiff > maxTime) {
|
if (timeDiff > maxTime) {
|
||||||
@ -371,15 +369,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function loadEventCodes() {
|
async function loadEventCodes() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE_URL}/new-events/`,{
|
const response = await fetch(`${API_BASE_URL}/new-events/`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`,
|
'Authorization': `Token ${getAuthToken()}`,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
@ -406,22 +403,22 @@
|
|||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading events:', error);
|
console.error('Error loading events:', error);
|
||||||
// ユーザーにエラーを表示
|
// ユーザーにエラーを表示
|
||||||
const select = document.getElementById('eventCode');
|
const select = document.getElementById('eventCode');
|
||||||
select.innerHTML = '<option value="">エラー: イベントの読み込みに失敗しました</option>';
|
select.innerHTML = '<option value="">エラー: イベントの読み込みに失敗しました</option>';
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ゼッケン番号をロードする
|
// ゼッケン番号をロードする
|
||||||
function loadZekkenNumbers(eventCode) {
|
function loadZekkenNumbers(eventCode) {
|
||||||
// APIからゼッケン番号を取得して選択肢を設定
|
// APIからゼッケン番号を取得して選択肢を設定
|
||||||
fetch(`${API_BASE_URL}/zekken_numbers/${eventCode}`,{
|
fetch(`${API_BASE_URL}/zekken_numbers/${eventCode}`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
})
|
}
|
||||||
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const select = document.getElementById('zekkenNumber');
|
const select = document.getElementById('zekkenNumber');
|
||||||
@ -433,29 +430,27 @@
|
|||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
|
|
||||||
});
|
}
|
||||||
|
|
||||||
|
|
||||||
// チームデータのロード
|
// チームデータのロード
|
||||||
async function loadTeamData(zekkenNumber,event_code) {
|
async function loadTeamData(zekkenNumber,event_code) {
|
||||||
try {
|
try {
|
||||||
const [teamResponse, checkinsResponse] = await Promise.all([
|
const [teamResponse, checkinsResponse] = await Promise.all([
|
||||||
fetch(`${API_BASE_URL}/team_info/${zekkenNumber}/`, {
|
fetch(`${API_BASE_URL}/team_info/${zekkenNumber}/`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error)),
|
||||||
;
|
fetch(`${API_BASE_URL}/checkins/${zekkenNumber}/${event_code}/`, {
|
||||||
fetch(`${API_BASE_URL}/checkins/${zekkenNumber}/${event_code}/`, {
|
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error))
|
||||||
;
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 各レスポンスのステータスを個別にチェック
|
// 各レスポンスのステータスを個別にチェック
|
||||||
@ -558,7 +553,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
updatePathOrders();
|
updatePathOrders();
|
||||||
|
|
||||||
// 合計ポイントの更新
|
// 合計ポイントの更新
|
||||||
document.getElementById('totalPoints').textContent = totalPoints;
|
document.getElementById('totalPoints').textContent = totalPoints;
|
||||||
@ -704,8 +699,8 @@
|
|||||||
`;
|
`;
|
||||||
tbody.appendChild(tr);
|
tbody.appendChild(tr);
|
||||||
});
|
});
|
||||||
updatePathOrders();
|
updatePathOrders();
|
||||||
calculatePoints(); // 総合ポイントの計算
|
calculatePoints(); // 総合ポイントの計算
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -718,12 +713,11 @@
|
|||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE_URL}/checkins/${id}`, {
|
const response = await fetch(`${API_BASE_URL}/checkins/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const row = document.querySelector(`tr[data-id="${id}"]`);
|
const row = document.querySelector(`tr[data-id="${id}"]`);
|
||||||
@ -742,11 +736,11 @@
|
|||||||
function calculatePointsForCheckin(checkin) {
|
function calculatePointsForCheckin(checkin) {
|
||||||
let points = 0;
|
let points = 0;
|
||||||
if (checkin.validate_location) {
|
if (checkin.validate_location) {
|
||||||
if(checkin.buy_flag){
|
if(checkin.buy_flag){
|
||||||
points += Number(checkin.buy_point) || 0;
|
points += Number(checkin.buy_point) || 0;
|
||||||
}else{
|
}else{
|
||||||
points += Number(checkin.checkin_point) || 0;
|
points += Number(checkin.checkin_point) || 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
@ -758,19 +752,19 @@
|
|||||||
const pointCell = tr.querySelector('.point-value');
|
const pointCell = tr.querySelector('.point-value');
|
||||||
const cpNumber = tr.dataset.cpNumber;
|
const cpNumber = tr.dataset.cpNumber;
|
||||||
|
|
||||||
fetch(`${API_BASE_URL}/location/${cpNumber}/`,
|
fetch(`${API_BASE_URL}/location/${cpNumber}/`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(location => {
|
.then(location => {
|
||||||
const points = checkbox.checked ? location.checkin_point : 0;
|
const points = checkbox.checked ? location.checkin_point : 0;
|
||||||
pointCell.textContent = points;
|
pointCell.textContent = points;
|
||||||
calculatePoints(); // 総合ポイントの計算
|
calculatePoints(); // 総合ポイントの計算
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 審査チェックボックス更新関数
|
// 審査チェックボックス更新関数
|
||||||
@ -785,11 +779,11 @@
|
|||||||
points: 0
|
points: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(`${API_BASE_URL}/location/${cpNumber}/`,
|
fetch(`${API_BASE_URL}/location/${cpNumber}/`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(location => {
|
.then(location => {
|
||||||
if (checkin.validate_location) {
|
if (checkin.validate_location) {
|
||||||
@ -811,8 +805,8 @@
|
|||||||
// APIに更新を送信
|
// APIに更新を送信
|
||||||
// updateCheckinOnServer(cpNumber, checkin);
|
// updateCheckinOnServer(cpNumber, checkin);
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 買い物チェックボックス更新関数
|
// 買い物チェックボックス更新関数
|
||||||
@ -821,19 +815,18 @@
|
|||||||
const pointCell = tr.querySelector('.point-value');
|
const pointCell = tr.querySelector('.point-value');
|
||||||
const cpNumber = tr.dataset.cpNumber;
|
const cpNumber = tr.dataset.cpNumber;
|
||||||
|
|
||||||
fetch(`${API_BASE_URL}/location/${cpNumber}/`,
|
fetch(`${API_BASE_URL}/location/${cpNumber}/`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(location => {
|
.then(location => {
|
||||||
const points = checkbox.checked ? location.buy_point : 0;
|
const points = checkbox.checked ? location.buy_point : 0;
|
||||||
pointCell.textContent = points;
|
pointCell.textContent = points;
|
||||||
calculatePoints(); // 総合ポイントの計算
|
calculatePoints(); // 総合ポイントの計算
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 買い物チェックボックス更新関数
|
// 買い物チェックボックス更新関数
|
||||||
@ -848,11 +841,11 @@
|
|||||||
points: 0
|
points: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(`${API_BASE_URL}/location/${cpNumber}/`,
|
fetch(`${API_BASE_URL}/location/${cpNumber}/`,{
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(location => {
|
.then(location => {
|
||||||
if (checkin.validate_location) {
|
if (checkin.validate_location) {
|
||||||
@ -867,8 +860,7 @@
|
|||||||
pointCell.textContent = checkin.points;
|
pointCell.textContent = checkin.points;
|
||||||
calculatePoints(); // 総合ポイントの計算
|
calculatePoints(); // 総合ポイントの計算
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 画像拡大表示用のモーダル関数
|
// 画像拡大表示用のモーダル関数
|
||||||
@ -942,8 +934,7 @@
|
|||||||
loadTeamData(currentZekkenNumber,eventCode); // チームデータのロード
|
loadTeamData(currentZekkenNumber,eventCode); // チームデータのロード
|
||||||
closeModal();
|
closeModal();
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
@ -958,13 +949,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 総合ポイントの計算
|
// 総合ポイントの計算
|
||||||
function calculatePoints() {
|
function calculatePoints() {
|
||||||
const rows = Array.from(document.getElementById('checkinList').children);
|
const rows = Array.from(document.getElementById('checkinList').children);
|
||||||
let totalPoints = 0; // チェックインポイントの合計をクリア
|
let totalPoints = 0; // チェックインポイントの合計をクリア
|
||||||
let buyPoints = 0; // 買い物ポイントの合計をクリア
|
let buyPoints = 0; // 買い物ポイントの合計をクリア
|
||||||
|
|
||||||
// 各行のチェックインポイント及び買い物ポイントを合算
|
// 各行のチェックインポイント及び買い物ポイントを合算
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
const points = parseInt(row.children[4].textContent);
|
const points = parseInt(row.children[4].textContent);
|
||||||
if (!isNaN(points)) {
|
if (!isNaN(points)) {
|
||||||
@ -975,13 +966,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 遅刻ポイントの計算=ゴール時刻がEventのゴール時刻を超えていたら1分につき-50点を加算する。
|
// 遅刻ポイントの計算=ゴール時刻がEventのゴール時刻を超えていたら1分につき-50点を加算する。
|
||||||
const latePoints = parseInt(document.getElementById('latePoints').textContent) || 0;
|
const latePoints = parseInt(document.getElementById('latePoints').textContent) || 0;
|
||||||
|
|
||||||
// 総合得点を計算
|
// 総合得点を計算
|
||||||
const finalPoints = totalPoints + buyPoints - latePoints;
|
const finalPoints = totalPoints + buyPoints - latePoints;
|
||||||
|
|
||||||
// 判定を更新。順位を表示、ゴール時刻を15分経過したら失格
|
// 判定を更新。順位を表示、ゴール時刻を15分経過したら失格
|
||||||
|
|
||||||
document.getElementById('totalPoints').textContent = totalPoints;
|
document.getElementById('totalPoints').textContent = totalPoints;
|
||||||
document.getElementById('buyPoints').textContent = buyPoints;
|
document.getElementById('buyPoints').textContent = buyPoints;
|
||||||
@ -1007,15 +998,15 @@
|
|||||||
'Authorization': `Token ${getAuthToken()}`
|
'Authorization': `Token ${getAuthToken()}`
|
||||||
},
|
},
|
||||||
body: JSON.stringify(updates)
|
body: JSON.stringify(updates)
|
||||||
}).then(response => {
|
})
|
||||||
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
alert('保存しました');
|
alert('保存しました');
|
||||||
} else {
|
} else {
|
||||||
alert('保存に失敗しました');
|
alert('保存に失敗しました');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// エラーハンドリング関数
|
// エラーハンドリング関数
|
||||||
|
|||||||
Reference in New Issue
Block a user