Oggetti artigianali fatti con passione

Scopri pezzi unici realizzati a mano da artigiani locali.

Acquista ora

Prodotti in evidenza

Pezzi selezionati a mano
Vedi tutto

Chi siamo

Benvenuti nel nostro piccolo mondo. Dietro ogni oggetto che vedete su questo sito non c’è una catena di montaggio, ma un tavolo di legno, il profumo delle materie prime e il calore di una famiglia che lavora insieme.

La nostra avventura nasce tra le mura di casa, dalla voglia di riscoprire il valore del 'fatto piano' e del 'fatto bene'. Ogni pezzo è unico, non solo perché creato artigianalmente, ma perché porta con sé il carattere di chi lo ha realizzato: la precisione, la creatività e la dedizione che solo una famiglia unita sa mettere in un progetto comune. Scegliere un nostro prodotto significa portare a casa un pezzetto della nostra storia.

Contattaci
artigianato
const PRODUCTS_URL = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?tqx=out:csv&sheet=inventario`; function createProductCard(p){ const col = document.createElement('div'); col.className = 'col-12 col-sm-6 col-md-4'; const card = document.createElement('div'); card.className = 'card h-100 shadow-sm'; const key = (p.titolo || p.title || '').trim() || 'prodotto'; // image wrapped in link to product detail const aImg = document.createElement('a'); aImg.href = `prodotto.html?key=${encodeURIComponent(key)}`; const img = document.createElement('img'); img.className = 'card-img-top product-img'; img.alt = p.image || p.titolo || 'prodotto'; img.src = p.image || 'media/product1.svg'; img.referrerPolicy = 'no-referrer'; // Risolve il blocco di Google Drive img.onerror = function(){ this.src = 'media/product1.svg'; }; // Fallback se l'immagine non carica // galleria on-hover: se ci sono più immagini, scorre al passaggio del mouse if(p.images && Array.isArray(p.images) && p.images.length > 1){ let idx = 0; let intervalId = null; const cycle = () => { idx = (idx + 1) % p.images.length; try{ img.src = p.images[idx]; }catch(e){} }; aImg.addEventListener('mouseenter', ()=>{ if(intervalId) return; intervalId = setInterval(cycle, 800); }); aImg.addEventListener('mouseleave', ()=>{ if(intervalId){ clearInterval(intervalId); intervalId = null; } idx = 0; img.src = p.images[0] || (p.image || 'media/product1.svg'); }); } aImg.appendChild(img); const body = document.createElement('div'); body.className = 'card-body d-flex flex-column'; const titleLink = document.createElement('a'); titleLink.href = `prodotto.html?key=${encodeURIComponent(key)}`; const title = document.createElement('h5'); title.className = 'card-title'; title.innerHTML = key; titleLink.appendChild(title); const desc = document.createElement('p'); desc.className = 'card-text text-muted mb-2'; desc.textContent = p.specifica || ''; const bottom = document.createElement('div'); bottom.className = 'mt-auto d-flex justify-content-between align-items-center'; const price = document.createElement('strong'); price.className = 'text-primary'; price.textContent = p.prezzo ? `CHF ${p.prezzo}` : (p.price ? `CHF ${p.price}` : 'CHF --'); const btn = document.createElement('a'); btn.className = 'btn btn-sm btn-outline-primary'; btn.href = '#'; btn.textContent = 'Aggiungi'; btn.addEventListener('click', (e)=>{ e.preventDefault(); addToCart(p); }); bottom.appendChild(price); bottom.appendChild(btn); body.appendChild(titleLink); body.appendChild(desc); body.appendChild(bottom); card.appendChild(aImg); card.appendChild(body); col.appendChild(card); return col; } // Funzioni carrello (localStorage) function addToCart(item){ try{ const cart = JSON.parse(localStorage.getItem('cart') || '[]'); const key = (item.titolo || item.title || '').trim(); if(!key){ console.warn('Prodotto senza titolo, non aggiunto.'); return; } const prezzo = parseFloat(item.prezzo || item.price || 0) || 0; const existing = cart.find(i => i.key === key); if(existing){ existing.qty = (existing.qty || 1) + 1; } else { cart.push({ key, titolo: key, descrizione: item.descrizione || item.desc || item.description || '', specifica: item.specifica || item.category || '', prezzo: prezzo, image: item.image || 'media/product1.svg', qty: 1 }); } localStorage.setItem('cart', JSON.stringify(cart)); updateCartCount(); // Dialog personalizzato con due pulsanti const dialogOverlay = document.createElement('div'); dialogOverlay.style.position = 'fixed'; dialogOverlay.style.top = '0'; dialogOverlay.style.left = '0'; dialogOverlay.style.width = '100%'; dialogOverlay.style.height = '100%'; dialogOverlay.style.backgroundColor = 'rgba(0,0,0,0.5)'; dialogOverlay.style.display = 'flex'; dialogOverlay.style.alignItems = 'center'; dialogOverlay.style.justifyContent = 'center'; dialogOverlay.style.zIndex = '2000'; const dialog = document.createElement('div'); dialog.className = 'bg-white rounded shadow-lg'; dialog.style.padding = '2rem'; dialog.style.maxWidth = '400px'; dialog.style.textAlign = 'center'; dialog.innerHTML = `
✓ Prodotto aggiunto

