Buongiorno
ho questi tre file
il file view.php
<?php
require_once 'config.php';
// 1. Recupero dati tramite codice NFC/Segreto
$code = $_GET['code'] ?? die("Profilo non trovato.");
$stmt = $pdo->prepare("SELECT * FROM contatti WHERE codice_segreto = ?");
$stmt->execute([$code]);
$c = $stmt->fetch();
if (!$c) { die("Profilo inesistente."); }
// 2. Pulizia numeri
$tel_clean = preg_replace('/[^0-9]/', '', $c['cellulare']);
$fisso_clean = preg_replace('/[^0-9]/', '', $c['telefono']);
$mappa_url = "http://maps.google.com/?q=" . urlencode($c['indirizzo'] . " " . $c['citta']);
?>
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title><?= htmlspecialchars($c['nome'] . ' ' . $c['cognome']) ?></title>
<link rel="manifest" href="manifest.php?code=<?= $code ?>">
<meta name="theme-color" content="#0097b2">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body { font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 0; background: #fff; color: #333; }
.container { width: 100%; max-width: 500px; margin: 0 auto; position: relative; padding-bottom: 120px; }
.header-bg { width: 100%; height: 210px; background: #0097b2; position: relative; }
.header-bg img.cover { width: 100%; height: 100%; object-fit: cover; }
.logo-wrap { text-align: center; margin-top: -65px; position: relative; z-index: 10; }
.logo-img {
width: 110px; height: 110px; border-radius: 50%; border: 4px solid white;
background: white; object-fit: cover; box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.info-area { text-align: center; margin-top: 15px; padding: 0 20px; }
.info-area h1 { margin: 0; font-size: 24px; color: #333; font-weight: bold; }
.info-area p { margin: 5px 0 0; color: #0097b2; font-size: 16px; font-weight: 600; }
.install-box { text-align: center; margin: 25px 0; display: flex; justify-content: center; }
#installBtn {
background: #1a1a1a;
color: white !important;
border: none;
padding: 14px 35px;
border-radius: 50px;
font-weight: bold;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
text-transform: uppercase;
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
text-decoration: none;
}
.list { padding: 0 25px; }
.item { display: flex; align-items: center; gap: 18px; padding: 16px 0; border-bottom: 1px solid #f4f4f4; text-decoration: none; color: inherit; }
.item i { font-size: 20px; width: 30px; text-align: center; color: #555; }
.label { font-size: 11px; font-weight: bold; color: #0097b2; text-transform: uppercase; display: block; margin-bottom: 2px; }
.val { font-size: 15px; color: #333; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn-extra {
background: #0097b2; margin-top: 15px; padding: 18px !important; border-radius: 12px;
border-bottom: none !important; box-shadow: 0 4px 10px rgba(0, 151, 178, 0.2);
}
.btn-extra i { color: white !important; }
.btn-extra .label { color: rgba(255,255,255,0.8) !important; }
.btn-extra .val { color: white !important; font-weight: bold; }
.footer {
position: fixed; bottom: 0; width: 100%; max-width: 500px;
display: grid; grid-template-columns: repeat(3, 1fr);
gap: 8px; padding: 12px; background: white;
border-top: 1px solid #eee; box-sizing: border-box; z-index: 999;
}
.f-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 12px 0; border-radius: 10px; color: white; text-decoration: none; font-size: 10px; font-weight: bold; gap: 4px; }
.bg-green { background: #38a14d; } .bg-grey { background: #444444; } .bg-blue { background: #1a89ff; }
</style>
</head>
<body>
<div class="container">
<div class="header-bg">
<?php if(!empty($c['copertina'])): ?>
<img src="data:image/jpeg;base64,<?= base64_encode($c['copertina']) ?>" class="cover">
<?php endif; ?>
</div>
<div class="logo-wrap">
<img src="<?= $c['foto'] ? 'data:image/jpeg;base64,'.base64_encode($c['foto']) : 'https://via.placeholder.com/150' ?>" class="logo-img">
</div>
<div class="info-area">
<h1><?= htmlspecialchars($c['nome'] . ' ' . $c['cognome']) ?></h1>
<p><?= htmlspecialchars($c['azienda']) ?></p>
</div>
<div class="install-box">
<button id="installBtn"><i class="fa fa-download"></i> SALVA APPLICAZIONE</button>
</div>
<div class="list">
<a href="tel:<?= $tel_clean ?>" class="item">
<i class="fa fa-phone"></i>
<div><span class="label">CELLULARE</span><span class="val"><?= htmlspecialchars($c['cellulare'] ?: '-') ?></span></div>
</a>
<?php if(!empty($c['telefono'])): ?>
<a href="tel:<?= $fisso_clean ?>" class="item">
<i class="fa fa-phone-flip"></i>
<div><span class="label">TELEFONO FISSO</span><span class="val"><?= htmlspecialchars($c['telefono']) ?></span></div>
</a>
<?php endif; ?>
<a href="mailto:<?= htmlspecialchars($c['email']) ?>" class="item">
<i class="fa fa-envelope"></i>
<div><span class="label">EMAIL</span><span class="val"><?= htmlspecialchars($c['email'] ?: '-') ?></span></div>
</a>
<?php if(!empty($c['link_wa'])): ?>
<a href="https://wa.me/<?= preg_replace('/[^0-9]/', '', $c['link_wa']) ?>" target="_blank" class="item">
<i class="fab fa-whatsapp" style="color: #25D366;"></i>
<div><span class="label">WHATSAPP</span><span class="val"><?= htmlspecialchars($c['nome_link2'] ?: 'Invia un messaggio') ?></span></div>
</a>
<?php endif; ?>
<?php if(!empty($c['link_sito'])): ?>
<a href="<?= htmlspecialchars($c['link_sito']) ?>" target="_blank" class="item">
<i class="fa fa-globe"></i>
<div><span class="label">SITO WEB</span><span class="val link"><?= htmlspecialchars($c['nome_link1'] ?: 'Visita il sito') ?></span></div>
</a>
<?php endif; ?>
<?php if(!empty($c['link_extra'])): ?>
<a href="<?= (strpos($c['link_extra'], 'http') === 0) ? $c['link_extra'] : 'https://'.$c['link_extra'] ?>" target="_blank" class="item btn-extra">
<i class="fa fa-link"></i>
<div><span class="label">LINK EXTRA</span><span class="val"><?= htmlspecialchars($c['nome_link3'] ?: 'Scopri di più') ?></span></div>
</a>
<?php endif; ?>
<?php if(!empty($c['indirizzo'])): ?>
<div class="item">
<i class="fa fa-location-dot" style="color: #e74c3c;"></i>
<div>
<span class="label">SEDE</span>
<span class="val" style="white-space: normal;"><?= htmlspecialchars($c['indirizzo'] . ", " . $c['citta']) ?></span>
<a href="<?= $mappa_url ?>" target="_blank" style="color:#007bff; font-weight:bold; text-decoration:none; font-size:14px; display:block; margin-top:5px;">Apri Navigatore ?</a>
</div>
</div>
<?php endif; ?>
</div>
<div class="footer">
<a href="tel:<?= $tel_clean ?>" class="f-btn bg-green"><i class="fa fa-phone"></i> CHIAMATA</a>
<a href="tel:<?= $fisso_clean ?>" class="f-btn bg-grey"><i class="fa fa-phone-flip"></i> FISSO</a>
<a href="vcf.php?code=<?= urlencode($code) ?>" class="f-btn bg-blue"><i class="fa fa-save"></i> RUBRICA</a>
</div>
</div>
<script>
let deferredPrompt;
const installBtn = document.getElementById('installBtn');
if ('serviceWorker' in navigator) {
// Registrazione senza parametri extra per non andare in conflitto con lo scope del manifest
navigator.serviceWorker.register('sw.js');
}
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
});
installBtn.addEventListener('click', async () => {
if (deferredPrompt) {
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
if (outcome === 'accepted') deferredPrompt = null;
} else {
alert("Per installare questa specifica App:\n\nAndroid: 3 puntini -> 'Installa app'.\n\niPhone: Condividi -> 'Aggiungi a Home'.");
}
});
</script>
</body>
</html>
sw.js
self.addEventListener('install', (event) => {
self.skipWaiting();
});
self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim());
});
self.addEventListener('fetch', (event) => {
// Risposta diretta senza cache per evitare conflitti su localhost
event.respondWith(fetch(event.request));
});
il file manifest.php
<?php
header("Content-Type: application/manifest+json; charset=utf-8");
require_once 'config.php';
$code = $_GET['code'] ?? '';
$stmt = $pdo->prepare("SELECT * FROM contatti WHERE codice_segreto = ?");
$stmt->execute([$code]);
$c = $stmt->fetch();
if (!$c) exit;
$nome_pwa = !empty($c['azienda']) ? $c['azienda'] : ($c['nome'] . " " . $c['cognome']);
$manifest = [
"name" => $nome_pwa,
"short_name" => mb_strimwidth($nome_pwa, 0, 12, ""),
// 1. ID UNICO: Impedisce la sovrascrittura
"id" => "/vcf/view.php?code=" . $code,
// 2. START_URL: Deve essere identico all'URL che visiti
"start_url" => "/vcf/view.php?code=" . $code,
// 3. SCOPE: Fondamentale! Isola l'app in questa "sotto-pagina"
"scope" => "/vcf/view.php?code=" . $code,
"display" => "standalone",
"background_color" => "#ffffff",
"theme_color" => "#0097b2",
"icons" => [
[
"src" => "get_logo.php?id=" . $c['id'],
"sizes" => "512x512",
"type" => "image/png"
]
]
];
echo json_encode($manifest, JSON_UNESCAPED_SLASHES);
ho questi tre file voglio che mi faccia l'istallazione sepdarata dei vari utenti ( che sono inseriti in un database mysql)
ma non riesco a farla
quacuno sa dirmi come fare?
grazie