// results-widget.jsx — живой виджет результатов опроса
const MIN_RESULTS_TO_SHOW = 5;
function ResultsWidget({ visible }) {
if (!visible) return null;
const [data, setData] = React.useState(null);
const [error, setError] = React.useState(false);
const [refreshAt, setRefreshAt] = React.useState(Date.now());
React.useEffect(() => {
let alive = true;
fetch("/api/results.php")
.then(r => r.json())
.then(d => { if (alive && d && d.ok) setData(d); else if (alive) setError(true); })
.catch(() => { if (alive) setError(true); });
return () => { alive = false; };
}, [refreshAt]);
// Авто-обновление раз в 60 секунд (полезно во время защиты)
React.useEffect(() => {
const id = setInterval(() => setRefreshAt(Date.now()), 60_000);
return () => clearInterval(id);
}, []);
// Время последнего обновления — относительное
const updatedHuman = data?.updated ? humanizeTime(data.updated) : null;
const total = data?.count || 0;
const words = data?.top_words || [];
const choices = data?.choices || {};
const maxCount = words.length ? words[0].count : 1;
const choiceCards = [
{ id: "q1", title: "Покупали удобрения" },
{ id: "q2", title: "Траты за сезон" },
{ id: "q3", title: "Куда уходят очистки" },
{ id: "q4", title: "Где живут" }
].filter((card) => choices[card.id] && choices[card.id].length);
if (!error && data === null) return null;
if (!error && total < MIN_RESULTS_TO_SHOW) return null;
return (
Опрос идёт в открытом доступе. Здесь — счётчик ответов и самые
частые слова из открытых полей, агрегированные по всему массиву.
Виджет обновляется автоматически — раз в минуту.
Не удалось загрузить результаты. Это значит, что бэкенд недоступен —
или вы открыли локальную версию сайта. На ekokrug.ru виджет работает. Пока недостаточно ответов с открытым текстом, чтобы выделить
частые темы. Виджет автоматически наполнится по мере поступления.
Что отвечают
прямо сейчас