fix: widget settings auto-save with debounce
This commit is contained in:
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user