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>
269 lines
13 KiB
PHP
Executable File
269 lines
13 KiB
PHP
Executable File
<!-- Banner -->
|
||
<section id="banner">
|
||
<img src="<?php echo SITEURL;?>assets/img/barber/banner.jpg" />
|
||
<!--div class="inner">
|
||
<h2>Ipsum dolore</h2>
|
||
<p>Amet lorem ipsum consequat feugiat</p>
|
||
</div-->
|
||
</section>
|
||
|
||
|
||
<section id="mobil-menu">
|
||
<div class="mobil-menucont">
|
||
<ul>
|
||
<li class="mobil-menu-book"><a href="<?php echo SITEURL;?>no/booking/barber">BESTILL TIME</a></li>
|
||
<li class=""><a href="https://www.facebook.com/studiobevebarber" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
|
||
<li class=""><a href="https://www.instagram.com/studio.beve.barber/" 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 SITEURL;?>assets/img/ollo.png">
|
||
<h2>Om oss</h2>
|
||
</header>
|
||
<div class="bemutatkozas">
|
||
<div class="bem-bal">
|
||
<p>
|
||
Mitt navn er Evelin Bence, lederen og skaperen av Studio Beve. Jeg anser det som viktig at våre gjester under oppholdet hos oss – mens de stenger ute litt av støyen fra omverdenen – kan lade sine batterier og kan vende tilbake til hverdagen forskjønnet både innvendig og utvendig.
|
||
</p>
|
||
<p>
|
||
Kvalitetstid, maksimal oppmerksomhet, de mest profesjonelle verktøyene, hånd i hånd med profesjonalitet og kompetanse, utgjør grunnlaget for vår filosofi og våre tjenester.
|
||
</p>
|
||
<p>
|
||
Jeg mener at skjønnhet, mote og trend ikke er kjønnsspesifikke, og hos oss har derfor alle mulighet til å bli vakrere på ett sted, uavhengig av kjønn. Hos Studio Beve Barber, Studio Beve Beauty og Studio Beve Massasje kan dere finne de tjenestene som er riktige for dere.
|
||
</p>
|
||
<p>
|
||
Med nesten 10 års erfaring fra skjønnhetsindustrien, inkludert mange års internasjonal erfaring, tenkte jeg det var på tide å åpne mitt eget studio her i Trondheim i Innheredsveien 92, hvor gjestene har mulighet til å parkere gratis under behandlingene.
|
||
</p>
|
||
<p>
|
||
Det er en ekstra glede for meg at jeg klarte å finne et tradisjonelt sted hvor det allerede var en skjønnhetssalong på 50-tallet. Derfor har jeg nå muligheten til å videreføre denne tradisjonen i et moderne miljø.
|
||
Bli vakker hos oss. Vi ser frem til å ønske deg velkommen.
|
||
</p>
|
||
</div>
|
||
<div class="bem-jobb">
|
||
<img src="<?php echo SITEURL;?>assets/img/evelin.JPG">
|
||
<h4>Evelin Bence <br> <span>Eieren, Studio Beve</span></h4>
|
||
</div>
|
||
</div>
|
||
<div class="dolgozo-nev">
|
||
<hr>
|
||
<img src="<?php echo SITEURL;?>assets/img/barber/evelin/evelin.jpg" class="dolgozo-kep">
|
||
<h4>EVELIN Bence <span>- Barber</span></h4>
|
||
</div>
|
||
<div class="bemutatkozas-dolgozo">
|
||
<div class="bem-dolgozo-bal">
|
||
<p>
|
||
"Jeg lærte å kjenne det grunnleggende om det å være barber allerede i svært ung alder, siden min mor også er barber. Fra henne klarte jeg i svært ung alder å mestre knepene i dette fantastiske yrket. Man kan si at jeg ble født inn i yrket, og jeg har offisielt vært andregenerasjons barber i noen år nå.
|
||
</p>
|
||
<p>
|
||
Jeg er stolt over å ha lært av de beste. Min mesterbarber og venn Ruben Tenkely, eier av «Peaky Barbers – Tenkely Limited Company», europacupvinner og ungarsk mester, har også skaffet seg mye erfaring internasjonalt. Han har blant annet arbeidet i en av Norges mest kjente tradisjonelle salonger, Brødrene Fevangs Barberstue. Slik lærte jeg om trender i Norge.
|
||
</p>
|
||
<p>
|
||
Jeg har bodd i Norge siden april 2023 og er ivrig etter å lære norsk. Jeg føler meg heldig som har fått muligheten til å jobbe sammen med Felipe Romero i Trondheim, som også er en utrolig kunnskapsrik barber. Hos ham kan flere av dere ha møtt og blitt kjent med meg.
|
||
</p>
|
||
<p>
|
||
Jeg deltar stadig på videreutdanninger fordi jeg tror at kontinuerlig utvikling, kvalitetsarbeid og engasjement hjelper meg til å bli en bedre fagperson dag for dag."
|
||
</p>
|
||
</div>
|
||
<div class="bem-dolgozo-jobb">
|
||
<img src="<?php echo SITEURL;?>assets/img/barber/evelin/1.jpg">
|
||
<img src="<?php echo SITEURL;?>assets/img/barber/evelin/2.jpg">
|
||
<img src="<?php echo SITEURL;?>assets/img/barber/evelin/3.jpg">
|
||
<img src="<?php echo SITEURL;?>assets/img/barber/evelin/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 SITEURL;?>assets/img/ollo.png">
|
||
<h2 class="nyitva">Behandlinger</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">Skjeggtrimming</div>
|
||
<div class="sub-title-serv">knivbarbering med varmt håndkle</div>
|
||
</div>
|
||
</div>
|
||
<div class="service-text service-text2">
|
||
<div class="service-icon icon2"></div>
|
||
<div class="service-content">
|
||
<div class="main-title">Barneklipp</div>
|
||
<div class="sub-title-serv">0-12 år</div>
|
||
</div>
|
||
</div>
|
||
<div class="service-text service-text3">
|
||
<div class="service-icon icon3"></div>
|
||
<div class="service-content">
|
||
<div class="main-title">Skjeggfarging</div>
|
||
<div class="sub-title-serv">skjeggfarging</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="one-third service-part2">
|
||
<div class="service-inner">
|
||
<div class="service service2">
|
||
<a href="#" class="banner-anchor"><img src="<?php echo SITEURL;?>assets/img/service-banner.png" alt="service-banner1" 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">Tradisjonell knivbarbering med varmt håndkle</div>
|
||
<div class="sub-title-serv">hele ansiktet</div>
|
||
</div>
|
||
</div>
|
||
<div class="service-text service-text2">
|
||
<div class="service-icon icon2"></div>
|
||
<div class="service-content">
|
||
<div class="main-title">Herreklipp eller Skinfade herreklipp</div>
|
||
<div class="sub-title-serv">overgang fra hodebunnen f.eks taper, low, mid eller high</div>
|
||
</div>
|
||
</div>
|
||
<div class="service-text service-text3">
|
||
<div class="service-icon icon3"></div>
|
||
<div class="service-content">
|
||
<div class="main-title">Voks</div>
|
||
<div class="sub-title-serv">nese, øre og<br> øyenbrynvoksing</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- One -->
|
||
|
||
<section id="one" class="wrapper style1">
|
||
<div class="container">
|
||
<div class="inner">
|
||
<header class="major">
|
||
<img src="<?php echo SITEURL;?>/assets/img/barber/ollo.png">
|
||
<h2>Priser</h2>
|
||
<h4>Prisen på alle hårbehandling inkluderer hårvask og styling.<br>10% studentrabatt ved framvising av ID, kan benyttes fra mandag til torsdag.</h4>
|
||
</header>
|
||
<?php
|
||
$prevousCategory = '';
|
||
|
||
if(is_array($services)){
|
||
foreach($services as $serviceItem){
|
||
if($serviceItem->service_category != $prevousCategory){
|
||
?>
|
||
<div class="prices-category" style="width: 100%;">
|
||
<h4 style="color: #9e8462;"><?php echo $serviceItem->service_category;?></h4>
|
||
</div>
|
||
<?php
|
||
}
|
||
?>
|
||
<div class="one-half">
|
||
<div class="category-content">
|
||
<div class="category-text-left">
|
||
<div class="main-title"><a><?php echo $serviceItem->service_name;?></a></div>
|
||
<div class="sub-title"><?php echo $serviceItem->service_description;?></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;
|
||
}
|
||
}
|
||
?>
|
||
|
||
<?php
|
||
/*
|
||
if(is_array($services)){
|
||
foreach($services as $serviceItem){
|
||
?>
|
||
<div class="one-half">
|
||
<div class="category-content">
|
||
<div class="category-text-left">
|
||
<div class="main-title"><a><?php echo $serviceItem->service_name;?></a></div>
|
||
<div class="sub-title"><?php echo $serviceItem->service_description;?></div>
|
||
</div>
|
||
<div class="category-text-right">
|
||
<div class="price">kr <?php echo $serviceItem->service_price;?></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
}
|
||
}
|
||
*/
|
||
?>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
|
||
<!-- Two -->
|
||
<section id="two" class="wrapper style2">
|
||
<div class="container">
|
||
<div class="inner">
|
||
<header class="major">
|
||
<img src="<?php echo SITEURL;?>assets/img/ollo.png">
|
||
<h2 class="nyitva">Åpningstider</h2>
|
||
<h4>Gratis kundeprarking under behandlingen</h4>
|
||
</header>
|
||
</div>
|
||
<div class="nyitvatartas">
|
||
<div class="about-content">
|
||
<div class="about-text-left">
|
||
<div class="title">Ukedager</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">Lørdag</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">Søndag</div>
|
||
</div>
|
||
<div class="about-text-right">
|
||
<div class="closed">Stengt</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|