fix(modal): replace native prompt() with custom modal dialogs
Native browser prompt() is unreliable on mobile browsers and PWAs, often requiring multiple clicks to close. Replace all prompt() calls with custom promptModal() and selectModal() functions that use the existing modal system with proper focus management and animations. Affected pages: shopping (create/rename list), tasks (add subtask), meals (choose shopping list). Fixes #12
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import { api } from '/api.js';
|
||||
import { openModal as openSharedModal, closeModal as closeSharedModal } from '/components/modal.js';
|
||||
import { openModal as openSharedModal, closeModal as closeSharedModal, selectModal } from '/components/modal.js';
|
||||
import { stagger } from '/utils/ux.js';
|
||||
import { t, formatDate } from '/i18n.js';
|
||||
import { esc } from '/utils/html.js';
|
||||
@@ -695,11 +695,10 @@ async function transferMeal(mealId) {
|
||||
let listId = state.lists[0].id;
|
||||
|
||||
if (state.lists.length > 1) {
|
||||
const names = state.lists.map((l, i) => `${i + 1}. ${l.name}`).join('\n');
|
||||
const choice = prompt(`Auf welche Einkaufsliste?\n${names}\nNummer eingeben:`);
|
||||
const n = parseInt(choice, 10);
|
||||
if (!n || n < 1 || n > state.lists.length) return;
|
||||
listId = state.lists[n - 1].id;
|
||||
const options = state.lists.map((l) => ({ value: l.id, label: l.name }));
|
||||
const choice = await selectModal(t('meals.transferToShoppingList'), options);
|
||||
if (choice === null) return;
|
||||
listId = Number(choice);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { api } from '/api.js';
|
||||
import { stagger, vibrate } from '/utils/ux.js';
|
||||
import { t } from '/i18n.js';
|
||||
import { esc } from '/utils/html.js';
|
||||
import { promptModal } from '/components/modal.js';
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Konstanten
|
||||
@@ -571,10 +572,10 @@ function wireTabBar(container) {
|
||||
}
|
||||
|
||||
if (target.dataset.action === 'new-list') {
|
||||
const name = prompt(t('shopping.newListPrompt'));
|
||||
if (!name?.trim()) return;
|
||||
const name = await promptModal(t('shopping.newListPrompt'));
|
||||
if (!name) return;
|
||||
try {
|
||||
const data = await api.post('/shopping', { name: name.trim() });
|
||||
const data = await api.post('/shopping', { name });
|
||||
state.lists.push({ ...data.data, item_total: 0, item_checked: 0 });
|
||||
await switchList(data.data.id, container);
|
||||
} catch (err) {
|
||||
@@ -652,10 +653,10 @@ function wireListContentEvents(container) {
|
||||
|
||||
// ---- Liste umbenennen ----
|
||||
if (action === 'rename-list') {
|
||||
const newName = prompt(t('shopping.renameListPrompt'), state.activeList?.name);
|
||||
if (!newName?.trim() || newName.trim() === state.activeList?.name) return;
|
||||
const newName = await promptModal(t('shopping.renameListPrompt'), state.activeList?.name ?? '');
|
||||
if (!newName || newName === state.activeList?.name) return;
|
||||
try {
|
||||
const data = await api.put(`/shopping/${state.activeListId}`, { name: newName.trim() });
|
||||
const data = await api.put(`/shopping/${state.activeListId}`, { name: newName });
|
||||
const idx = state.lists.findIndex((l) => l.id === state.activeListId);
|
||||
if (idx >= 0) state.lists[idx].name = data.data.name;
|
||||
state.activeList = data.data;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { api } from '/api.js';
|
||||
import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js';
|
||||
import { openModal as openSharedModal, closeModal, wireBlurValidation, btnSuccess, btnError } from '/components/modal.js';
|
||||
import { openModal as openSharedModal, closeModal, wireBlurValidation, btnSuccess, btnError, promptModal } from '/components/modal.js';
|
||||
import { stagger, vibrate } from '/utils/ux.js';
|
||||
import { t, formatDate } from '/i18n.js';
|
||||
import { esc } from '/utils/html.js';
|
||||
@@ -481,10 +481,10 @@ async function handleDeleteTask(id, container) {
|
||||
}
|
||||
|
||||
async function handleAddSubtask(parentId, container) {
|
||||
const title = prompt(t('tasks.subtaskPrompt'));
|
||||
if (!title?.trim()) return;
|
||||
const title = await promptModal(t('tasks.subtaskPrompt'));
|
||||
if (!title) return;
|
||||
try {
|
||||
await api.post('/tasks', { title: title.trim(), parent_task_id: parentId });
|
||||
await api.post('/tasks', { title, parent_task_id: parentId });
|
||||
await loadTasks(container);
|
||||
} catch (err) {
|
||||
window.oikos.showToast(err.message, 'danger');
|
||||
|
||||
Reference in New Issue
Block a user