diff --git a/src/App.svelte b/src/App.svelte index 050153c..ad1f37f 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -7,9 +7,13 @@ import VwSelection from "./lib/views/VwSelection.svelte"; import { fade } from 'svelte/transition'; import VwGallery from "./lib/views/VwGallery.svelte"; + import {appState} from "./lib/data/AppState.svelte"; - + function handleViewClick(viewId: string) { + appState.setView(viewId); + navegationState.activePage = 'cfg'; // Navegar al configurador + } @@ -27,7 +31,7 @@ {#if navegationState.activePage === 'cfg'} {:else if navegationState.activePage === 'sel'} - + {:else if navegationState.activePage === 'gal'} {:else} diff --git a/src/lib/cmps/BtDownload.svelte b/src/lib/cmps/BtDownload.svelte index 4a6ff5a..14cfc7b 100644 --- a/src/lib/cmps/BtDownload.svelte +++ b/src/lib/cmps/BtDownload.svelte @@ -1,14 +1,56 @@ + \ No newline at end of file diff --git a/src/lib/cmps/NvMain.svelte b/src/lib/cmps/NvMain.svelte index ef27aa2..a3e779f 100644 --- a/src/lib/cmps/NvMain.svelte +++ b/src/lib/cmps/NvMain.svelte @@ -1,9 +1,10 @@ @@ -86,36 +103,35 @@ import BtDownload from "./BtDownload.svelte"; - -
- - + onclick={toggleMobileMenu} + aria-expanded={mobileMenuOpen} + aria-label={mobileMenuOpen ? "Cerrar menú" : "Abrir menú"}> + {#if !mobileMenuOpen} + + + + + {:else} + + + + + {/if} + + - {#if mobileMenuOpen}
+ import { fade, scale } from 'svelte/transition'; + import type {DownloadState} from "../data/DownloadTypes"; + import {cubicOut} from "svelte/easing"; + + let { + downloadState, + isVisible , + message, + logoProject, + logoCompany, + text, + } = $props< { + downloadState: DownloadState; + isVisible : boolean; + message : string ; + logoProject : string ; + logoCompany? : string ; + text : string + }> (); + + + let stateText = $derived ( + downloadState === 'creating' ? 'Creando documento PDF' : + downloadState === 'downloading' ? 'Descargando documento' : + downloadState === 'success' ? '✅ PDF Generado correctamente' : + '' + ); + + let showSpin = $derived ( + downloadState === 'creating' || downloadState === 'downloading' + ); + + + + + +{#if isVisible} + +
+ +
+ +
+ {#if logoCompany} + logo empresa + {/if} + + logo proyecto + +

+ {text} +

+
+ + + {#if downloadState !== 'error' && downloadState !== 'idle' } + +
+ +
+ {#if showSpin} +
+ {/if} +
+ +
+ {stateText} +
+
+ + {:else} +
+ ❌ Error al generar PDF +
+

{message}

+ {/if} +
+
+{/if} \ No newline at end of file diff --git a/src/lib/cmps/pnView.svelte b/src/lib/cmps/pnView.svelte new file mode 100644 index 0000000..e029bcf --- /dev/null +++ b/src/lib/cmps/pnView.svelte @@ -0,0 +1,170 @@ + + +
e.key === 'Enter' && handleClick()} +> + + +
+ {view.name + + + {#if hasWarnings} +
+ ⚠️ Revisar +
+ {/if} +
+ + +
+

+ {view.name || view.id} +

+
+ + +
+ {#if view.options.length > 0} + {#each view.options as group} + {@const currentOptionId = appState.getCurrentOption(view.id, group.id)} + {@const optionValue = currentOptionId ? appState.getOptionValue(currentOptionId) : null} + {@const requiresConsult = currentOptionId ? appState.requiresConsultation(view.id, group.id, currentOptionId) : { required: false }} + +
+ + {group.name || group.id} + +
+ + {optionValue?.name || currentOptionId || 'No seleccionado'} + + {#if requiresConsult.required} + ⚠️ + {/if} +
+
+ {/each} + {:else} +
+

Sin opciones específicas

+
+ {/if} +
+ + + {#if total > 0} +
+
+
+ Extras: + + {formatearPrecio(total)} + +
+
+
+ {/if} +
+ + \ No newline at end of file diff --git a/src/lib/data/DataConfig.ts b/src/lib/data/DataConfig.ts index 8268253..5b0d1fc 100644 --- a/src/lib/data/DataConfig.ts +++ b/src/lib/data/DataConfig.ts @@ -9,7 +9,7 @@ export const dataConfig : DataConfig = { // sources: directorios de los diferentes elementos: imágenes, textos, etc sources: { // logos: Directorio donde se ubican los logos del proyecto - logos : '', + logos : './img/lg/', // images images : './img/', // imgViewsHi: Directorio donde residen las imágenes de las vistas de @@ -50,6 +50,12 @@ export const dataConfig : DataConfig = { home : 'edificio_openbox.jpeg', }, + logos : { + company : 'logo_ebrosa_living.png', + project : 'logo_openbox.png', + }, + + gallery: [ { img: '1.jpg', thumb:'1.jpg' }, { img: '2.jpg', thumb:'2.jpg' }, @@ -200,7 +206,7 @@ export const dataConfig : DataConfig = { name : 'Muebles altos negros y muebles bajos arena fina', text : '', image : 'muebles/mnaf.jpg', - thumb : './img/mt/mnaf_thumb.png', + thumb : 'mnaf_thumb.png', }, mvaf: { value : 'mvaf', diff --git a/src/lib/data/DataConfigTypes.ts b/src/lib/data/DataConfigTypes.ts index 765703f..80be8df 100644 --- a/src/lib/data/DataConfigTypes.ts +++ b/src/lib/data/DataConfigTypes.ts @@ -87,6 +87,7 @@ export interface DataConfig { texts: Record; images: Record; + logos : Record; gallery: ImageGallery[]; options: { diff --git a/src/lib/data/DownloadTypes.ts b/src/lib/data/DownloadTypes.ts new file mode 100644 index 0000000..8447d15 --- /dev/null +++ b/src/lib/data/DownloadTypes.ts @@ -0,0 +1,3 @@ +// DownloadTypes.ts + +export type DownloadState = 'idle' | 'creating' | 'downloading' | 'success' | 'error' \ No newline at end of file diff --git a/src/lib/views/VwSelection.svelte b/src/lib/views/VwSelection.svelte index bc16b1b..4a292ef 100644 --- a/src/lib/views/VwSelection.svelte +++ b/src/lib/views/VwSelection.svelte @@ -1,7 +1,270 @@ + + +
+
+ + +
+

Resumen de Configuración

+

Revisa y modifica tu selección de acabados

+
+ + +
+
+ + + {#each appState.getAllViews() as view} + + {/each} + + + {#if hasIncidencias} +
+
+
+

+ ⚠️ + Opciones que requieren consulta +

+ + {#each Object.entries(incidencias) as [viewId, listaInc]} +
handleViewClick(viewId)} + onkeydown={(e) => e.key === 'Enter' && handleViewClick(viewId)} + > +

+ {listaInc[0].viewName} + + {listaInc.length} {listaInc.length === 1 ? 'opción' : 'opciones'} + +

+ +
+ {#each listaInc as inc} +
+
+ {inc.groupName}: {inc.optionName} +
+
{inc.mensaje}
+
+ {/each} +
+
+ {/each} +
+
+
+ {/if} + + + {#if totalGeneral > 0} +
+
+ +
+

+ Total Extras +

+
+ +
+ {#each appState.getAllViews() as view} + {@const total = getTotalView(view.id)} + {#if total > 0} +
+ {view.name || view.id} + {formatearPrecio(total)} +
+ {/if} + {/each} +
+ +
+
+ TOTAL + {formatearPrecio(totalGeneral)} +
+
+
+
+ {/if} + +
+
+ + + {#if showGeneralOptions} +
+
+

+ {dataConfig.texts.title_options_general || 'Opciones Generales'} +

+ +
+ {#each Object.entries(dataConfig.options.general) as [key, group]} + {@const currentOptionId = appState.getCurrentOption('general', key)} + {@const optionValue = currentOptionId ? appState.getOptionValue(currentOptionId) : null} + +
+ + {group.name || group.id} + + + {optionValue?.name || currentOptionId || 'No seleccionado'} + + + {#if optionValue?.thumb} + {optionValue.name} { + (e.target as HTMLImageElement).style.display = 'none'; }} + /> + {/if} +
+ {/each} +
+
+
+ {/if} + + +
+
+

+ ℹ️ Las imágenes son orientativas y pueden no corresponder exactamente con el resultado final. + Los acabados están sujetos a disponibilidad. +

+
+
+ +
+
+ + \ No newline at end of file