Composables
useOpenNow
Reactive composable + pure helper to determine if a restaurant is currently open, plus its closing time or next opening.
useOpenNow
Given a restaurant's hours data, returns whether it's currently open plus the closing time (if open) or the next opening time (if closed).
Supports both data shapes the layer encounters:
- Schema.org array (API responses):
[{ dayOfWeek: 'Monday', opens: '09:00', closes: '21:00' }, ...] - Plain object (mock data):
{ monday: '11:00 AM - 10:00 PM', tuesday: '11:00 AM - 10:00 PM', ... }
Usage
<script setup>
const props = defineProps<{ restaurant: any }>()
// Reactive — re-evaluates if the hours change
const { isOpen, status, closesAt, opensAt } = useOpenNow(
computed(() => props.restaurant.openingHours ?? props.restaurant.hours),
)
</script>
<template>
<UBadge :color="isOpen ? 'success' : 'neutral'">
{{ isOpen ? 'Open Now' : 'Closed' }}
</UBadge>
<span v-if="isOpen && closesAt">Open until {{ formatTime12h(closesAt) }}</span>
<span v-else-if="opensAt">Closed · Opens {{ formatTime12h(opensAt) }}</span>
</template>
Pure function form
For non-reactive contexts (filter callbacks, event handlers), use isOpenNow() directly:
import { isOpenNow } from '#imports' // or auto-imported in setup
const filtered = list.filter(r => isOpenNow(r.openingHours ?? r.hours).isOpen)
Returns
| Key | Type | Description |
|---|---|---|
isOpen | boolean | Whether the restaurant is currently open. false if hours data is missing or the restaurant is closed. |
status | 'open' | 'closed' | 'unknown' | 'open' if within hours, 'closed' if outside hours, 'unknown' if hours data is missing/invalid. |
closesAt | string | undefined | HH:MM (24h) when the restaurant closes today. Only set when status === 'open'. |
opensAt | string | undefined | HH:MM (24h) when the restaurant next opens. Only set when status === 'closed'. |
Notes
- Times are evaluated against the current local time (
new Date()). - The composable accepts a ref, computed, or plain value for
hours. - Crosses midnight correctly — a restaurant open until "23:00" is shown as closing at 23:00, not as "closed since 23:00".
AI Context
composable: useOpenNow
package: "@xenterprises/nuxt-x-restaurants"
use-when: >
Showing whether a restaurant is currently open. Two forms: useOpenNow(hours)
for reactive display in components (cards, hero, sidebar), and isOpenNow(hours)
as a pure helper for filtering lists. Handles both schema.org array format and
plain object format. Returns { isOpen, status, closesAt?, opensAt? }.
