Refactor monster_catches from table to view and add overwrite option
- Convert monster_catches from table to view for automatic calculation - Add overwrite checkbox to monster import UI - Remove manual INSERT/UPDATE logic for catches (now handled by view) - Simplify API endpoints to query view instead of managing state - Add confirmation dialog for overwrite operation Benefits: - No data duplication - Always accurate catch status based on current steps - Simpler codebase with less state management - Easier to reset steps without orphaned catch records 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -823,6 +823,7 @@ function renderMonsterTimeline(timeline) {
|
||||
// Monster CSV Import
|
||||
async function importMonsters() {
|
||||
const fileInput = document.getElementById('monster-csv-file');
|
||||
const overwriteCheckbox = document.getElementById('monster-overwrite');
|
||||
const messageDiv = document.getElementById('monster-import-message');
|
||||
|
||||
if (!fileInput.files || !fileInput.files[0]) {
|
||||
@@ -830,6 +831,19 @@ async function importMonsters() {
|
||||
return;
|
||||
}
|
||||
|
||||
const overwrite = overwriteCheckbox.checked;
|
||||
|
||||
// Confirm if overwrite is selected
|
||||
if (overwrite) {
|
||||
const confirmed = confirm(
|
||||
'WARNING: This will DELETE all existing monsters and monster catches!\n\n' +
|
||||
'Are you sure you want to proceed?'
|
||||
);
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const file = fileInput.files[0];
|
||||
const reader = new FileReader();
|
||||
|
||||
@@ -846,18 +860,22 @@ async function importMonsters() {
|
||||
return { date, monster_name, monster_description, step_goal, monster_icon };
|
||||
});
|
||||
|
||||
const result = await apiCall('/api/monsters/import', 'POST', { data });
|
||||
const result = await apiCall('/api/monsters/import', 'POST', { data, overwrite });
|
||||
|
||||
showMessage(
|
||||
messageDiv,
|
||||
`Success! Created ${result.monstersCreated} monsters, updated ${result.monstersUpdated}`,
|
||||
'success'
|
||||
);
|
||||
let successMessage;
|
||||
if (overwrite) {
|
||||
successMessage = `Success! Deleted ${result.monstersDeleted} old monsters, created ${result.monstersCreated} new monsters`;
|
||||
} else {
|
||||
successMessage = `Success! Created ${result.monstersCreated} monsters, updated ${result.monstersUpdated}`;
|
||||
}
|
||||
|
||||
showMessage(messageDiv, successMessage, 'success');
|
||||
|
||||
// Reload monsters
|
||||
await loadDailyMonsters();
|
||||
|
||||
fileInput.value = '';
|
||||
overwriteCheckbox.checked = false;
|
||||
} catch (error) {
|
||||
showMessage(messageDiv, `Error: ${error.message}`, 'error');
|
||||
}
|
||||
|
||||
@@ -106,6 +106,12 @@
|
||||
<h3>Admin: Import Monsters</h3>
|
||||
<p class="help-text">Upload CSV with columns: date, monster_name, monster_description, step_goal, monster_icon</p>
|
||||
<input type="file" id="monster-csv-file" accept=".csv">
|
||||
<div style="margin: 10px 0;">
|
||||
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
|
||||
<input type="checkbox" id="monster-overwrite" style="cursor: pointer;">
|
||||
<span style="color: #ff7700;">Overwrite all existing monsters (deletes all current monsters and catches)</span>
|
||||
</label>
|
||||
</div>
|
||||
<button id="import-monsters" class="btn-secondary">Import Monsters</button>
|
||||
<div id="monster-import-message" class="message"></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user