fix(places): hours can be typed, and an edited place takes over the looked-up hours; quota as a badge

This commit is contained in:
Maurice
2026-10-01 15:18:30 +02:00
parent 647bb33565
commit 39074f6d46
34 changed files with 217 additions and 29 deletions
@@ -5,8 +5,8 @@ import { useGoogleQuota } from './useGoogleQuota'
/**
* The daily ceiling on Google calls (#1582), as one row of the Google options:
* the number on the right with today's count under it, a save button only while
* there is something to save, and a warning once the day is used up.
* today's count as a badge beside the name, the number on the right, a save
* button only while there is something to save.
*/
export default function GoogleDailyLimitRow() {
const { t } = useTranslation()
@@ -15,10 +15,28 @@ export default function GoogleDailyLimitRow() {
return (
<div className="flex flex-wrap items-start justify-between gap-x-4 gap-y-2 py-3">
<div className="min-w-0 flex-1 basis-60">
<label htmlFor="admin-google-daily-limit" className="text-sm font-medium text-content-secondary">{t('admin.googleQuota.title')}</label>
<div className="flex flex-wrap items-center gap-2">
<label htmlFor="admin-google-daily-limit" className="text-sm font-medium text-content-secondary">{t('admin.googleQuota.title')}</label>
{/* Today's count beside the name it belongs to: green while there is room, amber once the day is used up. */}
{status && (
status.exhausted ? (
<span className="inline-flex items-center gap-1 rounded-full bg-warning-soft px-2 py-[2px] text-caption font-semibold tabular-nums text-warning">
<AlertTriangle size={11} strokeWidth={2.4} />
{t('admin.googleQuota.reached', { used: status.used_today })}
</span>
) : (
<span className="inline-flex items-center gap-1.5 rounded-full border border-edge-faint bg-surface-secondary px-2 py-[2px] text-caption font-semibold tabular-nums text-content-secondary">
<span aria-hidden className="h-1.5 w-1.5 rounded-full bg-success" />
{status.daily_limit == null
? t('admin.googleQuota.usedToday', { used: status.used_today })
: t('admin.googleQuota.usedOfLimit', { used: status.used_today, limit: status.daily_limit })}
</span>
)
)}
</div>
<p className="text-xs text-content-faint mt-0.5">{t('admin.googleQuota.subtitle')}</p>
</div>
<div className="flex flex-col items-end gap-1.5">
<div className="flex flex-col items-end">
<div className="flex items-center gap-2">
<NumericInput
id="admin-google-daily-limit"
@@ -38,20 +56,6 @@ export default function GoogleDailyLimitRow() {
</button>
)}
</div>
{status && (
status.exhausted ? (
<span className="inline-flex items-center gap-1.5 rounded-full bg-warning-soft px-2.5 py-0.5 text-xs font-medium text-warning">
<AlertTriangle size={12} />
{t('admin.googleQuota.reached', { used: status.used_today })}
</span>
) : (
<span className="inline-flex items-center rounded-full bg-surface-tertiary px-2.5 py-0.5 text-xs font-medium tabular-nums text-content-muted">
{status.daily_limit == null
? t('admin.googleQuota.usedToday', { used: status.used_today })
: t('admin.googleQuota.usedOfLimit', { used: status.used_today, limit: status.daily_limit })}
</span>
)
)}
</div>
</div>
)