npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@andrezhan27/intelis-restaurant-ui

v0.2.2

Published

Shared native UI for Intelis restaurant websites and dashboards.

Readme

@andrezhan27/intelis-restaurant-ui

Shared native React/Next.js UI for Intelis restaurant websites and dashboards.

Restaurant website

Install this package and its peers (react, next, and @supabase/supabase-js). Supabase is now required for the live banner, not just for the dashboard. Configure NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (or the legacy anon key), then add:

import { PromotionBanner } from "@andrezhan27/intelis-restaurant-ui";

<body>
  <PromotionBanner restaurantId={restaurantId} />
  <Header />
  {children}
</body>

The server renders an initial snapshot and the browser subscribes to live changes, including when there are initially no promotions. Only a publishable or legacy anon key may be passed to the client. Secret/service-role keys are rejected.

Popup flow

  • Active means the restaurant is active, the promotion is enabled, its start has arrived (or is unset), and its exclusive end has not arrived (or is unset).
  • The centered popup opens automatically once per restaurant and browser-tab session. Closing with the × button, backdrop, or Escape leaves a compact See Promotions / Ver Promoções CTA at the top so it can be reopened.
  • Language is selected from the document's lang value, then the browser language. Portuguese locales use Portuguese UI labels; all others use English.
  • Desktop shows every active promotion as cards in authoritative database order. Mobile shows one card at a time with previous/next arrows and a position count.
  • On mobile, the popup stays at 65% of the viewport height without scrolling. Equal-width columns show the complete image on the left and offer text on the right, including on narrow phones. Titles use up to three lines; descriptions fit the available space with an ellipsis, reserving room for the CTA and spacing.
  • Promotion CTAs use normal same-tab links. Popup focus is trapped while open, background scrolling is locked, and focus is restored after closing.
  • A single promotion uses a wide image-and-copy treatment inspired by a classic editorial offer modal.

Live changes and scheduling

get_restaurant_promotion_state is a narrow public RPC returning ordered active promotion cards, server time, and the next scheduled change. It uses cache: "no-store". Database triggers broadcast invalidations on restaurant-promotions:<restaurantId> for promotion insert/update/delete and restaurant activation/deactivation. Payloads contain no promotion content (Supabase adds a delivery ID). Visitors refetch the authoritative public RPC; public messages cannot inject banner text or links.

Changes appear as soon as the push notification and refresh arrive, subject to normal network latency. Scheduled starts trigger a refresh at the returned boundary. Known endings are removed locally at their deadline even if offline. Reconnect, visibility return, and online events refresh the data. A 30-second safety check catches missed notifications; failed requests retry with backoff from one to 30 seconds. During an outage, retain the last known unexpired data. Instant remote updates cannot be guaranteed while a visitor is offline.

The RPC's deliberate SECURITY DEFINER boundary preserves existing restrictions: anonymous users cannot read the admin table, and draft/future/expired content is not returned. RLS for restaurant administrators remains unchanged. Supabase's public executable function advisor flags this intentional public API (as it does the legacy single-banner API). Trigger functions are private and are not executable by anonymous/authenticated clients. Public topics disclose change timing, never unpublished row contents.

Styling

Override these brand variables to keep a site's own banner colors:

:root {
  --promotion-banner-bg: #171717;
  --promotion-banner-text: #ffffff;
  --promotion-banner-link: #f1d48a;
  --promotion-banner-border: transparent;
}

Dashboard

The dashboard entry uses the existing authenticated Supabase client. RLS limits reads and writes to owner/manager memberships for the selected restaurant. Administrators can edit the popup title, description, safe root-relative or HTTPS image reference, required image alt text, CTA, schedule, variant, and priority. title is the single source of truth for promotion headings.

import { PromotionManager } from "@andrezhan27/intelis-restaurant-ui/dashboard";

<PromotionManager supabase={supabase} restaurantId={restaurantId} />

Saving updates connected websites through the database trigger; onSaved remains available for deployment-specific follow-up work.

Rollout and verification

Apply the existing promotion migrations followed by supabase/migrations/20260901110855_add_promotion_popup_content.sql and supabase/migrations/20260901152955_remove_legacy_promotion_message.sql before upgrading the UI. The first migration backfills titles from existing messages; the second removes the duplicate table column after all package code switches to title. The original get_active_restaurant_promotion RPC and fetchActivePromotion export remain available for older consumers; the RPC derives its legacy message output from title. Websites only gain the popup and live updates after installing a release containing these changes and redeploying. This repository does not deploy those consumer websites automatically.

  • npm test: build plus data-contract, URL, ordering, urgency, expiry, and key-safety tests.
  • npm run check: TypeScript verification.
  • tests/promotion-database.sql: database-owner integration test; fixtures and broadcasts roll back. Needs an existing active restaurant.
  • npm run preview:banners: local popup fixture at http://127.0.0.1:3111. Visit /mobile for a portrait poster fixture with single and multiple offers. Uses the actual component and Supabase client against a local mock RPC and Broadcast server. Controls exercise live edits, removals, urgent notices, schedules, and outages without touching restaurant data.
  • tests/realtime-probe.mjs: optional real-project public API/Broadcast probe; see its usage comments. Never provide a service-role key.