${key} è stato aggiunto al carrello!

`; dialogOverlay.appendChild(dialog); document.body.appendChild(dialogOverlay); dialog.querySelector('.continua-btn').addEventListener('click', ()=>{ dialogOverlay.remove(); }); dialog.querySelector('.carrello-btn').addEventListener('click', ()=>{ window.location.href = 'carrello.html'; }); }catch(err){ console.error(err); } } function updateCartCount(){ try{ const cart = JSON.parse(localStorage.getItem('cart') || '[]'); const count = cart.reduce((s,i)=> s + (Number(i.qty)||0), 0); const el = document.getElementById('cartCount'); if(el) el.textContent = count; }catch(e){ console.error(e); } } function renderProducts(items){ const row = document.getElementById('productsRow'); row.innerHTML = ''; if(!items || items.length===0){ row.innerHTML = '

Nessun prodotto disponibile. Assicurati che il foglio Google sia pubblicato e che il foglio (tab) si chiami "inventario".

'; return; } items.forEach(p=>{ row.appendChild(createProductCard(p)); }); } async function loadProducts(){ try{ if(SHEET_ID === 'INSERISCI_IL_TUO_ID_QUI') { document.getElementById('productsRow').innerHTML = '
Attenzione: Devi inserire l\'ID del tuo Google Sheet nel codice (variabile SHEET_ID).
'; return; } const res = await fetch(PRODUCTS_URL); if(!res.ok) throw new Error('Errore nel caricamento del foglio Google'); const text = await res.text(); const workbook = XLSX.read(text, { type: 'string' }); // Con il formato CSV, otteniamo un solo foglio (quello richiesto nell'URL) const ws = workbook.Sheets[workbook.SheetNames[0]]; if(!ws) return renderProducts([]); const raw = XLSX.utils.sheet_to_json(ws, { defval: '' }); // Helper per convertire link Google Drive in link diretti const fixUrl = (url) => { if(!url) return ''; let u = String(url).trim(); if(u.includes('drive.google.com') && u.includes('/d/')){ const match = u.match(/\/d\/([a-zA-Z0-9_-]+)/); if(match && match[1]) return `https://drive.google.com/thumbnail?id=${match[1]}&sz=w1000`; } // Supporto per link formato "open?id=" if(u.includes('drive.google.com') && u.includes('id=')){ const match = u.match(/id=([a-zA-Z0-9_-]+)/); if(match && match[1]) return `https://drive.google.com/thumbnail?id=${match[1]}&sz=w1000`; } return u; }; // mappa le intestazioni a chiavi canoniche: titolo, descrizione, prezzo, image function mapRow(row){ const obj = {}; // normalizza input keys Object.keys(row).forEach(k => { obj[k.toLowerCase().trim().replace(/\s+/g,'_')] = row[k]; }); const out = {}; out.titolo = obj.titolo || obj.title || obj.nome || obj.name || obj.product || obj['product_name'] || ''; out.descrizione = obj.descrizione || obj.description || obj.desc || obj.note || ''; out.prezzo = obj.prezzo || obj.price || obj.prezzo_chf || obj.prezzo_sfr || obj['prezzo(chf)'] || ''; out.specifica = obj.specifica || obj.category || obj.tipo || ''; // Raccogli immagini: campo 'image' (comma-separated) e colonne image1..image10, foto, immagine const images = []; const pushIf = v => { if(v || v === 0) { const s = String(v).trim(); if(s) images.push(s); } }; if(obj.image){ String(obj.image).split(/[,;]+/).map(s=>s.trim()).forEach(s=>{ if(s) images.push(s); }); } if(obj.images){ String(obj.images).split(/[,;]+/).map(s=>s.trim()).forEach(s=>{ if(s) images.push(s); }); } if(obj.foto) pushIf(obj.foto); if(obj.immagine) pushIf(obj.immagine); for(let i=1;i<=10;i++){ if(obj['image'+i]) pushIf(obj['image'+i]); else if(obj['image_'+i]) pushIf(obj['image_'+i]); // Supporta "Image 1" -> "image_1" } out.images = images.map(s=>fixUrl(s)).filter(Boolean); out.image = out.images.length > 0 ? out.images[0] : fixUrl(obj.image || obj.images || ''); return out; } const data = raw.map(mapRow); renderProducts(data); }catch(err){ console.error('Errore caricamento prodotti (Google Sheet):', err); // Mostra l'errore specifico a video invece del messaggio generico const row = document.getElementById('productsRow'); row.innerHTML = `
Errore caricamento: ${err.message}.
Verifica che il foglio Google sia condiviso con "Chiunque abbia il link" (Visualizzatore).
`; } } // Avvia il caricamento quando la pagina è pronta document.addEventListener('DOMContentLoaded', ()=>{ loadProducts(); updateCartCount(); });