<!DOCTYPE html>
<html lang=”it”>
<head>
<meta charset=”UTF-8″>
<title>Test Ricerca Vocale – Sassaricome</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, “Segoe UI”, sans-serif;
background: #f3f4f6;
margin: 0;
padding: 20px;
}
h1 {
text-align: center;
font-weight: 600;
margin-bottom: 10px;
}
p#status {
text-align: center;
font-size: 14px;
color: #555;
min-height: 20px;
}
.search-container {
display: flex;
align-items: center;
background: #ffffff;
border-radius: 12px;
padding: 10px 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
max-width: 500px;
margin: 20px auto;
}
#searchInput {
flex: 1;
border: none;
outline: none;
font-size: 18px;
}
.mic-btn {
background: #0078ff;
color: white;
border: none;
padding: 10px 14px;
border-radius: 50%;
cursor: pointer;
font-size: 18px;
transition: 0.2s;
}
.mic-btn:active {
transform: scale(0.9);
}
.wave {
width: 100%;
height: 4px;
background: linear-gradient(90deg, #0078ff, #00c6ff);
animation: waveMove 1s infinite linear;
margin: 10px auto 0;
max-width: 500px;
}
.hidden {
display: none;
}
@keyframes waveMove {
0% { background-position: 0 0; }
100% { background-position: 200px 0; }
}
.results {
max-width: 500px;
margin: 20px auto;
background: #ffffff;
border-radius: 12px;
padding: 10px 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
}
.result-item {
padding: 8px 0;
border-bottom: 1px solid #eee;
}
.result-item:last-child {
border-bottom: none;
}
.result-name {
font-weight: 600;
}
.result-type {
font-size: 13px;
color: #777;
}
</style>
</head>
<body>
<h1>Ricerca vocale – Demo Sassaricome</h1>
<p id=”status”></p>
<div class=”search-container”>
<input type=”text” id=”searchInput” placeholder=”Cerca attività, servizi…”>
<button id=”voiceBtn” class=”mic-btn”>🎤</button>
</div>
<div id=”voiceWave” class=”wave hidden”></div>
<div class=”results” id=”results”></div>
<script>
// — DATI DI PROVA (simulano il tuo motore di ricerca interno) —
const ATTIVITA = [
{ nome: “Studio Legale Rossi”, tipo: “Avvocato”, zona: “Centro” },
{ nome: “Farmacia Centrale”, tipo: “Farmacia”, zona: “Centro” },
{ nome: “Studio Medico Bianchi”, tipo: “Medico di base”, zona: “Latte Dolce” },
{ nome: “Bar Caffè Italia”, tipo: “Bar”, zona: “Emiciclo Garibaldi” },
{ nome: “Pizzeria Da Marco”, tipo: “Ristorazione”, zona: “Luna e Sole” },
{ nome: “Studio Tecnico Pinna”, tipo: “Geometra”, zona: “Monte Rosello” },
{ nome: “Parrucchiere Glamour”, tipo: “Parrucchiere”, zona: “Centro” }
];
const statusEl = document.getElementById(“status”);
const btn = document.getElementById(“voiceBtn”);
const input = document.getElementById(“searchInput”);
const wave = document.getElementById(“voiceWave”);
const resultsEl = document.getElementById(“results”);
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
// — MOTORE DI RICERCA INTERNO (demo) —
function avviaRicerca(query) {
const q = query.trim().toLowerCase();
if (!q) {
resultsEl.innerHTML = “<p>Nessun termine di ricerca.</p>”;
return;
}
const filtrati = ATTIVITA.filter(item =>
item.nome.toLowerCase().includes(q) ||
item.tipo.toLowerCase().includes(q) ||
item.zona.toLowerCase().includes(q)
);
if (filtrati.length === 0) {
resultsEl.innerHTML = “<p>Nessun risultato trovato.</p>”;
return;
}
resultsEl.innerHTML = filtrati.map(item => `
<div class=”result-item”>
<div class=”result-name”>${item.nome}</div>
<div class=”result-type”>${item.tipo} – Zona: ${item.zona}</div>
</div>
`).join(“”);
}
// Avvia ricerca anche quando l’utente scrive e preme Invio
input.addEventListener(“keydown”, (e) => {
if (e.key === “Enter”) {
avviaRicerca(input.value);
}
});
// — RICERCA VOCALE PREMIUM CON FALLBACK —
btn.addEventListener(“click”, async () => {
// HTTPS consigliato per mobile
if (location.protocol !== “https:”) {
statusEl.textContent = “Sugli smartphone la ricerca vocale richiede HTTPS.”;
// Per test locale puoi comunque provare da file, ma su mobile può non funzionare
}
// Richiesta permesso microfono
try {
await navigator.mediaDevices.getUserMedia({ audio: true });
} catch (err) {
statusEl.textContent = “Per usare la ricerca vocale, attiva il microfono nelle impostazioni del browser.”;
return;
}
// Fallback se il browser non supporta la Web Speech API
if (!SpeechRecognition) {
statusEl.textContent = “Il tuo dispositivo non supporta la ricerca vocale.”;
return;
}
const recognition = new SpeechRecognition();
recognition.lang = “it-IT”;
recognition.interimResults = false;
recognition.maxAlternatives = 1;
statusEl.textContent = “Ascolto…”;
wave.classList.remove(“hidden”);
recognition.start();
recognition.onresult = (event) => {
const testo = event.results[0][0].transcript;
input.value = testo;
statusEl.textContent = “Hai detto: ” + testo;
// Collegato al “motore interno”
avviaRicerca(testo);
};
recognition.onerror = (event) => {
statusEl.textContent = “Errore: ” + event.error;
};
recognition.onend = () => {
wave.classList.add(“hidden”);
};
});
</script>
</body>
</html>