Add massage as a third vertical, driven by a config registry
Introduces /massage alongside barber and beauty: landing page, booking flow, admin support, home tile and SEO entries, in all three languages. Architecture - application/config/verticals.php + vertical_helper.php: one registry entry per vertical (branding, assets, views, behaviour flags). A fourth vertical is a config entry plus content files. - Strangler: barber and beauty keep pointing at their existing view files, so their rendered HTML is unchanged. Only massage uses the new generic pages/vertical-*.php and includes/vertical-*.php views, which collapse the four duplicated per-language nav/footer branches into one. - Pages::vertical() + one route; booking(), booking_finished(), _booking_error() and manage_booking() are now registry-driven. Worker/vertical coupling - getActiveWorkers() derives the vertical from services.service_category_id instead of the workers.is_barber / is_beauty flags, which were a hand-maintained cache of exactly that fact. Verified against production data: the derived set reproduced the stored flags for every worker, in both verticals. No schema change was needed for massage. - The legacy flags are now written through from the category so a rollback cannot strand a new worker, and the admin worker UI shows the derived verticals read-only instead of two dropdowns that controlled nothing. Bug fixes found along the way (all pre-existing) - booking_process() had no server-side category guard; cross-vertical mixing was prevented only by client-side JS. - add-service-form / add-worker-form emitted `selected` on every category option, so the newest category silently became the default. - update-service-form offered only barber/beauty, so editing a service of any other type silently rewrote it. - getWorkerScheduleByDay ignored schedule overrides while getAvailableTimes honoured them, so slots could be shown and then rejected. Added an override-aware getWorkerScheduleForDate() and used it in both guards. - Booking lists dereferenced a null service if one had been hard-deleted. - main.css: .tiles was tuned for exactly two tiles, including an absolutely-positioned .style1 at the 1280px breakpoint. Massage-specific behaviour, opt-in per vertical - strip_category_prefix: grouped service lists show "50 min" under the treatment heading rather than repeating the full name. The full name is carried in data-service-name so the totals panel stays unambiguous, and services.service_name is untouched for emails and admin. - single_service_booking: one treatment per booking, enforced in the UI and in booking_process(). Re-clicking the selection releases it. - Displayed treatment time (50/80/110 min) is in the service name; the booked slot (60/90/120 min) is service_time and covers changing and payment. service_time is never shown to the guest. DB migrations for dev/prod are in documents/ - additive only, no ALTER. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Generic site footer for any vertical.
|
||||
*
|
||||
* Expects $vertical and $selectedLang.
|
||||
*
|
||||
* Replaces four near-identical <footer> copies per vertical file. The address,
|
||||
* org number and map link are salon-wide; only the social accounts and the map
|
||||
* image are per-vertical, and both come from the registry.
|
||||
*/
|
||||
|
||||
$labels = array(
|
||||
'en' => array(
|
||||
'orgnr' => 'Organisation number',
|
||||
'vacancies' => 'Open positions',
|
||||
'copyright' => '© Studio Beve - All rights reserved.',
|
||||
),
|
||||
'no' => array(
|
||||
'orgnr' => 'Organisasjonsnummer',
|
||||
'vacancies' => 'Ledige stillinger',
|
||||
'copyright' => '© Studio Beve - All rights reserved.',
|
||||
),
|
||||
'hu' => array(
|
||||
'orgnr' => 'Cégjegyzékszám',
|
||||
'vacancies' => 'Állásajánlatok',
|
||||
'copyright' => '© Studio Beve - All rights reserved.',
|
||||
),
|
||||
);
|
||||
|
||||
$lang = vertical_lang(isset($selectedLang) ? $selectedLang : 'en');
|
||||
$t = $labels[$lang];
|
||||
|
||||
$mapUrl = 'https://www.google.com/maps/place/Studio+Beve/@63.4370671,10.4348909,19z/data=!3m1!4b1!4m6!3m5!1s0x466d31f2b1166d2b:0x76228adf28216c74!8m2!3d63.4370671!4d10.4355346!16s%2Fg%2F11vlvkh6w4?entry=ttu';
|
||||
?>
|
||||
<!-- Footer -->
|
||||
<footer id="footer">
|
||||
<div class="container footer-div">
|
||||
<div class="footer-bal">
|
||||
<div class="contact-block">
|
||||
<ul>
|
||||
<li class="companyname"><span>Studio Beve AS</span></li>
|
||||
<li><span>Innherredsveien 92.<br> 7043 Trondheim, Norway</span></li>
|
||||
<li><span><?php echo $t['orgnr'];?>: 932 941 619</span></li>
|
||||
<li><span><a href="mailto:info@studiobeve.no">info@studiobeve.no</a></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="icons">
|
||||
<li><a href="<?php echo $vertical['facebook'];?>" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
|
||||
<li><a href="<?php echo $vertical['instagram'];?>" class="icon brands fa-instagram"><span class="label">Instagram</span></a></li>
|
||||
</ul>
|
||||
<a href="<?php echo SITEURL;?>ledigestilling/" class="footer-vacancies"><?php echo $t['vacancies'];?></a>
|
||||
</div>
|
||||
<div class="footer-jobb">
|
||||
<a href="<?php echo $mapUrl;?>" target="_blank"><img src="<?php echo SITEURL.$vertical['map_img'];?>"> </a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
<?php echo $t['copyright'];?>
|
||||
</div>
|
||||
</footer>
|
||||
Reference in New Issue
Block a user