Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Business Hours Laravel Package

laboiteacode/filament-business-hours

Filament field for managing business opening hours on a drag-and-drop weekly 24-hour grid, with exceptional closures, special hours, vacation periods, and timezones. Stores data natively in spatie/opening-hours format.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Data-model / build-vs-buy for "opening hours": the package forces the decision that hours live as a plain spatie/opening-hours definition (weekly map + exceptions + overflow + timezone) in one JSON row. That is the same artefact the app queries with OpeningHours::create(), so it is a reversible, low-lock-in choice — a real architectural decision point, not just a UI purchase.
  • Skip building an admin schedule editor: drag-to-create/resize ranges, snap steps, inline minute-level editor, copy/clear-day, first-day-of-week, exceptional dates with optional yearly repeat, vacation ranges, IANA timezone picker. This is a multi-day-to-multi-week build for any team; here it's composer require plus one migration and a plugin registration.
  • Storefront / consumer-facing roadmap enablers: "Open now / closes at 18:00" badges, next-open/next-close copy, "closed for Christmas" banners, vacation notices — all served by isOpenAt, nextOpen, nextClose, exceptionalClosingDates().
  • Commerce and fulfilment scope: pickup/delivery availability windows, cut-off messaging, store-hours gating on checkout or slot selection — where the product needs a queryable definition rather than human-readable text.
  • Multi-location / multi-brand decisions: ->record('shop-paris') gives one hours set per key, and multiple panels can each manage a different row. Supports a "one page per location" or "one page per brand" model without schema changes.
  • Seeders, imports, and service-to-service writes: because columns are in spatie shape, hours can be created from code or read by another service without going through the UI — useful when onboarding locations from a spreadsheet or syncing from a PIM/migration.
  • Explicit non-goals the team gets to keep off the roadmap: no bookings, no capacity, no per-staff or per-service availability, no slot inventory. This keeps "business hours" a display/config concern and prevents scope creep into a scheduling engine.
  • Authorization and governance decisions: a single canAccess() hook / Gate ability drives both nav item and route — supports the "who is allowed to change that we're closed?" question (ops manager vs. any panel user).
  • Roadmap framing choice you will have to make: whether hours are presentation (badges, copy) or policy (checkout gating, SLA clocks). The former is a cheap win; the latter means the record becomes a critical path and deserves a wrapper service, caching and tests.

When to Consider This Package

Consider it when all of these hold:

  • You already run a Filament 4/5 admin panel (this is the hard gate — it provides zero value outside Filament).
  • Laravel 12/13, PHP 8.2+ — note the narrow support matrix; older Laravel/Filament apps are excluded.
  • Business hours are weekly-recurring plus exceptions (holidays, one-off special hours, vacation ranges) — the 80% case for retail, restaurants, clinics, showrooms, offices.
  • One to a modest number of hours sets (a handful of locations/brands) that a human edits occasionally. This is not a high-write or high-cardinality scheduling system.
  • You are willing to adopt spatie/opening-hours as the query layer, or already use it. If you need a different query semantic (per-service hours, resource calendars), the storage format will fight you.
  • Blast radius is low and the escape hatch matters: if the plugin is abandoned, the data is still plain JSON in spatie format — you keep the rows, drop the UI, and query or edit however you like. That materially changes the risk calculus versus a package with a proprietary schema.
  • You want ops self-service without engineering tickets. The grid, day-copy and "repeat every year" features are aimed at non-technical editors; the validation story (merging overlapping ranges, rejecting double-covered dates, validating the payload by instantiating spatie's object) means an editor can't save an unqueryable record.
  • Multi-panel or multi-tenant-lite setups where each panel owns one key.

Look elsewhere when:

  • You need appointment booking, capacity, or slot inventory — pair this with a real scheduling system, or don't use it at all.
  • You need per-staff, per-service, or per-resource availability (a restaurant with different kitchen and bar hours, a clinic with per-practitioner rotas).
  • You need consumer-grade reliability guarantees or vendor support. This is an 8-star, 0-dependent, v1.x package from a single agency with one named maintainer. Pin the version, review the diff before upgrading, and be prepared to fork.
  • You need sub-day seasonal complexity that the day-grid can't express well — e.g. many different schedules per weekday across seasons. (Hand-written spatie definitions with recurring m-d to m-d ranges are preserved verbatim across edits, but not editable in the grid.)
  • Overnight hours are central to the business. The grid is 00:00–24:00 per day; the recommended model is splitting past-midnight ranges across two days, with spatie overflow mode as an opt-in that shows clamped ranges. Doable, but a nightly venue should validate this in a spike before committing.
  • You are not on Filament. Go straight to spatie/opening-hours and build a thin editor, or use a dedicated scheduling product.
  • You need many records managed from one screen — one page per key is the model; bulk management of dozens of locations is not what this is.

How to Pitch It (Stakeholders)

For executives (30 seconds). This is a small, MIT-licensed building block that gives our admin panel a proper opening-hours editor — a 24-hour weekly grid, holiday closures, vacation periods and timezones — for roughly the cost of one Composer dependency and one database table. It does not invent a data format: everything it saves is the exact input format of spatie/opening-hours, an established library we would likely standardise on anyway. That means the strategic risk is bounded — if we ever drop the plugin, we keep our data and only lose the editor. It unlocks "open now", holiday notices and hours-gated checkout copy without an engineering project, and it explicitly does not drag us into booking, capacity or staffing, which stay separate roadmap decisions.

For engineering. One table, one row per hours set (key, timezone, overflow, hours JSON, exceptions JSON). The page saves the whole state atomically after normalising ranges and validating by actually instantiating Spatie\OpeningHours\OpeningHours, so a stored record is queryable by construction. Reads are a one-liner (BusinessHours::openingHours('shop-paris')) or toOpeningHoursArray() if we want to cache the parsed definition (recommended for per-request header badges: cache()->remember(...), invalidated on save). Configuration is available both as a published config file and a fluent per-panel API. Authorization is a single canAccessUsing() closure or Gate ability covering nav and route. Livewire state is treated as untrusted: caps of 100 ranges/day, 500 exceptions, 1100 days per vacation, 255-char labels, with graceful degradation on malformed state. Ships EN/FR/ES, has tests and static analysis in CI.

For risk and procurement. MIT licence, v1.x with a changelog and docs, and — notably for a package this size — a supply-chain hardening release: CI actions pinned to full commit SHAs, Dependabot with a cooldown window, and a published SECURITY.md with disclosure channels. That is better hygiene than most small packages ship. Counterweights to state openly: 8 GitHub stars, 0 dependents, one maintainer, single-agency origin, no track record at scale. Mitigations are cheap and should be part of the proposal: pin the exact version, isolate usage behind our own model/service (the package supports ->model() subclassing and raw table reads), keep the format standard so a fork or hand-written definitions remain viable, and treat the UI as replaceable.

Recommendation and the ask. Timebox a one-day spike on a single non-critical panel: install, migrate, model our real hours (including an overnight case if we have one), and confirm the query paths we need (isOpenAt, nextOpen, exceptionalClosingDates) plus a cached read on a hot page. Fund the spike, not the commitment. Decision criteria to come back with: does the overnight/exceptions model match our venues, is the per-request read cheap enough with caching, and are we comfortable owning a fork. If all three pass, adopt for presentation-layer hours now and defer the "hours as checkout policy" decision until that roadmap item is prioritised.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator