// ─── Kundenbewertungen (AudioFlow review site → app) ──────────────────────
// Records match the review site's shape 1:1:
// { id, ts, ratings:{sound,condition,advice,handover,price,overall}, average, comment, lang }
// Stored in the app under 'rf-reviews'. The review site writes 'audioflow_reviews_v1';
// when both are served from the same origin we auto-merge those in by id.
const REVIEW_QIDS = ['sound', 'condition', 'advice', 'handover', 'price', 'overall'];
const REVIEW_TITLES = {
sound: 'Klangqualität',
condition: 'Zustand der Geräte',
advice: 'Kommunikation',
handover: 'Lieferung & Abholung',
price: 'Preis-Leistung',
overall: 'Gesamteindruck',
};
const REVIEW_SITE_KEY = 'audioflow_reviews_v1';
// Merge helper — dedupes by id, keeps chronological order.
function mergeReviews(a = [], b = []) {
const dismissed = loadDismissedReviews();
const map = new Map();
[...a, ...b].forEach((r) => { if (r && r.id != null && !dismissed.has(String(r.id))) map.set(String(r.id), r); });
return [...map.values()].sort((x, y) => (x.ts || 0) - (y.ts || 0));
}
// Pull whatever the review site left in this browser (same-origin case).
function loadSiteReviews() {
try { const raw = localStorage.getItem(REVIEW_SITE_KEY); return raw ? JSON.parse(raw) : []; }
catch (e) { return []; }
}
// Permanently dismissed review ids — deleted reviews must never reappear on import/auto-merge.
// Server-gespeichert (RFDB), damit ein Löschen auf einem Gerät auf allen Geräten gilt.
const REVIEW_DISMISSED_KEY = 'rf-reviews-dismissed';
function loadDismissedReviews() {
const v = window.RFDB ? window.RFDB.get(REVIEW_DISMISSED_KEY) : undefined;
return new Set(Array.isArray(v) ? v : []);
}
function addDismissedReview(id) {
const s = loadDismissedReviews(); s.add(String(id));
if (window.RFDB) window.RFDB.set(REVIEW_DISMISSED_KEY, [...s]).catch(() => {});
}
function reviewStars(n) {
// returns 5 booleans for filled stars given a 0..5 value (rounded)
const r = Math.round(n);
return [1, 2, 3, 4, 5].map((i) => i <= r);
}
function StarRow({ value, size = 16 }) {
return (
{reviewStars(value).map((on, i) => (
))}
);
}
// ─── Overview card for the home tab ───────────────────────────────────────
function ReviewsCard({ reviews = [], onOpen }) {
const t = useTheme();
const count = reviews.length;
const avg = count ? reviews.reduce((a, r) => a + (Number(r.average) || 0), 0) / count : 0;
const fmt = (n) => (Math.round(n * 10) / 10).toFixed(1).replace('.', ',');
return (
Die Bewertungsseite speichert jede Bewertung. Läuft sie auf derselben Domain wie diese App, werden neue Bewertungen automatisch übernommen — sonst per JSON-Export/-Import oder über eine zentrale Datenbank-Anbindung.