Files
comelifacciamo/public/home.php
T
2026-09-09 08:26:26 +02:00

758 lines
24 KiB
PHP

<?php
// index.php — Homepage HairBook (Come Li Facciamo)
// Hero + ricerca, VANTAGGI cliente, mappa Leaflet, griglia saloni, come funziona, CTA salone.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once(__DIR__ . '/userarea/class/db-functions.php');
$pdo = DBHandlerSelect::getInstance()->getConnection();
$salons = $pdo->query("
SELECT sh.id, sh.name, sh.slug, sh.description, sh.address, sh.city, sh.province,
sh.latitude, sh.longitude, sh.logo, sh.cover_image,
(SELECT MIN(sv.price) FROM services sv WHERE sv.shop_id = sh.id AND sv.is_active = 1) AS min_price
FROM shops sh
WHERE sh.active = 1
ORDER BY sh.name ASC
")->fetchAll(PDO::FETCH_ASSOC);
$mapSalons = array_values(array_filter($salons, function ($s) {
return $s['latitude'] !== null && $s['longitude'] !== null;
}));
$cities = $pdo->query("
SELECT DISTINCT city FROM shops
WHERE active = 1 AND city IS NOT NULL AND city <> ''
ORDER BY city ASC
")->fetchAll(PDO::FETCH_COLUMN);
$favIds = [];
if (!empty($_SESSION['iduserlogin'])) {
$fstmt = $pdo->prepare("SELECT shop_id FROM user_favorite_shops WHERE user_id = ?");
$fstmt->execute([$_SESSION['iduserlogin']]);
$favIds = $fstmt->fetchAll(PDO::FETCH_COLUMN);
}
$mapData = array_map(function ($s) {
return [
'name' => $s['name'],
'slug' => $s['slug'],
'lat' => (float)$s['latitude'],
'lng' => (float)$s['longitude'],
'city' => $s['city'],
'addr' => $s['address']
];
}, $mapSalons);
$totalSalons = count($salons);
function euro($v): string
{
return number_format((float)$v, 2, ',', '.');
}
?>
<!doctype html>
<html class="no-js" lang="it">
<head>
<?php include('tophead.php'); ?>
<?php include('cssinclude.php'); ?>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
.hm-accent {
background: linear-gradient(120deg, #e6007e, #ff6a3d);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.hm-btn {
display: inline-block;
text-align: center;
padding: 14px 34px;
border-radius: 12px;
font-weight: 800;
font-size: 16px;
text-decoration: none;
transition: all .15s ease;
}
.hm-btn-primary {
background: linear-gradient(120deg, #e6007e, #ff6a3d);
color: #fff;
box-shadow: 0 12px 28px rgba(230, 0, 126, .3);
}
.hm-btn-primary:hover {
color: #fff;
transform: translateY(-2px);
opacity: .95;
}
.hm-btn-ghost {
background: #fff;
color: #e6007e;
border: 1.5px solid #ffd0e4;
}
.hm-btn-ghost:hover {
background: #e6007e;
color: #fff;
}
/* HERO */
.hm-hero {
position: relative;
padding: 100px 0 70px;
background: linear-gradient(160deg, #fff5f9 0%, #fff 60%, #fff7f3 100%);
text-align: center;
}
.hm-hero h1 {
font-size: 56px;
font-weight: 900;
color: #2b2540;
letter-spacing: -.03em;
line-height: 1.06;
margin-bottom: 20px;
}
.hm-hero p {
font-size: 20px;
color: #6b6480;
max-width: 640px;
margin: 0 auto 38px;
line-height: 1.5;
}
@media (max-width:575px) {
.hm-hero h1 {
font-size: 38px;
}
.hm-hero p {
font-size: 17px;
}
}
.hm-search {
max-width: 680px;
margin: 0 auto;
background: #fff;
border: 1.5px solid #ffe0ee;
border-radius: 16px;
padding: 10px;
display: flex;
gap: 8px;
box-shadow: 0 18px 50px rgba(230, 0, 126, .1);
}
@media (max-width:600px) {
.hm-search {
flex-direction: column;
}
}
.hm-search select,
.hm-search input {
flex: 1;
border: none;
padding: 14px 16px;
font-size: 15px;
border-radius: 10px;
background: #faf7fb;
}
.hm-search select:focus,
.hm-search input:focus {
outline: 2px solid #ffd0e4;
}
.hm-search button {
background: linear-gradient(120deg, #e6007e, #ff6a3d);
color: #fff;
border: none;
border-radius: 10px;
padding: 14px 28px;
font-weight: 800;
cursor: pointer;
white-space: nowrap;
}
.hm-trust {
margin-top: 26px;
display: flex;
gap: 26px;
justify-content: center;
flex-wrap: wrap;
color: #8b8399;
font-size: 14px;
font-weight: 600;
}
.hm-trust span i {
color: #1db954;
margin-right: 6px;
}
/* SEZIONE VANTAGGI (perché usarla) */
.hm-why {
padding: 80px 0;
}
.hm-sec-head {
text-align: center;
margin-bottom: 50px;
}
.hm-sec-head h2 {
font-size: 36px;
font-weight: 900;
color: #2b2540;
letter-spacing: -.02em;
margin-bottom: 12px;
}
.hm-sec-head p {
color: #6b6480;
font-size: 18px;
max-width: 580px;
margin: 0 auto;
}
.hm-why-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 26px;
max-width: 1080px;
margin: 0 auto;
}
@media (max-width:850px) {
.hm-why-grid {
grid-template-columns: 1fr 1fr;
}
}
@media (max-width:560px) {
.hm-why-grid {
grid-template-columns: 1fr;
}
}
.hm-why-card {
background: #fff;
border: 1.5px solid #f0e6ee;
border-radius: 20px;
padding: 32px 26px;
text-align: center;
transition: transform .16s ease, box-shadow .16s ease, border-color .16s;
}
.hm-why-card:hover {
transform: translateY(-6px);
box-shadow: 0 24px 54px rgba(43, 37, 64, .12);
border-color: #ffd0e4;
}
.hm-why-ico {
width: 70px;
height: 70px;
margin: 0 auto 20px;
border-radius: 20px;
background: linear-gradient(135deg, #e6007e, #ff6a3d);
color: #fff;
font-size: 30px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 14px 30px rgba(230, 0, 126, .26);
}
.hm-why-card h4 {
font-size: 20px;
font-weight: 800;
color: #2b2540;
margin-bottom: 10px;
}
.hm-why-card p {
color: #6b6480;
font-size: 15px;
line-height: 1.6;
}
/* FASCIA gratis */
.hm-free {
background: linear-gradient(120deg, #e6007e, #ff6a3d);
padding: 56px 20px;
text-align: center;
}
.hm-free h3 {
font-size: 30px;
font-weight: 900;
color: #fff;
margin-bottom: 10px;
}
.hm-free p {
color: rgba(255, 255, 255, .94);
font-size: 18px;
max-width: 600px;
margin: 0 auto;
}
/* SECTION generica */
.hm-sec {
padding: 70px 0;
}
/* MAPPA */
.hm-map-wrap {
position: relative;
max-width: 1120px;
margin: 0 auto;
}
#hm-map {
height: 440px;
border-radius: 20px;
border: 1.5px solid #f0e6ee;
box-shadow: 0 20px 50px rgba(43, 37, 64, .1);
z-index: 1;
}
.hm-map-geo {
margin-top: 14px;
text-align: center;
}
.hm-map-geo button {
background: #fff;
border: 1.5px solid #ffd0e4;
color: #e6007e;
font-weight: 700;
padding: 10px 20px;
border-radius: 10px;
cursor: pointer;
}
.hm-map-geo button:hover {
background: #e6007e;
color: #fff;
}
/* GRIGLIA saloni */
.hm-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
max-width: 1120px;
margin: 0 auto;
}
.hm-card {
background: #fff;
border: 1px solid #f0e6ee;
border-radius: 18px;
overflow: hidden;
transition: transform .16s ease, box-shadow .16s ease;
}
.hm-card:hover {
transform: translateY(-5px);
box-shadow: 0 22px 50px rgba(43, 37, 64, .13);
}
.hm-card-img {
position: relative;
height: 170px;
background: linear-gradient(135deg, #e6007e, #ff6a3d);
overflow: hidden;
}
.hm-card-img img {
width: 100%;
height: 100%;
object-fit: cover;
}
.hm-card-fav {
position: absolute;
top: 12px;
right: 12px;
width: 38px;
height: 38px;
border-radius: 50%;
background: rgba(255, 255, 255, .92);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: none;
}
.hm-card-fav i {
color: #e11d6b;
font-size: 16px;
}
.hm-card-body {
padding: 18px;
}
.hm-card-body h4 {
font-size: 18px;
font-weight: 800;
color: #2b2540;
margin-bottom: 6px;
}
.hm-card-loc {
color: #9a93ac;
font-size: 13.5px;
margin-bottom: 14px;
}
.hm-card-loc i {
color: #e6007e;
margin-right: 4px;
}
.hm-card-foot {
display: flex;
align-items: center;
justify-content: space-between;
}
.hm-card-price {
font-size: 14px;
color: #2b2540;
}
.hm-card-price b {
color: #e6007e;
font-size: 17px;
}
.hm-card-btn {
background: #fff5f9;
color: #e6007e;
border: 1.5px solid #ffd9e8;
padding: 8px 16px;
border-radius: 9px;
font-weight: 700;
font-size: 13.5px;
text-decoration: none;
transition: all .15s;
}
.hm-card-btn:hover {
background: #e6007e;
color: #fff;
}
/* COME FUNZIONA */
.hm-how {
background: #fff5f9;
}
.hm-steps {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 28px;
max-width: 960px;
margin: 0 auto;
}
@media (max-width:800px) {
.hm-steps {
grid-template-columns: 1fr;
}
}
.hm-step {
text-align: center;
padding: 14px;
}
.hm-step-ico {
width: 64px;
height: 64px;
margin: 0 auto 16px;
border-radius: 18px;
background: linear-gradient(135deg, #e6007e, #ff6a3d);
color: #fff;
font-size: 26px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 12px 26px rgba(230, 0, 126, .24);
}
.hm-step h4 {
font-size: 18px;
font-weight: 800;
color: #2b2540;
margin-bottom: 8px;
}
.hm-step p {
color: #6b6480;
font-size: 14.5px;
}
/* CTA salone */
.hm-cta-salon {
background: #2b2540;
padding: 70px 20px;
text-align: center;
}
.hm-cta-salon h2 {
font-size: 34px;
font-weight: 900;
color: #fff;
margin-bottom: 14px;
}
.hm-cta-salon p {
color: rgba(255, 255, 255, .8);
font-size: 18px;
margin-bottom: 30px;
}
</style>
</head>
<body>
<?php include('preloader.php'); ?>
<?php include('offcanvas.php'); ?>
<header class="tp-header-height"><?php include('topbar.php'); ?></header>
<main>
<!-- HERO -->
<section class="hm-hero">
<div class="container">
<h1>Il tuo parrucchiere,<br><span class="hm-accent">prenotato in un tap</span></h1>
<p>Trova i saloni migliori vicino a te, scegli servizio e orario, e prenota online in pochi secondi. Senza chiamare, a qualsiasi ora.</p>
<form class="hm-search" action="search.php" method="get">
<select name="city">
<option value="">Tutte le città</option>
<?php foreach ($cities as $c): ?>
<option value="<?= htmlspecialchars($c) ?>"><?= htmlspecialchars($c) ?></option>
<?php endforeach; ?>
</select>
<input type="text" name="service" placeholder="Che servizio cerchi? (es. taglio)">
<button type="submit"><i class="fa-solid fa-magnifying-glass"></i> Cerca</button>
</form>
<div class="hm-trust">
<span><i class="fa-solid fa-circle-check"></i> Gratis per te</span>
<span><i class="fa-solid fa-circle-check"></i> Nessuna registrazione per cercare</span>
<span><i class="fa-solid fa-circle-check"></i> Prenoti 24 ore su 24</span>
</div>
</div>
</section>
<!-- PERCHÉ USARLA -->
<section class="hm-why">
<div class="container">
<div class="hm-sec-head">
<h2>Perché prenotare con noi</h2>
<p>Dì addio alle telefonate e alle attese. Il tuo salone a portata di tap, quando vuoi tu.</p>
</div>
<div class="hm-why-grid">
<div class="hm-why-card">
<div class="hm-why-ico"><i class="fa-solid fa-clock"></i></div>
<h4>Prenoti 24/7</h4>
<p>Anche di notte o nel weekend, quando il salone è chiuso. Scegli il momento, ci pensi quando puoi tu.</p>
</div>
<div class="hm-why-card">
<div class="hm-why-ico"><i class="fa-solid fa-calendar-day"></i></div>
<h4>Disponibilità reali</h4>
<p>Vedi gli orari liberi in tempo reale e prenoti solo slot davvero disponibili. Niente telefonate a vuoto.</p>
</div>
<div class="hm-why-card">
<div class="hm-why-ico"><i class="fa-solid fa-user-check"></i></div>
<h4>Il tuo parrucchiere preferito</h4>
<p>Scegli l'operatore da cui vuoi farti servire e ritrovalo a ogni prenotazione.</p>
</div>
<div class="hm-why-card">
<div class="hm-why-ico"><i class="fa-solid fa-bell"></i></div>
<h4>Promemoria e storico</h4>
<p>Ricordi i tuoi appuntamenti a colpo d'occhio e riprenoti in un attimo quello che hai già fatto.</p>
</div>
<div class="hm-why-card">
<div class="hm-why-ico"><i class="fa-solid fa-heart"></i></div>
<h4>I tuoi saloni preferiti</h4>
<p>Salva i saloni che ami e ritrovali subito, senza cercarli ogni volta.</p>
</div>
<div class="hm-why-card">
<div class="hm-why-ico"><i class="fa-solid fa-location-dot"></i></div>
<h4>Vicino a te</h4>
<p>Scopri i saloni della tua zona sulla mappa e raggiungi quello più comodo.</p>
</div>
</div>
</div>
</section>
<!-- FASCIA GRATIS -->
<section class="hm-free">
<h3>Per te è tutto gratis</h3>
<p>Cercare, confrontare e prenotare non ti costa nulla. Paghi solo il servizio, direttamente al salone.</p>
</section>
<!-- MAPPA -->
<section class="hm-sec">
<div class="container">
<div class="hm-sec-head">
<h2>Saloni vicino a te</h2>
<p>Esplora la mappa e scopri i parrucchieri nella tua zona.</p>
</div>
<div class="hm-map-wrap">
<div id="hm-map"></div>
<div class="hm-map-geo">
<button type="button" id="hm-geo-btn"><i class="fa-solid fa-location-crosshairs"></i> Usa la mia posizione</button>
</div>
</div>
</div>
</section>
<!-- GRIGLIA SALONI -->
<section class="hm-sec" style="padding-top:0;">
<div class="container">
<div class="hm-sec-head">
<h2>Saloni in evidenza</h2>
<p><?= $totalSalons ?> salon<?= $totalSalons === 1 ? 'e' : 'i' ?> ti aspetta<?= $totalSalons === 1 ? '' : 'no' ?> online.</p>
</div>
<?php if (empty($salons)): ?>
<p class="text-center text-muted">Ancora nessun salone disponibile. Torna presto!</p>
<?php else: ?>
<div class="hm-grid">
<?php foreach (array_slice($salons, 0, 8) as $s):
$cover = !empty($s['cover_image']) ? htmlspecialchars($s['cover_image']) : '';
$isFav = in_array($s['id'], $favIds);
$loc = trim(($s['city'] ?? '') . ($s['province'] ? ' (' . $s['province'] . ')' : ''));
?>
<div class="hm-card">
<div class="hm-card-img">
<?php if ($cover): ?><img src="<?= $cover ?>" alt="<?= htmlspecialchars($s['name']) ?>"><?php endif; ?>
<button class="hm-card-fav js-fav <?= $isFav ? 'is-active' : '' ?>" data-id="<?= (int)$s['id'] ?>" title="Preferito" type="button">
<i class="<?= $isFav ? 'fa-solid' : 'fa-regular' ?> fa-heart"></i>
</button>
</div>
<div class="hm-card-body">
<h4><?= htmlspecialchars($s['name']) ?></h4>
<div class="hm-card-loc"><i class="fa-solid fa-location-dot"></i><?= htmlspecialchars($loc ?: '—') ?></div>
<div class="hm-card-foot">
<div class="hm-card-price">
<?php if ($s['min_price'] !== null): ?>da <b>€<?= euro($s['min_price']) ?></b><?php else: ?><span class="text-muted">Servizi vari</span><?php endif; ?>
</div>
<a href="salon.php?slug=<?= urlencode($s['slug']) ?>" class="hm-card-btn">Prenota</a>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php if ($totalSalons > 8): ?>
<div class="text-center mt-5">
<a href="search.php" class="hm-btn hm-btn-ghost">Vedi tutti i saloni</a>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</section>
<!-- COME FUNZIONA -->
<section class="hm-sec hm-how">
<div class="container">
<div class="hm-sec-head">
<h2>Prenotare è semplicissimo</h2>
<p>Tre passi e sei a posto.</p>
</div>
<div class="hm-steps">
<div class="hm-step">
<div class="hm-step-ico"><i class="fa-solid fa-magnifying-glass"></i></div>
<h4>1. Cerca</h4>
<p>Trova il salone giusto per città, servizio o vicinanza sulla mappa.</p>
</div>
<div class="hm-step">
<div class="hm-step-ico"><i class="fa-solid fa-calendar-check"></i></div>
<h4>2. Scegli</h4>
<p>Seleziona servizio, operatore e l'orario libero che preferisci.</p>
</div>
<div class="hm-step">
<div class="hm-step-ico"><i class="fa-solid fa-check"></i></div>
<h4>3. Prenota</h4>
<p>Confermi in pochi tap. Ritrovi tutto nella tua area personale.</p>
</div>
</div>
</div>
</section>
<!-- CTA SALONE -->
<section class="hm-cta-salon">
<h2>Hai un salone?</h2>
<p>Porta le tue prenotazioni online e riempi l'agenda senza pensieri.</p>
<a href="business.php" class="hm-btn hm-btn-primary">Scopri come funziona</a>
</section>
</main>
<footer><?php include('footer.php'); ?></footer>
<?php include('jsinclude.php'); ?>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
var salons = <?= json_encode($mapData, JSON_UNESCAPED_UNICODE) ?>;
var defaultCenter = [45.4642, 9.1900];
var map = L.map('hm-map').setView(defaultCenter, 11);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; OpenStreetMap',
maxZoom: 19
}).addTo(map);
var markers = [];
salons.forEach(function(s) {
if (!s.lat || !s.lng) return;
var m = L.marker([s.lat, s.lng]).addTo(map);
m.bindPopup('<strong>' + s.name + '</strong><br>' + (s.addr ? s.addr + '<br>' : '') +
'<a href="salon.php?slug=' + encodeURIComponent(s.slug) + '" style="color:#e6007e;font-weight:700;">Vai al salone →</a>');
markers.push(m);
});
if (markers.length > 0) {
var group = L.featureGroup(markers);
map.fitBounds(group.getBounds().pad(0.2));
}
document.getElementById('hm-geo-btn').addEventListener('click', function() {
if (!navigator.geolocation) {
alert('Geolocalizzazione non supportata dal browser.');
return;
}
navigator.geolocation.getCurrentPosition(function(pos) {
var lat = pos.coords.latitude,
lng = pos.coords.longitude;
map.setView([lat, lng], 13);
L.circleMarker([lat, lng], {
radius: 9,
color: '#e6007e',
fillColor: '#e6007e',
fillOpacity: .8
})
.addTo(map).bindPopup('Sei qui').openPopup();
}, function() {
alert('Non riusciamo a rilevare la tua posizione.');
});
});
</script>
</body>
</html>