Files
studiobeve.no/application/views/pages/includes/massage-form-hu.php
T
UbuntuandClaude Opus 5 5c30467fbd 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>
2026-08-13 16:34:47 +00:00

292 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/* -----------------------------------------------------------------------
* Massage vertical landing content - Hungarian.
*
* Bio, treatment names and descriptions supplied by the salon.
* Generated from one template so massage-form-no / -en / -hu stay
* structurally identical.
*
* DURATIONS: the price list shows the treatment time from the service NAME
* (50 / 80 / 110 min). services.service_time holds the longer BOOKED slot
* (60 / 90 / 120 min) which covers changing and payment, and is never
* rendered to the guest. See prices_note below.
*
* Still a placeholder: assets/img/massage/masseur.png (therapist portrait),
* assets/img/massage/banner.jpg and map.jpg.
* -------------------------------------------------------------------- */
?>
<!-- Banner -->
<section id="banner">
<img src="<?php echo base_url();?>assets/img/massage/banner.jpg" style="width: 100%;" />
</section>
<section id="mobil-menu">
<div class="mobil-menucont">
<ul>
<li class="mobil-menu-book"><a href="<?php echo SITEURL;?>hu/booking/massage">IDŐPONTFOGLALÁS</a></li>
<li class=""><a href="<?php echo $vertical['facebook'];?>" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
<li class=""><a href="<?php echo $vertical['instagram'];?>" class="icon brands fa-instagram"><span class="label">Instagram</span></a></li>
</ul>
</div>
</section>
<!-- About Us -->
<section id="aboutus" class="wrapper style1">
<div class="container">
<div class="inner">
<header class="major">
<img src="<?php echo base_url();?>assets/img/massage/ollo_rose.png">
<h2>Rólunk</h2>
</header>
<?php /* Owner block, lifted verbatim from beauty-form-<lang>.php at
generation time so all three verticals introduce Evelin
identically. Do not edit here - edit the beauty file and
regenerate, or the two will drift. */ ?>
<div class="bemutatkozas">
<div class="bem-bal">
<p>
Bence Evelin vagyok a Studio Beve vezetője és megálmodója. Fontosnak
tartom, hogy a vendégek a nálunk töltött idő alatt – egy kicsit megpihenve a világ zajától – feltöltődjenek, és kívül-belül egszépülve térjenek vissza a mindennapokhoz.
</p>
<p>
A minőségi idő, a maximális figyelem, a legprofesszionálisabb eszközök, a
hivatástudattal és szakértelemmel karöltve jelentik a filozófiánk és
szolgáltatásaink alapjait.
</p>
<p>
Hiszem, hogy a szépség, a divat és a trend nem nemhez kötött, így nálunk
lehetőség van arra, hogy mindenki egy helyen szépülhessen nemtől függetlenül.
A Barber, Beauty és Masszázs részlegeink között pedig megtalálhatjátok a számotokra
megfelelő szolgáltatásokat.
</p>
<p>
Közel 10 éves szépségipari, és közte több éves nemzetközi tapasztalattal
elérkezettnek láttam az időt, hogy megnyissam saját stúdiómat itt
Trondheimben, az Innheredsveien 92 szám alatt, ahol a vendégeknek lehetősége
van ingyenes parkolásra is a kezelések időtartama alatt.
</p>
<p>
Extra öröm számomra, hogy egy olyan tradicionális helyet sikerült találnom,
ahol az 50-es években már szépségszalon működött, ennek köszönhetően a
hagyományt, modern környezetben lehetőségem van tovább vinni.
Szépülj velünk, szeretettel várunk.
</p>
</div>
<div class="bem-jobb">
<img src="<?php echo base_url();?>assets/img/evelin_beauty.JPG">
<h4>Bence Evelin <br> <span>Tulajdonos, Studio Beve</span></h4>
</div>
</div>
<?php /* Therapist sub-section, following the per-worker pattern
barber/beauty use: circular portrait + name, then the bio
with a photo strip alongside. */ ?>
<div class="dolgozo-nev">
<hr>
<img src="<?php echo base_url();?>assets/img/massage/vincent/vincent.jpg" class="dolgozo-kep">
<h4>VINCENT Pusch <span>- Masszőr</span></h4>
</div>
<div class="bemutatkozas-dolgozo">
<div class="bem-dolgozo-bal">
<p>A masszázs, a manuális kezelések és az emberi test működése iránti érdeklődésem 2011 óta kísér, és az évek során szakmai pályám meghatározó részévé vált.</p>
<p>Fizioterápiás végzettségemet Németországban szereztem. Pályafutásomat katonai kórházban kezdtem, ahol fizioterapeutaként és manuálterapeutaként dolgoztam. Később multidiszciplináris rendelőben folytattam a munkámat, majd saját magánpraxist vezettem Németországban, mielőtt Norvégiába költöztem.</p>
<p>Az évek során folyamatosan bővítettem szakmai ismereteimet és tapasztalataimat. A fizioterápia és manuálterápia mellett sportfizioterápiával, valamint 2019 óta craniosacralis terápiával és oszteopátiával is foglalkozom. Fontos számomra a folyamatos szakmai fejlődés és az új módszerek megismerése.</p>
<p>Hiszek abban, hogy minden ember és minden test más, ezért a kezeléseim során mindig az egyéni igényeket és célokat tartom szem előtt. A különböző masszázs- és manuális technikákat ennek megfelelően választom ki és kombinálom, legyen szó relaxációról, a mindennapi vagy fizikai terhelés következtében kialakult izomfeszültségről, sport utáni regenerációról vagy egyszerűen a testi feltöltődésről.</p>
<p>2026 májusa óta élek Trondheimben. Külföldön megszerzett fizioterápiás képesítésem norvég elismertetése jelenleg folyamatban van. A Studio Bevében jelenleg masszőrként végzem szakmai tevékenységemet, ahol masszázs- és olyan manuális kezeléseket kínálok, amelyekhez nem szükséges norvég egészségügyi engedély. A norvég engedély megszerzésével szakmai tevékenységem és az általam kínált kezelések köre a jövőben tovább bővülhet.</p>
<p>Örömmel várom, hogy a Studio Beve vendégeit is megismerhessem, és szakmai tapasztalatommal személyre szabott, figyelmes kezelést nyújthassak számukra.</p>
</div>
<div class="bem-dolgozo-jobb">
<img src="<?php echo base_url();?>assets/img/massage/vincent/1.jpg">
<img src="<?php echo base_url();?>assets/img/massage/vincent/2.jpg">
<img src="<?php echo base_url();?>assets/img/massage/vincent/3.jpg">
<img src="<?php echo base_url();?>assets/img/massage/vincent/4.jpg">
</div>
</div>
</div>
</div>
</section>
<!-- Treatments -->
<section id="treatments" class="wrapper style2">
<div class="container">
<div class="inner">
<header class="major">
<img src="<?php echo base_url();?>assets/img/massage/ollo_rose.png">
<h2 class="nyitva">Szolgáltatások</h2>
</header>
</div>
<div class="service-block">
<div class="service-area">
<div class="one-third service-part1">
<div class="service-inner">
<div class="service service1">
<div class="service-text service-text1">
<div class="service-icon icon1"></div>
<div class="service-content">
<div class="main-title">Klasszikus svédmasszázs</div>
<div class="sub-title-serv">teljes test, lazítás és feltöltődés</div>
</div>
</div>
<div class="service-text service-text2">
<div class="service-icon icon2"></div>
<div class="service-content">
<div class="main-title">Sportmasszázs</div>
<div class="sub-title-serv">aktív életmódhoz és sportolóknak</div>
</div>
</div>
<div class="service-text service-text3">
<div class="service-icon icon3"></div>
<div class="service-content">
<div class="main-title">Mélyszöveti masszázs</div>
<div class="sub-title-serv">mélyebb izmok és kötőszövet</div>
</div>
</div>
</div>
</div>
</div>
<div class="one-third service-part2">
<div class="service-inner">
<div class="service service2">
<a href="<?php echo SITEURL;?>hu/booking/massage" class="banner-anchor"><img src="<?php echo base_url();?>assets/img/service-banner-massage.png" alt="massage" class="banner-image1"></a>
</div>
</div>
</div>
<div class="one-third service-part3">
<div class="service-inner">
<div class="service service3">
<div class="service-text service-text1">
<div class="service-icon icon1"></div>
<div class="service-content">
<div class="main-title">Irodai és fizikai munka utáni masszázs</div>
<div class="sub-title-serv">ülőmunkához és fizikai terheléshez</div>
</div>
</div>
<div class="service-text service-text2">
<div class="service-icon icon2"></div>
<div class="service-content">
<div class="main-title">Studio Beve Signature</div>
<div class="sub-title-serv">személyre szabott kezelés</div>
</div>
</div>
<div class="service-text service-text3">
<div class="service-icon icon3"></div>
<div class="service-content">
<div class="main-title">Craniosacralis kezelés</div>
<div class="sub-title-serv">gyengéd, holisztikus manuális kezelés</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Prices -->
<section id="one" class="wrapper style1">
<div class="container">
<div class="inner">
<header class="major">
<img src="<?php echo SITEURL;?>assets/img/massage/ollo_rose.png">
<h2>Árlista</h2>
<h4 class="prices-note">A feltüntetett kezelési idő a tényleges masszázsidőt jelenti. A lefoglalt időpont ennél valamivel hosszabb, hogy legyen idő az át&shy;öltözésre és a fizetésre.</h4>
</header>
<?php
/**
* Grouped by treatment type. Two deliberate differences from the
* barber/beauty price lists, both because massage sells the SAME
* treatment at two or three lengths:
*
* 1. The description is printed ONCE per group rather than once
* per duration, so a three-length treatment does not repeat
* its blurb three times.
* 2. The row label is the duration alone. services.service_name
* has to stay self-describing ("Klassisk svensk massasje -
* 50 min") because the booking form and the confirmation
* email render it with no category around it - but here the
* category heading is directly above, so repeating it just
* makes every row wrap.
*
* $services arrives ordered by service_id and the catalogue is
* inserted grouped, so a simple change-detect is enough.
*/
$prevousCategory = '';
if(is_array($services)){
foreach($services as $serviceItem){
if($serviceItem->service_category != $prevousCategory){
if($prevousCategory !== ''){
echo '<div style="clear:both;"></div>';
}
?>
<div class="prices-category" style="width: 100%">
<h4><?php echo $serviceItem->service_category;?></h4>
<p class="category-intro"><?php echo $serviceItem->service_description;?></p>
</div>
<?php
}
// Same rule as the booking form: the category heading is
// directly above, so the row need not repeat it.
$rowLabel = vertical_service_label($vertical, $serviceItem);
?>
<div class="one-half">
<div class="category-content">
<div class="category-text-left">
<div class="main-title"><a><?php echo $rowLabel;?></a></div>
</div>
<div class="category-text-right">
<div class="price">kr <?php echo $serviceItem->service_price;?></div>
</div>
</div>
</div>
<?php
$prevousCategory = $serviceItem->service_category;
}
echo '<div style="clear:both;"></div>';
}
?>
</div>
</div>
</section>
<!-- Opening hours -->
<section id="two" class="wrapper style2">
<div class="container">
<div class="inner">
<header class="major">
<img src="<?php echo SITEURL;?>assets/img/massage/ollo_rose.png">
<h2 class="nyitva">Nyitvatartás</h2>
<h4>Ingyenes vendégparkolás a kezelés ideje alatt</h4>
</header>
</div>
<div class="nyitvatartas">
<div class="about-content">
<div class="about-text-left">
<div class="title">Hétköznap</div>
</div>
<div class="about-text-right">
<div class="time">10:00 - 18:00</div>
</div>
</div>
<div class="about-content">
<div class="about-text-left">
<div class="title">Szombat</div>
</div>
<div class="about-text-right">
<div class="time">10:00 - 16:00</div>
</div>
</div>
<div class="about-content">
<div class="about-text-left">
<div class="title">Vasárnap</div>
</div>
<div class="about-text-right">
<div class="closed">Zárva</div>
</div>
</div>
</div>
</div>
</section>