|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 416 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 276 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 9.4 MiB After Width: | Height: | Size: 597 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 842 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 715 KiB |
|
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 674 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,59 @@
|
||||
<script lang="ts">
|
||||
import {formatearPrecio} from "../utils/formaters";
|
||||
import type {Add} from "../../data/data_types";
|
||||
import {showWarning} from "../stores/popup.svelte";
|
||||
|
||||
|
||||
|
||||
let { add, seleccionada, onclick } = $props<{
|
||||
add: Add,
|
||||
seleccionada: boolean,
|
||||
onclick?: (event: Event) => void}>();
|
||||
|
||||
|
||||
function handleClick (event: Event) {
|
||||
console.log('seleccionada ', seleccionada, add.texto);
|
||||
if (!seleccionada && add.texto) {
|
||||
console.log("debe de aparecer el popuip")
|
||||
showWarning(add.texto)
|
||||
}
|
||||
onclick(event);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="group relative p-2 rounded-lg border transition-all duration-200 w-full cursor-pointer
|
||||
{seleccionada
|
||||
? 'border-blue-200 bg-blue-50 ring-1 ring-blue-200'
|
||||
: 'border-gray-200 hover:border-gray-400'
|
||||
}"
|
||||
aria-pressed={seleccionada}
|
||||
onclick={(e) => handleClick(e)}
|
||||
>
|
||||
|
||||
<div class="flex justify-between items-center w-full p-2 rounded-lg group">
|
||||
<!-- Nombre a la izquierda -->
|
||||
<span class="font-medium text-xs text-gray-800 group-hover:text-gray-900 truncate">{add.nombre}</span>
|
||||
<!-- Precio a la derecha -->
|
||||
{#if add.precio}
|
||||
<span class="font-medium text-xs text-gray-800 group-hover:text-gray-900">+{formatearPrecio(add.precio)}</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
{#if seleccionada}
|
||||
<div class="absolute -top-1 -right-1 w-5 h-5 bg-green-600 rounded-full flex items-center justify-center shadow-md">
|
||||
<svg class="w-3 h-3 text-white" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
@ -0,0 +1,51 @@
|
||||
<script lang="ts">
|
||||
import {popupState, hideWarning} from "../stores/popup.svelte";
|
||||
|
||||
const handleClose = () => {
|
||||
hideWarning();
|
||||
};
|
||||
|
||||
const handleKeyClose = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
handleClose();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="fixed inset-0 z-50 flex items-center justify-center p-4 transition-opacity duration-300"
|
||||
style="background-color: rgba(0, 0, 0, 0.5);"
|
||||
class:hidden={!popupState.isVisible}
|
||||
onclick={handleClose}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
onkeydown={handleKeyClose}
|
||||
>
|
||||
<div
|
||||
class="relative max-w-lg w-full p-6 bg-yellow-100 border-l-4 border-yellow-500 rounded-lg shadow-xl"
|
||||
role="alert presentation"
|
||||
onclick={(e) => { e.stopPropagation() }}
|
||||
>
|
||||
<div class="flex items-start">
|
||||
<svg class="h-6 w-6 text-yellow-500 mr-4 mt-1 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.3 16c-.77 1.333.192 3 1.732 3z" />
|
||||
</svg>
|
||||
|
||||
<div class="text-yellow-800">
|
||||
<h3 class="text-lg font-semibold mb-1">Advertencia Importante</h3>
|
||||
<p class="text-sm leading-relaxed">{popupState.message}</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="absolute top-3 right-3 text-yellow-600 hover:text-yellow-800 transition-colors duration-150"
|
||||
aria-label="Cerrar advertencia"
|
||||
onclick={handleClose}
|
||||
>
|
||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
// 1. Define la forma del estado
|
||||
interface PopupState {
|
||||
isVisible: boolean;
|
||||
message: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const popupState = $state<PopupState>({
|
||||
isVisible: false,
|
||||
message: ''
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 3. Define funciones para manipular el estado
|
||||
export const showWarning = (message: string) => {
|
||||
popupState.message = message;
|
||||
popupState.isVisible = true;
|
||||
};
|
||||
|
||||
export const hideWarning = () => {
|
||||
popupState.isVisible = false;
|
||||
};
|
||||
@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
export const formatearPrecio = (precio?: number): string => {
|
||||
if (precio === undefined) return 'No disponible';
|
||||
return new Intl.NumberFormat('es-ES', {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
}).format(precio);
|
||||
};
|
||||