fix: widget settings auto-save with debounce

This commit is contained in:
2026-04-07 22:25:00 +03:00
parent 99274dfa04
commit 643774ce0a

View File

@@ -1121,6 +1121,7 @@ export function BookingWidgetPage() {
allowExtraBeds: hs.widget_extra_beds !== undefined ? Boolean(hs.widget_extra_beds) : prev.allowExtraBeds,
allowChildren: hs.widget_children !== undefined ? Boolean(hs.widget_children) : prev.allowChildren,
}))
setSettingsReady(true)
}).finally(() => setGatewayLoading(false))
}, [slug])
@@ -1142,6 +1143,7 @@ export function BookingWidgetPage() {
const [copied, setCopied] = useState(false)
const [saving, setSaving] = useState(false)
const [saved, setSaved] = useState(false)
const [settingsReady, setSettingsReady] = useState(false)
const [pageTab, setPageTab] = useState<'constructor' | 'code' | 'stats'>('constructor')
const [newFieldLabel, setNewFieldLabel] = useState('')
const [showAddField, setShowAddField] = useState(false)
@@ -1149,21 +1151,21 @@ export function BookingWidgetPage() {
const set = <K extends keyof WidgetSettings>(k: K, v: WidgetSettings[K]) =>
setSettings(prev => ({ ...prev, [k]: v }))
const handleSaveSettings = async () => {
const doSave = async (s: WidgetSettings) => {
if (!slug) return
setSaving(true)
try {
await api.hotelSettings.update(slug, {
widget_hotel_name: settings.hotelName,
widget_color: settings.primaryColor,
widget_lang: settings.language,
widget_show_rooms: settings.showRooms,
widget_show_rental: settings.showRental,
widget_room_mode: settings.roomDisplayMode,
widget_min_nights: settings.minNights,
widget_show_promo: settings.showPromo,
widget_extra_beds: settings.allowExtraBeds,
widget_children: settings.allowChildren,
widget_hotel_name: s.hotelName,
widget_color: s.primaryColor,
widget_lang: s.language,
widget_show_rooms: s.showRooms,
widget_show_rental: s.showRental,
widget_room_mode: s.roomDisplayMode,
widget_min_nights: s.minNights,
widget_show_promo: s.showPromo,
widget_extra_beds: s.allowExtraBeds,
widget_children: s.allowChildren,
})
setSaved(true)
setTimeout(() => setSaved(false), 2000)
@@ -1171,6 +1173,15 @@ export function BookingWidgetPage() {
finally { setSaving(false) }
}
const handleSaveSettings = () => doSave(settings)
// Auto-save 1.5s after any settings change (only after initial load)
useEffect(() => {
if (!settingsReady) return
const t = setTimeout(() => doSave(settings), 1500)
return () => clearTimeout(t)
}, [settings, settingsReady])
const toggleService = (id: string) =>
setSettings(prev => ({
...prev,
@@ -1502,9 +1513,10 @@ export function BookingWidgetPage() {
className="btn-primary flex items-center gap-2"
>
{saving ? <Loader2 size={15} className="animate-spin" /> : <Save size={15} />}
{saved ? 'Сохранено!' : 'Сохранить настройки'}
Сохранить
</button>
{saved && <span className="text-sm text-emerald-600 dark:text-emerald-400">Настройки виджета сохранены</span>}
{saving && <span className="text-sm text-slate-400">Сохранение...</span>}
{saved && !saving && <span className="text-sm text-emerald-600 dark:text-emerald-400"> Сохранено</span>}
</div>
</div>