import type { HeadersFunction, LoaderFunctionArgs } from "react-router"; import { useLoaderData } from "react-router"; import { boundary } from "@shopify/shopify-app-react-router/server"; import { authenticate } from "../shopify.server"; import { ensureShop } from "../lib/shop.server"; import { planOf } from "../lib/plans"; import { festivalByName, TEMPLATES, upcomingFestivals } from "../lib/templates"; import { moneyFormatter, offerSummary, TYPE_LABEL } from "../lib/offer-text"; export const loader = async ({ request }: LoaderFunctionArgs) => { const { admin, session } = await authenticate.admin(request); const shop = await ensureShop(admin, session.shop); const plan = planOf(shop.planCode); const money = moneyFormatter(shop.currency); const now = new Date(); return { allowed: plan.templates, calendar: upcomingFestivals(now).map((f) => ({ ...f, weeksAway: Math.round((new Date(`${f.date}T00:00:00Z`).getTime() - now.getTime()) / (7 * 86400000)), })), templates: TEMPLATES.map((t) => ({ ...t, summary: offerSummary({ ...t, mixQty: t.mixQty ?? 3, buyQty: t.buyQty ?? 2, getQty: t.getQty ?? 1, getPercent: t.getPercent ?? 100, active: true, published: true, startsAt: null, endsAt: null }, money), next: festivalByName(t.festival)?.date || "", })), }; }; export default function Templates() { const { templates, calendar, allowed } = useLoaderData(); return ( {!allowed ? ( See plans ) : null} {calendar.map((f) => ( {f.name} {f.date}{f.approximate ? " (approx.)" : ""} {f.weeksAway <= 0 ? "This week" : `In ${f.weeksAway} weeks`} ))} Plan your offers about 6 weeks ahead. Lunar dates are approximate: check them locally. {templates.map((t) => ( {t.badge}{TYPE_LABEL[t.type]} {t.name} {t.summary} {t.festival}{t.next ? ` ยท ${t.next}` : ""} Use template ))} ); } export const headers: HeadersFunction = (headersArgs) => boundary.headers(headersArgs);