feat: Add confirmation modal for item actions and enhance user feedback with toast notifications in pedidos management.
This commit is contained in:
133
apps/web/src/lib/components/ConfirmationModal.svelte
Normal file
133
apps/web/src/lib/components/ConfirmationModal.svelte
Normal 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>
|
||||
Reference in New Issue
Block a user