feat: Add confirmation modal for item actions and enhance user feedback with toast notifications in pedidos management.

This commit is contained in:
2025-12-09 12:25:05 -03:00
parent 090298659e
commit 881f2fbb8b
4 changed files with 434 additions and 117 deletions

View File

@@ -0,0 +1,133 @@
<script lang="ts">
import { AlertTriangle, X } from 'lucide-svelte';
interface Props {
open: boolean;
title?: string;
message: string;
confirmText?: string;
cancelText?: string;
isDestructive?: boolean;
onConfirm: () => void;
onClose: () => void;
}
let {
open = $bindable(false),
title = 'Confirmar Ação',
message,
confirmText = 'Confirmar',
cancelText = 'Cancelar',
isDestructive = false,
onConfirm,
onClose
}: Props = $props();
// Tenta centralizar, mas se tiver um contexto específico pode ser ajustado
// Por padrão, centralizado.
function getModalStyle() {
return 'position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; max-width: 500px;';
}
function handleClose() {
open = false;
onClose();
}
function handleConfirm() {
open = false;
onConfirm();
}
</script>
{#if open}
<div
class="pointer-events-none fixed inset-0 z-50"
style="animation: fadeIn 0.2s ease-out;"
role="dialog"
aria-modal="true"
aria-labelledby="modal-confirm-title"
>
<!-- Backdrop leve -->
<div
class="pointer-events-auto absolute inset-0 bg-black/20 transition-opacity duration-200"
onclick={handleClose}
aria-hidden="true"
></div>
<!-- Modal Box -->
<div
class="pointer-events-auto absolute z-10 flex w-full max-w-lg flex-col overflow-hidden rounded-2xl bg-white shadow-2xl transition-all duration-300"
style="animation: slideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); {getModalStyle()}"
onclick={(e) => e.stopPropagation()}
>
<!-- Header -->
<div class="flex shrink-0 items-center justify-between border-b border-gray-100 px-6 py-4">
<h2
id="modal-confirm-title"
class="flex items-center gap-2 text-xl font-bold {isDestructive
? 'text-red-600'
: 'text-gray-900'}"
>
{#if isDestructive}
<AlertTriangle class="h-6 w-6" strokeWidth={2.5} />
{/if}
{title}
</h2>
<button
type="button"
class="rounded-full p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-600"
onclick={handleClose}
aria-label="Fechar"
>
<X class="h-5 w-5" />
</button>
</div>
<!-- Content -->
<div class="flex-1 overflow-y-auto px-6 py-6">
<p class="text-base leading-relaxed font-medium text-gray-700">{message}</p>
</div>
<!-- Footer -->
<div class="flex shrink-0 justify-end gap-3 border-t border-gray-100 bg-gray-50 px-6 py-4">
<button
class="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-200"
onclick={handleClose}
>
{cancelText}
</button>
<button
class="rounded-lg px-4 py-2 text-sm font-medium text-white shadow-sm {isDestructive
? 'bg-red-600 hover:bg-red-700 focus:ring-red-500'
: 'bg-blue-600 hover:bg-blue-700 focus:ring-blue-500'}"
onclick={handleConfirm}
>
{confirmText}
</button>
</div>
</div>
</div>
{/if}
<style>
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
</style>