119 lines
5.3 KiB
TypeScript
119 lines
5.3 KiB
TypeScript
import { usageValue, type SearchUsageReport } from '@/lib/product-usage';
|
|
import { card } from '@/pages/investment/shared';
|
|
|
|
export default function SearchUsage({ search }: { search: SearchUsageReport }) {
|
|
return (
|
|
<section
|
|
className={card + ' space-y-3'}
|
|
aria-labelledby="search-usage-title"
|
|
>
|
|
<h2 id="search-usage-title" className="text-xl font-semibold">
|
|
Pesquisas — respostas registadas
|
|
</h2>
|
|
<p>
|
|
Uma resposta HTTP de primeira página com critérios explícitos é
|
|
a unidade desta medição. Repetições e actualizações contam
|
|
novamente; pessoas, bots e pesquisas únicas não são
|
|
identificados.
|
|
</p>
|
|
<p>
|
|
Edição: {search.definition_version}. Dias {search.from} a{' '}
|
|
{search.to}, em {search.timezone}. Leitura em {search.read_at}.
|
|
As contagens diárias usam o snapshot do relatório; o dia actual
|
|
é parcial e não há corte por fracção de segundo.
|
|
</p>
|
|
{!search.installed && (
|
|
<p role="status">
|
|
Ainda não há dados de recolha disponíveis neste destino.
|
|
</p>
|
|
)}
|
|
{!search.enabled_now && (
|
|
<p role="status">
|
|
A recolha está desligada neste momento. O histórico
|
|
registado mantém-se disponível.
|
|
</p>
|
|
)}
|
|
{!search.applicable && (
|
|
<p role="status">
|
|
Estas pesquisas públicas não têm associação comprovada ao
|
|
serviço do Balcão seleccionado. Os valores não são
|
|
calculados para esse filtro.
|
|
</p>
|
|
)}
|
|
{search.definition_conflict_now && (
|
|
<p role="status">
|
|
A definição desta edição foi preservada. Uma configuração
|
|
diferente com o mesmo identificador não acrescenta contagens
|
|
a esta série.
|
|
</p>
|
|
)}
|
|
<p>
|
|
Respostas: {usageValue(search.responses)}. Sem resultados
|
|
principais: {usageValue(search.zero_responses)}. Taxa entre
|
|
respostas registadas: {usageValue(search.zero_rate, '%')}.
|
|
</p>
|
|
<p>
|
|
Cobertura parcial: falhas de recolha podem deixar respostas por
|
|
contar. Sem registos de medição não significa zero pesquisas.
|
|
</p>
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-left">
|
|
<caption className="text-left font-semibold">
|
|
Canais públicos instrumentados nesta edição
|
|
</caption>
|
|
<thead>
|
|
<tr>
|
|
<th className="p-2">Canal</th>
|
|
<th className="p-2">Respostas</th>
|
|
<th className="p-2">Sem resultados principais</th>
|
|
<th className="p-2">Taxa na base registada</th>
|
|
<th className="p-2">
|
|
Primeira / última observação no período
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{search.channels.map((channel) => (
|
|
<tr className="border-t align-top" key={channel.id}>
|
|
<th scope="row" className="p-2">
|
|
{channel.label}
|
|
</th>
|
|
<td className="p-2">
|
|
{usageValue(channel.responses)}
|
|
</td>
|
|
<td className="p-2">
|
|
{usageValue(channel.zero_responses)}
|
|
</td>
|
|
<td className="p-2">
|
|
{usageValue(channel.zero_rate, '%')}
|
|
</td>
|
|
<td className="p-2">
|
|
{channel.first_recorded_at ? (
|
|
<>
|
|
{channel.first_recorded_at}
|
|
<br />
|
|
{channel.last_recorded_at}
|
|
</>
|
|
) : (
|
|
'Sem registos'
|
|
)}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<details>
|
|
<summary className="cursor-pointer underline">
|
|
Âmbito, exclusões e interpretação
|
|
</summary>
|
|
<ul className="list-disc pl-5">
|
|
{[...search.limits, ...search.exclusions].map((text) => (
|
|
<li key={text}>{text}</li>
|
|
))}
|
|
</ul>
|
|
</details>
|
|
</section>
|
|
);
|
|
}
|