useOpeningHours
Works out from a weekly schedule whether the store is open right now and, when closed, when it opens next.
import { useOpeningHours, UseOpeningHoursResult } from '@salla.sa/twilight-theme-engine/hooks';In plain words
Give it the store's weekly hours, such as monday: ['09:00-17:00']. It tells you whether the store isOpen at this moment and, when it is closed, gives you a readable nextOpenFormatted such as "Sunday 9:00 AM" in the page language.
isEnabled is false when opening hours are switched off or missing, and then the store counts as open.
Signature
function useOpeningHours(settings?: OpeningHoursSettings): UseOpeningHoursResult
interface OpeningHoursSettings { // from @salla.sa/twilight-theme-engine/types
enabled?: boolean;
hours?: Record<string, string[]>; // monday … sunday
}
interface UseOpeningHoursResult {
isOpen: boolean;
isEnabled: boolean;
nextOpen: Date | null;
nextOpenFormatted: string; // '' when open or not configured
}Try it live
import { useOpeningHours } from '@salla.sa/twilight-theme-engine/hooks';
// Module scope keeps the object stable between renders.
const OPENING_HOURS = {
enabled: true,
hours: { sunday: ['09:00-17:00'], monday: ['09:00-17:00'] /* …every day */ },
};
export function OpenStatus() {
const { isOpen, isEnabled, nextOpenFormatted } = useOpeningHours(OPENING_HOURS);
if (!isEnabled) return null;
return <p>{isOpen ? 'Open now' : `Closed. Opens ${nextOpenFormatted}`}</p>;
}
Example
import { useOpeningHours } from '@salla.sa/twilight-theme-engine/hooks';
import { useStore } from '@salla.sa/twilight-theme-engine/hooks/useStore';
export function OpenStatus() {
const { settings } = useStore();
const { isOpen, isEnabled, nextOpenFormatted } = useOpeningHours(settings.opening_hours);
if (!isEnabled || isOpen) return null;
return <p className="store-closed">Closed now. Opens {nextOpenFormatted}</p>;
}
How it behaves
Ranges are
'HH:MM-HH:MM'or with AM/PM ('9:00 AM - 5:00 PM'). Day keys must be lowercase English day names.When closed, it looks for a later range today, then for the first range on each of the next 7 days. If none exists it reports open, with
isEnabled: true.Day names and AM/PM come from the translation keys
common.days.*andcommon.time.am/pm, joined as "<day> h:mm <AM|PM>".The result is memoised on
[settings, t]: keep the settings object stable (store settings are).The default
StoreClosedNotificationhandler onbody:startuses it.It has no subpath of its own: import it from
@salla.sa/twilight-theme-engine/hooks.
Gotchas
It uses the clock and time zone of wherever it runs: UTC on the server while it renders, the shopper's zone in the browser, and neither is necessarily the store's. The result can differ between the server HTML and hydration. Render it after mount (
useIsClient) when the difference matters.It does not tick. The status is computed when the component renders, so an open page does not flip at opening time until something re-renders it.
An overnight range such as
'22:00-02:00'is dropped (a range must start before it ends), and a time it cannot parse counts as midnight.opening_hoursis marked "TODO: add to API response" in theStoreSettingstype; this demo store does not send it today, so pass your own schedule if you need one.
Related
Registers the engine's built-in slot handlers (GTM, bundles, store closed, fast checkout, price quote, pre-order); importing the hooks module already runs it.
useIsClientReturns false while the page is rendered on the server and during hydration, then true once the component has mounted in the browser.