parent
d38ff4469f
commit
5f65fa1f88
|
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
@ -0,0 +1,60 @@
|
||||
<script lang="ts">
|
||||
import {appState, getAvailableGroups, imageSrc, selectedAdds, selections} from "../stores/sel.svelte";
|
||||
import { openModal } from "../stores/modal.svelte";
|
||||
import {proyecto} from "../../data/data_proyecto";
|
||||
import BotonModalMaterial from "./BotonModalMaterial.svelte";
|
||||
|
||||
let { estancia, border } = $props<{ estancia : string, border: boolean | undefined }>();
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- RESUMEN DE ACABADOS -->
|
||||
<div class="mt-6 p-4 bg-blue-50 border-gray-400"
|
||||
class:border={border}
|
||||
class:border-gray-400={border}
|
||||
>
|
||||
|
||||
<!-- OPCIONES -->
|
||||
<h5 class="text-xs text-left font-medium text-gray-800 mb-2 uppercase tracking-wide">Acabados Seleccionados</h5>
|
||||
<div class="space-y-1 mb-4 min-h-[5rem]
|
||||
|
||||
">
|
||||
{#each getAvailableGroups(estancia) as grupo}
|
||||
<div class="flex justify-between text-xs text-gray-800">
|
||||
<span class="text-gray-600">{grupo.nombre}</span>
|
||||
|
||||
{#each grupo.opciones as opcion}
|
||||
{#if selections[estancia]?.[grupo.nombre] === opcion.value}
|
||||
|
||||
{#if proyecto.materiales[opcion.material]?.imagen }
|
||||
<BotonModalMaterial nombre={opcion.nombre} titulo={opcion.nombre} imagen={proyecto.materiales[opcion.material].imagen} />
|
||||
{:else}
|
||||
<span class="font-medium text-gray-900">{opcion.nombre}</span>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- ADDS -->
|
||||
{#if proyecto.estancias[estancia].adds && Object.values(selectedAdds[estancia] ?? {}).some(value => value)}
|
||||
{@const adds = proyecto.estancias[estancia].adds }
|
||||
<div>
|
||||
<h5 class="text-xs font-medium text-left text-gray-800 uppercase tracking-wide">Otras Opciones</h5>
|
||||
<div class="space-y-1 text-right pt-2">
|
||||
{#each Object.entries(adds) as [addKey, add]}
|
||||
{#if selectedAdds[estancia][addKey] }
|
||||
<BotonModalMaterial nombre={add.nombre} titulo={add.nombre} imagen={add.imagen} />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
<script lang="ts">
|
||||
// Eliminamos 'content' ya que se usa <slot/> y solo requerimos 'title'
|
||||
let {title} = $props<{
|
||||
title: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="hidden lg:block">
|
||||
<div class="w-80 bg-white shadow-xl border-l border-gray-200 flex flex-col h-full overflow-hidden">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import {openModal} from "../stores/modal.svelte";
|
||||
|
||||
|
||||
let { nombre, titulo, imagen } = $props <{
|
||||
nombre: string;
|
||||
titulo: string;
|
||||
imagen?: string;
|
||||
}>();
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div role="button"
|
||||
tabindex="0"
|
||||
class="group flex items-center justify-between p-2 rounded-lg bg-cyan-100 hover:bg-cyan-400 cursor-pointer transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-cyan-500 text-gray-900 hover:text-white"
|
||||
onclick={() => { openModal(imagen , titulo ?? 'Sin Nombre'); }}
|
||||
onkeydown={(e) => { if (e.key === 'Enter' || e.key === 'Space') { openModal(imagen ?? 'https://placehold.co/400x400', titulo ?? 'Sin Nombre'); } }}
|
||||
>
|
||||
<span class="text-xs font-medium">{nombre ?? 'Sin Nombre'}</span>
|
||||
|
||||
</div>
|
||||
@ -1,27 +0,0 @@
|
||||
<script lang="ts">
|
||||
|
||||
import {proyecto} from "../../data/data_proyecto";
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="mx-auto text-center bg-amber-50 min-h-[calc(100vh-4.3rem)] bg-cover bg-center">
|
||||
|
||||
<div class="max-w-7xl w-full h-full mx-auto flex">
|
||||
|
||||
<div class="flex-1 p-4 sm:p-6 text-center">
|
||||
|
||||
<!--
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-white mb-6">Exploración del Proyecto</h1>
|
||||
|
||||
<div class="bg-black bg-opacity-40 p-8 rounded-lg h-[calc(100%-4rem)] flex flex-col items-center justify-center">
|
||||
<p class="text-white text-xl font-semibold">
|
||||
Visualizador 3D.
|
||||
</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,49 @@
|
||||
<script lang="ts">
|
||||
import { getModalInfo, closeModal } from '../stores/modal.svelte';
|
||||
|
||||
|
||||
// Depuración para verificar cambios en modalInfo
|
||||
$effect(() => {
|
||||
console.log('modalInfo cambió:', getModalInfo());
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
{#if getModalInfo()}
|
||||
<div
|
||||
class="fixed inset-0 bg-black/80 flex items-center justify-center z-50 transition-opacity duration-300"
|
||||
onclick={closeModal}
|
||||
onkeydown={(e) => { if (e.key === 'Escape') closeModal(); }}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="bg-white p-6 rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-auto transform transition-transform duration-300 scale-100"
|
||||
onclick={(e) => { e.stopPropagation(); closeModal(); }}
|
||||
onkeydown={(e) => { if (e.key === 'Escape') closeModal(); }}
|
||||
role="dialog"
|
||||
tabindex="0"
|
||||
>
|
||||
<h2 class="text-2xl font-bold text-center mb-4 text-gray-800">Opción de {getModalInfo()!.texto}</h2>
|
||||
<img
|
||||
src={getModalInfo()!.imagen}
|
||||
alt="Imagen ampliada"
|
||||
class="w-full max-h-[70vh] object-contain rounded-lg mb-4"
|
||||
/>
|
||||
<button
|
||||
class="w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 focus:ring-4 focus:ring-blue-300 font-medium transition-all duration-200"
|
||||
onclick={closeModal}
|
||||
>
|
||||
Cerrar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.max-h-\[90vh\] {
|
||||
max-height: 90vh;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,63 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { selections, getAvailableGroups, imageSrc } from "../stores/sel.svelte";
|
||||
import { proyecto } from "../../data/data_proyecto";
|
||||
import AcabadosEstancia from "./AcabadosEstancia.svelte";
|
||||
|
||||
// Definir tipos para los datos
|
||||
interface Estancia {
|
||||
nombre: string;
|
||||
grupos?: { nombre: string; opciones: { nombre: string; value: string }[] }[];
|
||||
}
|
||||
|
||||
interface Proyecto {
|
||||
estancias: Record<string, Estancia>;
|
||||
}
|
||||
|
||||
interface Selections {
|
||||
[estancia: string]: { [grupo: string]: string };
|
||||
}
|
||||
|
||||
// Inicializar selections para todas las estancias
|
||||
$effect(() => {
|
||||
for (const estanciaKey of Object.keys(proyecto.estancias)) {
|
||||
if (!selections[estanciaKey]) {
|
||||
selections[estanciaKey] = {};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="mx-auto text-center bg-white min-h-[calc(100vh-4.3rem)] bg-cover bg-center">
|
||||
|
||||
<div class="max-w-7xl w-full h-full mx-auto flex">
|
||||
|
||||
<div class="flex-1 p-4 sm:p-6 text-center">
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
|
||||
{#each Object.entries(proyecto.estancias) as [estanciaKey, estancia]}
|
||||
<div class="bg-white rounded-lg border border-gray-200 hover:border-cyan-500 shadow-sm overflow-hidden" >
|
||||
<h2 class="text-lg font-semibold text-gray-900 p-4">{estancia.nombre}</h2>
|
||||
|
||||
<!-- Imagen de la estancia -->
|
||||
<img
|
||||
src={imageSrc()[estanciaKey] || "https://placehold.co/400x200/cccccc/333333?text=N/A"}
|
||||
alt={`Vista de ${estancia.nombre}`}
|
||||
class="w-full h-48 object-contain"
|
||||
/>
|
||||
<div class="bg-blue-50 h-full">
|
||||
<!-- Resumen de acabados -->
|
||||
<AcabadosEstancia estancia={estanciaKey} border={false} />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,27 @@
|
||||
|
||||
|
||||
// Define la estructura de la información del modal
|
||||
export type ModalInfo = {
|
||||
texto: string;
|
||||
imagen: string;
|
||||
} | null;
|
||||
|
||||
// Estado interno del modal usando $state
|
||||
let modalInfo = $state<ModalInfo>(null);
|
||||
|
||||
// Exportar una función getter para acceder al estado
|
||||
export function getModalInfo() {
|
||||
return modalInfo;
|
||||
}
|
||||
|
||||
// Función para abrir el modal
|
||||
export function openModal(imagen: string, texto: string) {
|
||||
console.log("Abriendo modal con texto:", texto, "e imagen:", imagen);
|
||||
modalInfo = { imagen, texto };
|
||||
}
|
||||
|
||||
// Función para cerrar el modal
|
||||
export function closeModal() {
|
||||
modalInfo = null;
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue