From 06617a985a2e01307ce2176db01d392a928f19b4 Mon Sep 17 00:00:00 2001 From: Carmine Savino Date: Mon, 19 Oct 2026 19:49:44 +0200 Subject: [PATCH] feat: add previous configuration handling for user selections in quotes - Implemented session storage management for the last configuration choices made by the user. - Added functionality to prompt users when changing models to retain their previous selections. - Introduced methods to apply previous choices to the newly loaded model, including finishes, handles, glass types, and options. - Enhanced user experience by ensuring selections are automatically applied where applicable. --- .gitignore | 4 +- CLAUDE.md | 45 +- .../Filament/Resources/FinituraResource.php | 142 ++++ .../FinituraResource/Pages/ManageFiniture.php | 19 + .../Resources/GruppoOpzioniResource.php | 105 +++ .../Pages/ManageGruppiOpzioni.php | 19 + .../Filament/Resources/ModelloResource.php | 59 +- .../FinitureRelationManager.php | 142 ++++ .../OpzioniRelationManager.php | 130 ++++ .../Filament/Resources/OpzioneResource.php | 267 ++++++++ .../OpzioneResource/Pages/ManageOpzioni.php | 19 + .../Resources/RegolaVetroResource.php | 155 +++++ .../Pages/ManageRegoleVetro.php | 19 + .../app/Filament/Resources/VetroResource.php | 126 ++++ .../VetroResource/Pages/ManageVetri.php | 19 + .../Filament/Support/CampiConfiguratore.php | 54 ++ .../Controllers/Api/CarrelloController.php | 51 +- .../Controllers/Api/CatalogoController.php | 67 +- .../Http/Controllers/Api/MediaController.php | 33 + .../Models/Concerns/HaImmaginiCatalogo.php | 31 + backoffice/app/Models/Finitura.php | 99 +++ backoffice/app/Models/GruppoOpzioni.php | 54 ++ backoffice/app/Models/Modello.php | 79 ++- backoffice/app/Models/Opzione.php | 139 ++++ backoffice/app/Models/RegolaVetro.php | 50 ++ backoffice/app/Models/Sistema.php | 21 + backoffice/app/Models/Vetro.php | 58 ++ .../Configuratore/CalcolatorePrezzo.php | 260 +++++++ .../Configuratore/ConfigurazioneModello.php | 148 ++++ .../app/Support/Configuratore/Media.php | 18 + .../app/Support/ConfigurazioneFormatter.php | 10 +- ..._19_170000_create_configuratore_tables.php | 120 ++++ ...0_19_180000_add_lato_to_finiture_table.php | 39 ++ ...000_add_metro_lineare_to_opzioni_table.php | 30 + ..._19_200000_create_gruppi_opzioni_table.php | 46 ++ .../database/seeders/CatalogoSeeder.php | 2 + .../database/seeders/ConfiguratoreSeeder.php | 168 +++++ .../database/seeders/DatabaseSeeder.php | 2 +- .../database/seeders/NuoveOpzioniSeeder.php | 92 +++ .../database/seeders/ProfiliExtraSeeder.php | 99 +++ .../pvc/finiture/anteprime/10_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/11_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/12_anteprima.jpg | Bin 0 -> 2207 bytes .../pvc/finiture/anteprime/13_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/14_anteprima.jpg | Bin 0 -> 66704 bytes .../pvc/finiture/anteprime/15_anteprima.jpg | Bin 0 -> 67326 bytes .../pvc/finiture/anteprime/16_anteprima.jpg | Bin 0 -> 87297 bytes .../pvc/finiture/anteprime/17_anteprima.jpg | Bin 0 -> 79277 bytes .../pvc/finiture/anteprime/18_anteprima.jpg | Bin 0 -> 74767 bytes .../pvc/finiture/anteprime/19_anteprima.jpg | Bin 0 -> 94409 bytes .../pvc/finiture/anteprime/1_anteprima.jpg | Bin 0 -> 2206 bytes .../pvc/finiture/anteprime/20_anteprima.jpg | Bin 0 -> 81609 bytes .../pvc/finiture/anteprime/21_anteprima.jpg | Bin 0 -> 58315 bytes .../pvc/finiture/anteprime/22_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/23_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/24_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/25_anteprima.jpg | Bin 0 -> 41103 bytes .../pvc/finiture/anteprime/26_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/27_anteprima.jpg | Bin 0 -> 67569 bytes .../pvc/finiture/anteprime/28_anteprima.jpg | Bin 0 -> 87712 bytes .../pvc/finiture/anteprime/29_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/2_anteprima.jpg | Bin 0 -> 119475 bytes .../pvc/finiture/anteprime/30_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/31_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/32_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/33_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/34_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/35_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/36_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/37_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/38_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/39_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/3_anteprima.jpg | Bin 0 -> 34774 bytes .../pvc/finiture/anteprime/40_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/41_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/42_anteprima.jpg | Bin 0 -> 64848 bytes .../pvc/finiture/anteprime/43_anteprima.jpg | Bin 0 -> 88544 bytes .../pvc/finiture/anteprime/44_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/45_anteprima.jpg | Bin 0 -> 2208 bytes .../pvc/finiture/anteprime/46_anteprima.jpg | Bin 0 -> 2208 bytes .../pvc/finiture/anteprime/47_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/48_anteprima.jpg | Bin 0 -> 2209 bytes .../pvc/finiture/anteprime/4_anteprima.jpg | Bin 0 -> 72636 bytes .../pvc/finiture/anteprime/5_anteprima.jpg | Bin 0 -> 68032 bytes .../pvc/finiture/anteprime/6_anteprima.jpg | Bin 0 -> 117481 bytes .../pvc/finiture/anteprime/7_anteprima.jpg | Bin 0 -> 2210 bytes .../pvc/finiture/anteprime/8_anteprima.jpg | Bin 0 -> 83838 bytes .../pvc/finiture/anteprime/9_anteprima.jpg | Bin 0 -> 45343 bytes .../pvc/finiture/texture/14/14_A.jpg | Bin 0 -> 2775705 bytes .../pvc/finiture/texture/15/15_A.jpg | Bin 0 -> 446755 bytes .../pvc/finiture/texture/16/16_A.jpg | Bin 0 -> 1891308 bytes .../pvc/finiture/texture/16/16_A_bump.jpg | Bin 0 -> 930538 bytes .../pvc/finiture/texture/17/17_A.jpg | Bin 0 -> 875422 bytes .../pvc/finiture/texture/18/18_A.jpg | Bin 0 -> 813465 bytes .../pvc/finiture/texture/19/19_A.jpg | Bin 0 -> 749803 bytes .../pvc/finiture/texture/2/2_A.jpg | Bin 0 -> 489017 bytes .../pvc/finiture/texture/20/20_A.jpg | Bin 0 -> 638070 bytes .../pvc/finiture/texture/21/21_A.jpg | Bin 0 -> 738540 bytes .../pvc/finiture/texture/25/25_A.jpg | Bin 0 -> 447196 bytes .../pvc/finiture/texture/27/27_A.jpg | Bin 0 -> 777387 bytes .../pvc/finiture/texture/28/28_A.jpg | Bin 0 -> 811101 bytes .../pvc/finiture/texture/3/3_A.jpg | Bin 0 -> 754541 bytes .../pvc/finiture/texture/4/4_A.jpg | Bin 0 -> 691380 bytes .../pvc/finiture/texture/42/42_A.jpg | Bin 0 -> 769254 bytes .../pvc/finiture/texture/43/43_A.jpg | Bin 0 -> 888053 bytes .../pvc/finiture/texture/5/5_A.jpg | Bin 0 -> 837880 bytes .../pvc/finiture/texture/6/6_A.jpg | Bin 0 -> 829184 bytes .../pvc/finiture/texture/8/8_A.jpg | Bin 0 -> 872701 bytes .../pvc/finiture/texture/9/9_A.jpg | Bin 0 -> 900392 bytes .../maniglie/maniglia_argento_anteprima.jpg | Bin 0 -> 18819 bytes .../maniglie/maniglia_bianco_anteprima.jpg | Bin 0 -> 20488 bytes .../pvc/maniglie/maniglia_nero_anteprima.jpg | Bin 0 -> 16697 bytes .../pvc/maniglie/maniglia_oro_anteprima.jpg | Bin 0 -> 28117 bytes .../apertura/finestra_1_anta/destra.jpg | Bin 0 -> 21080 bytes .../apertura/finestra_1_anta/sinistra.jpg | Bin 0 -> 20540 bytes .../apertura/finestra_2_ante/destra.jpg | Bin 0 -> 30246 bytes .../apertura/finestra_2_ante/sinistra.jpg | Bin 0 -> 31144 bytes .../apertura/finestra_3_ante/destra.jpg | Bin 0 -> 39062 bytes .../apertura/finestra_3_ante/sinistra.jpg | Bin 0 -> 39754 bytes .../opzioni/apertura/porta_1_anta/destra.jpg | Bin 0 -> 16075 bytes .../apertura/porta_1_anta/sinistra.jpg | Bin 0 -> 16852 bytes .../porta_1_anta_antipanico/destra.jpg | Bin 0 -> 14779 bytes .../porta_1_anta_antipanico/sinistra.jpg | Bin 0 -> 15132 bytes .../opzioni/apertura/porta_2_ante/destra.jpg | Bin 0 -> 24589 bytes .../apertura/porta_2_ante/sinistra.jpg | Bin 0 -> 25010 bytes .../porta_2_ante_antipanico/destra.jpg | Bin 0 -> 23832 bytes .../porta_2_ante_antipanico/sinistra.jpg | Bin 0 -> 24580 bytes .../apertura/portafinestra_1_anta/destra.jpg | Bin 0 -> 17579 bytes .../portafinestra_1_anta/sinistra.jpg | Bin 0 -> 17584 bytes .../apertura/portafinestra_2_ante/destra.jpg | Bin 0 -> 26606 bytes .../portafinestra_2_ante/sinistra.jpg | Bin 0 -> 26576 bytes .../apertura/portafinestra_3_ante/destra.jpg | Bin 0 -> 29037 bytes .../portafinestra_3_ante/sinistra.jpg | Bin 0 -> 29734 bytes .../apertura/scorrevole_hst_1_anta/destra.jpg | Bin 0 -> 21329 bytes .../scorrevole_hst_1_anta/sinistra.jpg | Bin 0 -> 22143 bytes .../apertura/scorrevole_hst_2_ante/destra.jpg | Bin 0 -> 22686 bytes .../scorrevole_hst_2_ante/sinistra.jpg | Bin 0 -> 23253 bytes .../apertura/scorrevole_hst_4_ante/destra.jpg | Bin 0 -> 47591 bytes .../scorrevole_hst_4_ante/sinistra.jpg | Bin 0 -> 47591 bytes .../apertura/scorrevole_sf_2_ante/destra.jpg | Bin 0 -> 21194 bytes .../scorrevole_sf_2_ante/sinistra.jpg | Bin 0 -> 21022 bytes .../apertura/scorrevole_sf_3_ante/destra.jpg | Bin 0 -> 46394 bytes .../scorrevole_sf_3_ante/sinistra.jpg | Bin 0 -> 46394 bytes .../apertura/scorrevole_sf_4_ante/destra.jpg | Bin 0 -> 47591 bytes .../scorrevole_sf_4_ante/sinistra.jpg | Bin 0 -> 47591 bytes .../traslante_scorrevole_1_anta/destra.jpg | Bin 0 -> 26146 bytes .../traslante_scorrevole_1_anta/sinistra.jpg | Bin 0 -> 25508 bytes .../traslante_scorrevole_1_anta_f/destra.jpg | Bin 0 -> 46048 bytes .../sinistra.jpg | Bin 0 -> 45886 bytes .../pvc/opzioni/profili_extra/406200.jpg | Bin 0 -> 5567 bytes .../pvc/opzioni/profili_extra/50811.jpg | Bin 0 -> 9466 bytes .../pvc/opzioni/profili_extra/50811_50801.jpg | Bin 0 -> 10897 bytes .../pvc/opzioni/profili_extra/9320.jpg | Bin 0 -> 18271 bytes .../pvc/opzioni/profili_extra/NP8300.jpg | Bin 0 -> 8177 bytes .../pvc/opzioni/profili_extra/NP8500.jpg | Bin 0 -> 9513 bytes .../pvc/opzioni/profili_extra/NP8700.jpg | Bin 0 -> 10596 bytes .../profili_extra/coprifili_piatti.jpg | Bin 0 -> 3077 bytes .../profili_extra/coprifili_scatolati.jpg | Bin 0 -> 3330 bytes .../pvc/opzioni/telaio/telaio_l.jpg | Bin 0 -> 24559 bytes .../pvc/opzioni/telaio/telaio_z_35.jpg | Bin 0 -> 13530 bytes .../pvc/opzioni/telaio/telaio_z_60.jpg | Bin 0 -> 20915 bytes .../pvc/vetri/icone/01_acustico_base.jpg | Bin 0 -> 23824 bytes .../pvc/vetri/icone/02_standard_satinato.jpg | Bin 0 -> 72848 bytes .../vetri/icone/03_standard_trasparente.jpg | Bin 0 -> 23824 bytes .../pvc/vetri/icone/04_acustico_satinato.jpg | Bin 0 -> 72848 bytes .../vetri/icone/05_vetro_max_trasparente.jpg | Bin 0 -> 14922 bytes .../pvc/vetri/icone/06_vetro_max_satinato.jpg | Bin 0 -> 38995 bytes .../pvc/vetri/icone/07_no_vetro.jpg | Bin 0 -> 19217 bytes .../vetri/icone/08_pannello_pvc_bianco.jpg | Bin 0 -> 21326 bytes .../vetri/icone/09_pannello_pvc_rivestito.jpg | Bin 0 -> 21326 bytes .../10_riflettente_no_termico_trasparente.jpg | Bin 0 -> 13086 bytes .../vetri/icone/11_riflettente_termico.jpg | Bin 0 -> 13471 bytes .../12_riflettente_no_termico_bronzo.jpg | Bin 0 -> 27689 bytes .../vetri/icone/13_triplo_base_satinato.jpg | Bin 0 -> 38747 bytes .../icone/14_triplo_base_trasparente.jpg | Bin 0 -> 36618 bytes .../pvc/vetri/texture/vetro_satinato.jpg | Bin 0 -> 376291 bytes .../seeders/data/configuratore_pvc.php | 119 ++++ .../data/configuratore_pvc_catalogo.php | 647 ++++++++++++++++++ .../data/icone/pvc/scorrevole_hst_4_ante.jpg | Bin 0 -> 64404 bytes .../data/icone/pvc/scorrevole_sf_3_ante.jpg | Bin 0 -> 46394 bytes .../data/icone/pvc/scorrevole_sf_4_ante.jpg | Bin 0 -> 47591 bytes .../pvc/traslante_scorrevole_1_anta_f.jpg | Bin 0 -> 45886 bytes backoffice/routes/api.php | 6 + .../tests/Feature/CatalogoAdminTest.php | 32 + backoffice/tests/Feature/CatalogoApiTest.php | 15 +- .../tests/Feature/ConfiguratoreAdminTest.php | 197 ++++++ .../tests/Feature/ConfiguratorePrezzoTest.php | 426 ++++++++++++ reference/Regole_Profili Extra.xls | Bin 0 -> 34304 bytes src/assets/_menu.html | 22 +- src/assets/style.css | 93 ++- src/index.html | 20 + src/js/app.js | 21 +- src/js/configurator.js | 199 ++---- src/js/configurazione_precedente.js | 118 ++++ src/js/menu_builder.js | 122 ++-- src/js/price_calculator.js | 147 +--- src/js/starter.js | 68 +- 197 files changed, 4892 insertions(+), 400 deletions(-) create mode 100644 backoffice/app/Filament/Resources/FinituraResource.php create mode 100644 backoffice/app/Filament/Resources/FinituraResource/Pages/ManageFiniture.php create mode 100644 backoffice/app/Filament/Resources/GruppoOpzioniResource.php create mode 100644 backoffice/app/Filament/Resources/GruppoOpzioniResource/Pages/ManageGruppiOpzioni.php create mode 100644 backoffice/app/Filament/Resources/ModelloResource/RelationManagers/FinitureRelationManager.php create mode 100644 backoffice/app/Filament/Resources/ModelloResource/RelationManagers/OpzioniRelationManager.php create mode 100644 backoffice/app/Filament/Resources/OpzioneResource.php create mode 100644 backoffice/app/Filament/Resources/OpzioneResource/Pages/ManageOpzioni.php create mode 100644 backoffice/app/Filament/Resources/RegolaVetroResource.php create mode 100644 backoffice/app/Filament/Resources/RegolaVetroResource/Pages/ManageRegoleVetro.php create mode 100644 backoffice/app/Filament/Resources/VetroResource.php create mode 100644 backoffice/app/Filament/Resources/VetroResource/Pages/ManageVetri.php create mode 100644 backoffice/app/Filament/Support/CampiConfiguratore.php create mode 100644 backoffice/app/Http/Controllers/Api/MediaController.php create mode 100644 backoffice/app/Models/Concerns/HaImmaginiCatalogo.php create mode 100644 backoffice/app/Models/Finitura.php create mode 100644 backoffice/app/Models/GruppoOpzioni.php create mode 100644 backoffice/app/Models/Opzione.php create mode 100644 backoffice/app/Models/RegolaVetro.php create mode 100644 backoffice/app/Models/Vetro.php create mode 100644 backoffice/app/Support/Configuratore/CalcolatorePrezzo.php create mode 100644 backoffice/app/Support/Configuratore/ConfigurazioneModello.php create mode 100644 backoffice/app/Support/Configuratore/Media.php create mode 100644 backoffice/database/migrations/2026_10_19_170000_create_configuratore_tables.php create mode 100644 backoffice/database/migrations/2026_10_19_180000_add_lato_to_finiture_table.php create mode 100644 backoffice/database/migrations/2026_10_19_190000_add_metro_lineare_to_opzioni_table.php create mode 100644 backoffice/database/migrations/2026_10_19_200000_create_gruppi_opzioni_table.php create mode 100644 backoffice/database/seeders/ConfiguratoreSeeder.php create mode 100644 backoffice/database/seeders/NuoveOpzioniSeeder.php create mode 100644 backoffice/database/seeders/ProfiliExtraSeeder.php create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/10_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/11_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/12_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/13_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/14_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/15_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/16_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/17_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/18_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/19_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/1_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/20_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/21_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/22_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/23_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/24_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/25_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/26_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/27_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/28_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/29_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/2_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/30_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/31_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/32_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/33_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/34_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/35_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/36_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/37_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/38_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/39_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/3_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/40_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/41_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/42_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/43_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/44_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/45_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/46_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/47_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/48_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/4_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/5_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/6_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/7_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/8_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/anteprime/9_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/14/14_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/15/15_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/16/16_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/16/16_A_bump.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/17/17_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/18/18_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/19/19_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/2/2_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/20/20_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/21/21_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/25/25_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/27/27_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/28/28_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/3/3_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/4/4_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/42/42_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/43/43_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/5/5_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/6/6_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/8/8_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/finiture/texture/9/9_A.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/maniglie/maniglia_argento_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/maniglie/maniglia_bianco_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/maniglie/maniglia_nero_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/maniglie/maniglia_oro_anteprima.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/finestra_1_anta/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/finestra_1_anta/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/finestra_2_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/finestra_2_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/finestra_3_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/finestra_3_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_1_anta/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_1_anta/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_1_anta_antipanico/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_1_anta_antipanico/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_2_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_2_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_2_ante_antipanico/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/porta_2_ante_antipanico/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/portafinestra_1_anta/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/portafinestra_1_anta/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/portafinestra_2_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/portafinestra_2_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/portafinestra_3_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/portafinestra_3_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_hst_1_anta/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_hst_1_anta/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_hst_2_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_hst_2_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_hst_4_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_hst_4_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_sf_2_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_sf_2_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_sf_3_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_sf_3_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_sf_4_ante/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/scorrevole_sf_4_ante/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/traslante_scorrevole_1_anta/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/traslante_scorrevole_1_anta/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/traslante_scorrevole_1_anta_f/destra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/apertura/traslante_scorrevole_1_anta_f/sinistra.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/406200.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/50811.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/50811_50801.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/9320.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/NP8300.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/NP8500.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/NP8700.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/coprifili_piatti.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/profili_extra/coprifili_scatolati.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/telaio/telaio_l.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/telaio/telaio_z_35.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/opzioni/telaio/telaio_z_60.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/01_acustico_base.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/02_standard_satinato.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/03_standard_trasparente.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/04_acustico_satinato.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/05_vetro_max_trasparente.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/06_vetro_max_satinato.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/07_no_vetro.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/08_pannello_pvc_bianco.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/09_pannello_pvc_rivestito.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/10_riflettente_no_termico_trasparente.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/11_riflettente_termico.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/12_riflettente_no_termico_bronzo.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/13_triplo_base_satinato.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/icone/14_triplo_base_trasparente.jpg create mode 100644 backoffice/database/seeders/data/configuratore/pvc/vetri/texture/vetro_satinato.jpg create mode 100644 backoffice/database/seeders/data/configuratore_pvc.php create mode 100644 backoffice/database/seeders/data/configuratore_pvc_catalogo.php create mode 100644 backoffice/database/seeders/data/icone/pvc/scorrevole_hst_4_ante.jpg create mode 100644 backoffice/database/seeders/data/icone/pvc/scorrevole_sf_3_ante.jpg create mode 100644 backoffice/database/seeders/data/icone/pvc/scorrevole_sf_4_ante.jpg create mode 100644 backoffice/database/seeders/data/icone/pvc/traslante_scorrevole_1_anta_f.jpg create mode 100644 backoffice/tests/Feature/ConfiguratoreAdminTest.php create mode 100644 backoffice/tests/Feature/ConfiguratorePrezzoTest.php create mode 100644 reference/Regole_Profili Extra.xls create mode 100644 src/js/configurazione_precedente.js diff --git a/.gitignore b/.gitignore index f1bee86..e25a23a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ /backoffice/cliente/dist/ /node_modules/ kreios.zip -.env.production \ No newline at end of file +.env.production +Thumbs.db +/reference/icone_profili_extra \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 3f0c6ee..6bce9f9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,16 +41,21 @@ Entry point is `src/js/starter.js`, loaded from `src/index.html`. Flow on load ( *Note: that doc describes a more modular refactor (`Application.js`, `communication/UrlParamsParser.js`, `communication/IframeBridge.js`) that does not exist yet in `src/js` — the current implementation is the flatter `starter.js`/`params_parser.js` described here.* -2. Product/catalog data is fetched as JSON from `src/assets/data/sistemi//modelli.json` and - `src/assets/data/modelli///{form,modello,maniglia,avvolgibile,vetro,listino}.json` - (which JSON files are fetched depends on the `moduli` array in the matched `modelli.json` entry). +2. Catalog data comes from the Laravel backoffice (`backoffice/`, API base in `src/js/api_base.js`): + `GET /api/sistemi` (systems + active models that have a price list; models without one are hidden and flagged in the admin list) and + `GET /api/sistemi//modelli//configurazione`, which returns the menu wiring (`form`: radios, + selects, finish menus — the old `form.json` shape), finishes, handles, glass types and the price-grid sizes, + with image URLs served by `GET /api/media/...` (CORS-enabled, needed for WebGL textures). Only + `avvolgibile.json` and `sistemi//altezza_maniglia_.json` are still read from `src/assets/data`. 3. **`MenuBuilder.build()`** (`src/js/menu_builder.js`) injects an HTML template (`assets/_menu.html`, or `assets/_menu-cassonetto.html` when `type=cassonetto`) into `#left-container`, builds the model-picker list, handles the mobile-portrait/landscape layout reflow, and initializes `PriceCalculator`. It returns the price calculator instance used by the rest of the app. 4. **`Configurator.init()` / `.enable()`** (`src/js/configurator.js`) wires a single delegated `input` handler - on the size fields, selects and radios. On every change it recomputes price via `PriceCalculator`, builds - `window.configurazione` (the object that gets posted to the parent on "add to cart"), and updates the DOM. + on the size fields, selects and radios. On every change (debounced) it sends the selected codes to + `POST /api/sistemi//modelli//prezzo`, stores the result in `window.configurazione` and + updates the DOM. "Add to cart" sends the same codes (`scelte`): the backend recomputes the price and ignores + any price coming from the client. 5. **`APP.Player`** (`src/js/app.js`) wraps a Three.js renderer/scene/camera (scene graph loaded from `src/assets/app.json`, a three.js-editor-style export) plus the actual product GLB (`src/assets/models//`). Two players are created: `player` (visible canvas) and @@ -59,22 +64,30 @@ Entry point is `src/js/starter.js`, loaded from `src/index.html`. Flow on load ( per `userData.categoria` mesh tag — categories like `interno`, `esterno`, `maniglia`, `vetro`, `cerniere`), `flipView` (180° GSAP-animated turn between front/back view), `addMarker` (in-scene hotspot with a video popup). -6. **`PriceCalculator`** (`src/js/price_calculator.js`) is a stateless-ish module (single module-level - `listini` cache set via `init`) that looks up a base price from a width/height grid in **mm** (served by - the backoffice API, using the first grid size ≥ the requested one) and layers on percentage/flat supplements for finish, glass, hinges, handle - height, and actuator type, then adds 22% VAT. +6. **Pricing is server-side only**: `backoffice/app/Support/Configuratore/CalcolatorePrezzo.php`. + `prezzo = base × (1 + supplementi % / 100) + supplementi fissi + variazione vetro` (VAT excluded). Base is + the first grid size ≥ the requested one (mm). Supplements come from `opzioni` rows (finish type + bianco/uniforme/bicolore, hinges, profili extra, ...): percentage, fixed, or per linear metre + (ml from L/H multipliers + extra mm). Groups with `ui = multipla` (profili extra) accept several codes, + with same-`alternativa` options mutually exclusive. Sistema-level rows can be overridden per model by group. + Option groups themselves live in `gruppi_opzioni` (title, control radio/select/multipla, menu section, and + the model `moduli` key that enables them): a group without fixed markup in `_menu.html` is rendered by + `MenuBuilder` into `.opzioni-sistema` / `.opzioni-accessori`. Select options can call a `window[func]` + (e.g. `nascondiCategoria` with `categoria: maniglia` for the motor) via their `parametri`. The glass + variation is Σ max(pane area, minimo_mq) × maggiorazione_mq, with panes from the model's `regole_vetro` + (spec: "Specifica tecnica vetri"). All of it is edited in Filament under "Configuratore". + `src/js/price_calculator.js` only wraps the API call and the grid sizes. ### Data conventions - Every 3D-visible part is tagged with `userData.categoria` in the GLB/scene so JS can show/hide/retexture it without knowing mesh names (`interno`, `esterno`, `maniglia`, `cerniere`, `vetro`, ...). -- Each model folder under `src/assets/data/modelli///` follows the same file set: - `form.json` (UI radios/selects/finiture wiring — declares which named ` +
- ${option.descrizione} + ${option.descrizione}
@@ -334,8 +323,6 @@ const buildTextureRadio = async (model, parent, icon_folder, texture_folder, cat const isStale = () => textureRequestVersion[parent] !== requestVersion; option.categories = categories; - option.folder = model; - option.texture_folder = texture_folder; option.isStale = isStale; $(".mobile-popup-backdrop, .mobile-popup").addClass("d-none"); @@ -357,15 +344,43 @@ const buildTextureRadio = async (model, parent, icon_folder, texture_folder, cat //container.querySelector(`.${parent}`).innerHTML = html; }; +const assicuraContenitore = (key, gruppo) => { + if (container.querySelector(`.${key}`)) return; + + const controllo = gruppo.ui === 'select' + ? `` + : ``; + + $(container).find(`.opzioni-${gruppo.sezione}`).append(`
+
+ +
+
`); + + if (gruppo.sezione === 'sistema') $('.sistema-menu').removeClass('d-none'); +}; + +const buildMultiple = (options, key) => options.map(option => `
+ +
${option.label}
+
`).join(''); + const buildRadios = (options, key, model) => { let html = ''; let has_sub_options = false; options.forEach((option, i) => { - let percentuale = ''; let modello = ''; - let class_percentuale = ''; let has_options = false; let sub_option_container = null; let html_func = ''; @@ -391,11 +406,6 @@ const buildRadios = (options, key, model) => { modello = `data-model="${option.model}"`; } - if (option.percentuale != null) { - percentuale = `data-percentuale="${option.percentuale}"`; - class_percentuale = 'percentuale'; - } - if (has_options) { has_options_class = 'has-options'; html_func = `onclick="toggleSubOption('${sub_option_container.id}',event)"`; @@ -407,9 +417,9 @@ const buildRadios = (options, key, model) => { html += `