final stage update bugs
This commit is contained in:
@ -113,6 +113,10 @@ class SumasenExcel:
|
|||||||
|
|
||||||
self.basic = basic
|
self.basic = basic
|
||||||
|
|
||||||
|
self.output_path = basic.get("output_path")
|
||||||
|
if not os.path.exists(self.output_path):
|
||||||
|
os.makedirs(self.output_path, exist_ok=True)
|
||||||
|
|
||||||
logging.info("step-2")
|
logging.info("step-2")
|
||||||
|
|
||||||
# basicセクションから必要なパラメータを取得
|
# basicセクションから必要なパラメータを取得
|
||||||
@ -143,7 +147,7 @@ class SumasenExcel:
|
|||||||
logging.error("sections not found in basic section")
|
logging.error("sections not found in basic section")
|
||||||
|
|
||||||
# 出力ファイルパスを設定
|
# 出力ファイルパスを設定
|
||||||
self.output_filepath = f"{self.docpath}/{doc_file}"
|
self.output_filepath = f"{self.output_path}/{doc_file}"
|
||||||
# 新規のExcelワークブックを作成
|
# 新規のExcelワークブックを作成
|
||||||
self.workbook = openpyxl.Workbook()
|
self.workbook = openpyxl.Workbook()
|
||||||
# デフォルトで作成されるシートを削除
|
# デフォルトで作成されるシートを削除
|
||||||
|
|||||||
Binary file not shown.
@ -4,6 +4,7 @@ doc_file=certificate_[zekken_number].xlsx
|
|||||||
sections=section1
|
sections=section1
|
||||||
maxcol=10
|
maxcol=10
|
||||||
column_width=3,5,16,16,16,16,16,8,8,12,3
|
column_width=3,5,16,16,16,16,16,8,8,12,3
|
||||||
|
output_path=media/reports/[event_code]
|
||||||
|
|
||||||
[section1]
|
[section1]
|
||||||
template_sheet=certificate
|
template_sheet=certificate
|
||||||
|
|||||||
@ -134,8 +134,7 @@ FROM
|
|||||||
AND CAST(e.zekken_number AS TEXT) = cs.zekken_number
|
AND CAST(e.zekken_number AS TEXT) = cs.zekken_number
|
||||||
LEFT JOIN v_category_rankings cr ON e.id = cr.id
|
LEFT JOIN v_category_rankings cr ON e.id = cr.id
|
||||||
LEFT JOIN rog_member m ON t.id = m.team_id
|
LEFT JOIN rog_member m ON t.id = m.team_id
|
||||||
LEFT JOIN rog_goalimages gi ON ev.event_name = gi.event_code
|
LEFT JOIN rog_goalimages gi ON e.owner_id = gi.user_id
|
||||||
AND CAST(e.zekken_number AS TEXT) = gi.zekken_number
|
|
||||||
|
|
||||||
GROUP BY
|
GROUP BY
|
||||||
e.id, e.zekken_number, e.is_active, e."hasParticipated", e."hasGoaled", e.date,
|
e.id, e.zekken_number, e.is_active, e."hasParticipated", e."hasGoaled", e.date,
|
||||||
@ -176,7 +175,8 @@ SELECT
|
|||||||
g.points
|
g.points
|
||||||
FROM
|
FROM
|
||||||
gps_checkins g
|
gps_checkins g
|
||||||
LEFT JOIN rog_location l ON g.cp_number = l.cp
|
LEFT JOIN rog_location l ON g.cp_number = l.cp
|
||||||
|
AND l."group" LIKE '%' || g.event_code || '%'
|
||||||
ORDER BY
|
ORDER BY
|
||||||
g.event_code,
|
g.event_code,
|
||||||
g.zekken_number,
|
g.zekken_number,
|
||||||
|
|||||||
@ -2561,7 +2561,7 @@ def update_checkins(request):
|
|||||||
checkin.buy_flag = update.get('buy_flag', False)
|
checkin.buy_flag = update.get('buy_flag', False)
|
||||||
checkin.validate_location = update.get('validation', False)
|
checkin.validate_location = update.get('validation', False)
|
||||||
checkin.points = update.get('points', 0)
|
checkin.points = update.get('points', 0)
|
||||||
checkin.update_at = timezone.now()
|
# checkin.update_at = timezone.now() チェックイン時刻は更新しない
|
||||||
checkin.update_user = request.user.email if request.user.is_authenticated else None
|
checkin.update_user = request.user.email if request.user.is_authenticated else None
|
||||||
checkin.save()
|
checkin.save()
|
||||||
logger.info(f"Updated existing checkin result: {checkin}")
|
logger.info(f"Updated existing checkin result: {checkin}")
|
||||||
@ -2583,7 +2583,7 @@ def update_checkins(request):
|
|||||||
validate_location=update.get('validation', False),
|
validate_location=update.get('validation', False),
|
||||||
buy_flag=update.get('buy_flag', False),
|
buy_flag=update.get('buy_flag', False),
|
||||||
points=update.get('points', 0),
|
points=update.get('points', 0),
|
||||||
create_at=timezone.now(),
|
# create_at=timezone.now(), チェックイン時刻は更新しない
|
||||||
update_at=timezone.now(),
|
update_at=timezone.now(),
|
||||||
create_user=request.user.email if request.user.is_authenticated else None,
|
create_user=request.user.email if request.user.is_authenticated else None,
|
||||||
update_user=request.user.email if request.user.is_authenticated else None
|
update_user=request.user.email if request.user.is_authenticated else None
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bg-gray-50 p-4 rounded-lg">
|
<div class="bg-gray-50 p-4 rounded-lg">
|
||||||
<div class="text-sm text-gray-500">ゴール時刻</div>
|
<div class="text-sm text-gray-500">ゴール時刻</div>
|
||||||
<div class="goal-time-container">
|
<div class="goal-time-container">
|
||||||
<span id="goalTimeDisplay" class="goal-time-display cursor-pointer"></span>
|
<span id="goalTimeDisplay" class="goal-time-display cursor-pointer"></span>
|
||||||
<input type="datetime-local" id="goalTimeInput" class="goal-time-input hidden border rounded px-2 py-1"
|
<input type="datetime-local" id="goalTimeInput" class="goal-time-input hidden border rounded px-2 py-1"
|
||||||
onchange="updateGoalTime(this)">
|
onchange="updateGoalTime(this)">
|
||||||
@ -123,7 +123,7 @@
|
|||||||
// APIのベースURLを環境に応じて設定
|
// APIのベースURLを環境に応じて設定
|
||||||
const API_BASE_URL = 'http://rogaining.sumasen.net/api';
|
const API_BASE_URL = 'http://rogaining.sumasen.net/api';
|
||||||
let original_goal_time = '';
|
let original_goal_time = '';
|
||||||
let selected_event_code = '';
|
let selected_event_code = '';
|
||||||
|
|
||||||
// イベントリスナーの設定
|
// イベントリスナーの設定
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
@ -147,7 +147,7 @@
|
|||||||
alert('イベントコードを選択してください');
|
alert('イベントコードを選択してください');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
selected_event_code = eventCode;
|
selected_event_code = eventCode;
|
||||||
loadTeamData(e.target.value, eventCode);
|
loadTeamData(e.target.value, eventCode);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -253,6 +253,16 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const newTime = new Date(input.value);
|
const newTime = new Date(input.value);
|
||||||
|
// inputがnullの場合は棄権処理
|
||||||
|
if (!input) {
|
||||||
|
const validateElement = document.getElementById('validate');
|
||||||
|
display.textContent = '棄権';
|
||||||
|
if (validateElement) {
|
||||||
|
validateElement.textContent = '棄権';
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
display.textContent = newTime.toLocaleString();
|
display.textContent = newTime.toLocaleString();
|
||||||
|
|
||||||
const eventCodeSelect = document.getElementById('eventCode');
|
const eventCodeSelect = document.getElementById('eventCode');
|
||||||
@ -279,23 +289,23 @@
|
|||||||
.then(checkins => {
|
.then(checkins => {
|
||||||
const startCheckin = checkins.find(c => c.cp_number === -1);
|
const startCheckin = checkins.find(c => c.cp_number === -1);
|
||||||
if (startCheckin) {
|
if (startCheckin) {
|
||||||
const startTime = new Date(startCheckin.create_at);
|
const startTime = new Date(startCheckin.create_at);
|
||||||
const timeDiff = (newTime - startTime) / 1000; // 秒単位の差
|
const timeDiff = (newTime - startTime) / 1000; // 秒単位の差
|
||||||
const maxTime = team.duration + 15*60; // 制限時間+15分
|
const maxTime = team.duration + 15*60; // 制限時間+15分
|
||||||
updateValidation(timeDiff, maxTime );
|
updateValidation(timeDiff, maxTime );
|
||||||
const overtime = ((newTime - startTime) / 1000 - team.duration/1000 + 60 ) // 60;
|
const overtime = ((newTime - startTime) / 1000 - team.duration/1000 + 60 ) // 60;
|
||||||
if( overtime>0 ){
|
if( overtime>0 ){
|
||||||
late_point = overtime*(-50);
|
late_point = overtime*(-50);
|
||||||
lateElement = document.getElementById('latePoints');
|
lateElement = document.getElementById('latePoints');
|
||||||
lateElement.textContent = late_point;
|
lateElement.textContent = late_point;
|
||||||
lateElement.classList.add('text-red-600');
|
lateElement.classList.add('text-red-600');
|
||||||
}else{
|
}else{
|
||||||
lateElement = document.getElementById('latePoints');
|
lateElement = document.getElementById('latePoints');
|
||||||
lateElement.textContent = 0;
|
lateElement.textContent = 0;
|
||||||
lateElement.classList.remove('text-red-600');
|
lateElement.classList.remove('text-red-600');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => handleApiError(error));
|
.catch(error => handleApiError(error));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -304,24 +314,25 @@
|
|||||||
const timeDiff = (newTime - startTime) / 1000; // 分単位の差
|
const timeDiff = (newTime - startTime) / 1000; // 分単位の差
|
||||||
const maxTime = team.duration + 15*60; // 制限時間+15分
|
const maxTime = team.duration + 15*60; // 制限時間+15分
|
||||||
|
|
||||||
//console.info('startTime=',startTime,',goalTime=',newTime,',timeDiff=',timeDiff,'duration=',team.duration,',maxTime=',maxTime);
|
//console.info('startTime=',startTime,',goalTime=',newTime,',timeDiff=',timeDiff,'duration=',team.duration,',maxTime=',maxTime);
|
||||||
updateValidation(timeDiff, maxTime );
|
updateValidation(timeDiff, maxTime );
|
||||||
|
|
||||||
// 1秒でも遅刻すると、1分につき-50点
|
// 1秒でも遅刻すると、1分につき-50点
|
||||||
const overtime = ((newTime - startTime) / 1000 - team.duration );
|
const overtime = ((newTime - startTime) / 1000 - team.duration );
|
||||||
if( overtime>0 ){
|
if( overtime>0 ){
|
||||||
//console.info('overtime=',overtime);
|
//console.info('overtime=',overtime);
|
||||||
late_point = Math.ceil(overtime/60)*(-50);
|
late_point = Math.ceil(overtime/60)*(-50);
|
||||||
lateElement = document.getElementById('latePoints');
|
lateElement = document.getElementById('latePoints');
|
||||||
lateElement.textContent = late_point;
|
lateElement.textContent = late_point;
|
||||||
lateElement.classList.add('text-red-600');
|
lateElement.classList.add('text-red-600');
|
||||||
}else{
|
}else{
|
||||||
lateElement = document.getElementById('latePoints');
|
lateElement = document.getElementById('latePoints');
|
||||||
lateElement.textContent = 0;
|
lateElement.textContent = 0;
|
||||||
lateElement.classList.remove('text-red-600');
|
lateElement.classList.remove('text-red-600');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
calculatePoints(); // 総合ポイントの計算
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error updating goal time:', e);
|
console.error('Error updating goal time:', e);
|
||||||
@ -419,7 +430,7 @@
|
|||||||
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}/`),
|
||||||
fetch(`${API_BASE_URL}/checkins/${zekkenNumber}/${event_code}/`),
|
fetch(`${API_BASE_URL}/checkins/${zekkenNumber}/${event_code}/`),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 各レスポンスのステータスを個別にチェック
|
// 各レスポンスのステータスを個別にチェック
|
||||||
@ -434,7 +445,7 @@
|
|||||||
|
|
||||||
// ゴール時刻の表示を更新
|
// ゴール時刻の表示を更新
|
||||||
updateGoalTimeDisplay(teamData.end_datetime);
|
updateGoalTimeDisplay(teamData.end_datetime);
|
||||||
original_goal_time = teamData.end_datetime;
|
original_goal_time = teamData.end_datetime;
|
||||||
|
|
||||||
// イベントコードに対応するイベントを検索
|
// イベントコードに対応するイベントを検索
|
||||||
//const event = eventData.find(e => e.code === document.getElementById('eventCode').value);
|
//const event = eventData.find(e => e.code === document.getElementById('eventCode').value);
|
||||||
@ -453,34 +464,36 @@
|
|||||||
'未ゴール';
|
'未ゴール';
|
||||||
goalTimeDisplay.textContent = goalTime;
|
goalTimeDisplay.textContent = goalTime;
|
||||||
|
|
||||||
console.info('teamData.goal_photo = ',teamData.goal_photo );
|
updateGoalTime(goalTime) // ゴール時刻の表示を更新
|
||||||
|
|
||||||
|
console.info('teamData.goal_photo = ',teamData.goal_photo );
|
||||||
|
|
||||||
if (goalTime === '-') {
|
if (goalTime === '-') {
|
||||||
goalTimeDisplay.classList.add('cursor-pointer');
|
goalTimeDisplay.classList.add('cursor-pointer');
|
||||||
goalTimeDisplay.onclick = () => editGoalTime(goalTimeDisplay);
|
goalTimeDisplay.onclick = () => editGoalTime(goalTimeDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.info("step 0");
|
//console.info("step 0");
|
||||||
// ゴール時計の表示を更新
|
// ゴール時計の表示を更新
|
||||||
const goalTimeElement = document.getElementById('goalTime');
|
const goalTimeElement = document.getElementById('goalTime');
|
||||||
if (teamData.goal_photo) {
|
if (teamData.goal_photo) {
|
||||||
// 画像要素を作成
|
// 画像要素を作成
|
||||||
//console.info("step 1");
|
//console.info("step 1");
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = teamData.goal_photo;
|
img.src = teamData.goal_photo;
|
||||||
img.classList.add('h-32', 'w-auto', 'object-contain', 'cursor-pointer');
|
img.classList.add('h-32', 'w-auto', 'object-contain', 'cursor-pointer');
|
||||||
img.onclick = () => showLargeImage(teamData.goal_photo);
|
img.onclick = () => showLargeImage(teamData.goal_photo);
|
||||||
|
|
||||||
//console.info("step 2");
|
//console.info("step 2");
|
||||||
// 既存の内容をクリアして画像を追加
|
// 既存の内容をクリアして画像を追加
|
||||||
goalTimeElement.innerHTML = '';
|
goalTimeElement.innerHTML = '';
|
||||||
goalTimeElement.appendChild(img);
|
goalTimeElement.appendChild(img);
|
||||||
|
|
||||||
//console.info("Goal photo displayed: ",teamData.goal_photo);
|
//console.info("Goal photo displayed: ",teamData.goal_photo);
|
||||||
} else {
|
} else {
|
||||||
goalTimeElement.textContent = '画像なし';
|
goalTimeElement.textContent = '画像なし';
|
||||||
console.info("No goal photo available");
|
console.info("No goal photo available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// チェックインリストの更新
|
// チェックインリストの更新
|
||||||
@ -493,11 +506,11 @@
|
|||||||
checkinsData.forEach((checkin, index) => {
|
checkinsData.forEach((checkin, index) => {
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
tr.dataset.id = checkin.id;
|
tr.dataset.id = checkin.id;
|
||||||
tr.dataset.local_id = index+1;
|
tr.dataset.local_id = index+1;
|
||||||
tr.dataset.cpNumber = checkin.cp_number;
|
tr.dataset.cpNumber = checkin.cp_number;
|
||||||
tr.dataset.buyPoint = checkin.buy_point;
|
tr.dataset.buyPoint = checkin.buy_point;
|
||||||
tr.dataset.checkinPoint = checkin.checkin_point;
|
tr.dataset.checkinPoint = checkin.checkin_point;
|
||||||
tr.dataset.path_order = index+1;
|
tr.dataset.path_order = index+1;
|
||||||
const bgColor = checkin.buy_point > 0 ? 'bg-blue-100' : '';
|
const bgColor = checkin.buy_point > 0 ? 'bg-blue-100' : '';
|
||||||
|
|
||||||
tr.innerHTML = `
|
tr.innerHTML = `
|
||||||
@ -510,7 +523,11 @@
|
|||||||
`<img src="/media/compressed/${checkin.photos}" class="h-20 w-20 object-cover rounded" onclick="showLargeImage(this.src)">` : ''}
|
`<img src="/media/compressed/${checkin.photos}" class="h-20 w-20 object-cover rounded" onclick="showLargeImage(this.src)">` : ''}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-2 py-3">
|
<td class="px-2 py-3">
|
||||||
${checkin.cp_number===-1 || checkin.image_address===null ? "" : `<img src="${checkin.image_address}" class="h-20 w-20 object-cover rounded" onclick="showLargeImage(this.src)">`}
|
${checkin.cp_number===-1 || checkin.image_address===null ? "" :
|
||||||
|
`<img src="${checkin.image_address}"
|
||||||
|
class="h-20 w-20 object-cover rounded"
|
||||||
|
onclick="showLargeImage(this.src)"
|
||||||
|
onerror="this.parentElement.innerHTML=''">`}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-2 py-3 ${bgColor}">
|
<td class="px-2 py-3 ${bgColor}">
|
||||||
<div class="font-bold">${checkin.sub_loc_id}</div>
|
<div class="font-bold">${checkin.sub_loc_id}</div>
|
||||||
@ -546,7 +563,7 @@
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
});
|
});
|
||||||
updatePathOrders();
|
updatePathOrders();
|
||||||
|
|
||||||
// 合計ポイントの更新
|
// 合計ポイントの更新
|
||||||
//document.getElementById('totalPoints').textContent = totalPoints;
|
//document.getElementById('totalPoints').textContent = totalPoints;
|
||||||
@ -991,37 +1008,39 @@ function applyImageOrientation(imgElement) {
|
|||||||
|
|
||||||
// 総合ポイントの計算
|
// 総合ポイントの計算
|
||||||
function calculatePoints() {
|
function calculatePoints() {
|
||||||
//console.info('calculatePoints');
|
//console.info('calculatePoints');
|
||||||
const rows = Array.from(document.getElementById('checkinList').children);
|
const rows = Array.from(document.getElementById('checkinList').children);
|
||||||
let totalPoints = 0; // チェックインポイントの合計をクリア
|
let totalPoints = 0; // チェックインポイントの合計をクリア
|
||||||
let cpPoints = 0; // チェックインポイントの合計をクリア
|
let cpPoints = 0; // チェックインポイントの合計をクリア
|
||||||
let buyPoints = 0; // 買い物ポイントの合計をクリア
|
let buyPoints = 0; // 買い物ポイントの合計をクリア
|
||||||
|
let latePoints = 0; // 遅刻ポイントの合計をクリア
|
||||||
|
|
||||||
// 各行のチェックインポイント及び買い物ポイントを合算
|
// 各行のチェックインポイント及び買い物ポイントを合算
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
const buybox = row.children[6].querySelector('input[type="checkbox"]');
|
const buybox = row.children[6].querySelector('input[type="checkbox"]');
|
||||||
const checkbox = row.children[7].querySelector('input[type="checkbox"]');
|
const checkbox = row.children[7].querySelector('input[type="checkbox"]');
|
||||||
const point = parseInt(row.children[8].textContent);
|
const point = parseInt(row.children[8].textContent);
|
||||||
if (checkbox) {
|
if (checkbox) {
|
||||||
totalPoints += point;
|
totalPoints += point;
|
||||||
if (buybox && buybox.checked) {
|
if (buybox && buybox.checked) {
|
||||||
buyPoints += point;
|
buyPoints += point;
|
||||||
}else{
|
}else{
|
||||||
cpPoints += point;
|
cpPoints += point;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 遅刻ポイントの計算=ゴール時刻がEventのゴール時刻を超えていたら1分につき-50点を加算する。
|
// 遅刻ポイントの計算=ゴール時刻がEventのゴール時刻を超えていたら1分につき-50点を加算する。
|
||||||
const latePoints = parseInt(document.getElementById('latePoints').textContent) || 0;
|
latePoints = parseInt(document.getElementById('latePoints').textContent) || 0;
|
||||||
// 総合得点を計算
|
// 総合得点を計算
|
||||||
const finalPoints = totalPoints + latePoints;
|
const finalPoints = totalPoints + latePoints;
|
||||||
|
|
||||||
// 判定を更新。順位を表示、ゴール時刻を15分経過したら失格
|
// 判定を更新。順位を表示、ゴール時刻を15分経過したら失格
|
||||||
//console.info('calculatePoints:totalPoints=',cpPoints,',buyPoints=',buyPoints,',finalPoints=',finalPoints);
|
//console.info('calculatePoints:totalPoints=',cpPoints,',buyPoints=',buyPoints,',finalPoints=',finalPoints);
|
||||||
|
|
||||||
document.getElementById('totalPoints').textContent = cpPoints;
|
document.getElementById('totalPoints').textContent = cpPoints;
|
||||||
document.getElementById('buyPoints').textContent = buyPoints;
|
document.getElementById('buyPoints').textContent = buyPoints;
|
||||||
|
document.getElementById('latePoints').textContent = latePoints;
|
||||||
document.getElementById('finalPoints').textContent = finalPoints;
|
document.getElementById('finalPoints').textContent = finalPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1034,17 +1053,17 @@ function applyImageOrientation(imgElement) {
|
|||||||
const zekkenNumber = document.querySelector('#zekkenNumber').value;
|
const zekkenNumber = document.querySelector('#zekkenNumber').value;
|
||||||
const eventCode = document.querySelector('#eventCode').value;
|
const eventCode = document.querySelector('#eventCode').value;
|
||||||
|
|
||||||
const display = document.getElementById('goalTimeDisplay');
|
const display = document.getElementById('goalTimeDisplay');
|
||||||
|
|
||||||
if (!display) {
|
if (!display) {
|
||||||
console.error('Goal time elements not found');
|
console.error('Goal time elements not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let goalTime = display.textContent;
|
let goalTime = display.textContent;
|
||||||
console.info('Goal time = ',goalTime);
|
console.info('Goal time = ',goalTime);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const checkins = getCurrentCheckins(); // 現在の表示データを取得
|
const checkins = getCurrentCheckins(); // 現在の表示データを取得
|
||||||
|
|
||||||
const response = await fetch(`${API_BASE_URL}/update_checkins/`, {
|
const response = await fetch(`${API_BASE_URL}/update_checkins/`, {
|
||||||
|
|||||||
Reference in New Issue
Block a user