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