The /[locale]/loja route showcases paid/free templates pulled from Supabase and rendered with liquid-glass cards. This page documents the data model, components, analytics hooks, and how to extend the module.
src/app/[locale]/(pages)/store/page.tsx
setRequestLocale(locale).Store.*.getAllProducts() (Server Query that uses ProductRepository).trackServerEvent("page_view", { page: "store" }) for Mixpanel.TemplatesGrid (filters + cards) and a CTA.TemplatesGrid (client component)
search, category, stack, level, priceType).store_filter_applied through useClickTracking (GA4 + Mixpanel).TemplateCard and optionally highlights one via ?template=<id> query string.StoreContactCTA linking to /[locale]/contato and track conversions.src/app/types/template.ts defines the Template type (single source of truth for the store). Key fields:
| Field | Description |
|---|---|
id, slug | Stable identifiers used for filtering and highlight anchors. |
price, priceType, stripePriceId | Pricing metadata (one-time, subscription, free). |
category, stack, level | Drive filters in TemplateFilters. Keep values in sync with translation files (Store.filters.*). |
features | Rendered as bullet list inside TemplateCard. |
demoUrl, image | CTA + screenshot link. |
Data can come from:
products table (via ProductRepository).src/app/data/recommendations.ts (used for marketing sections like /recommendations).ProductRepository (see src/app/lib/repositories/product-repository.ts) encapsulates Supabase queries (findAll, findPaginated, create, update, etc.) and enforces unique slugs.src/app/actions/products/* and src/app/[locale]/admin/products/* pages.revalidateProducts/revalidateProduct via src/app/lib/cache.ts so the ISR store page refreshes within 1 hour (revalidate = 3600).Store.* strings in src/i18n/messages/{locale}.json cover hero copy, filters, empty state, CTA. When adding new filters/categories:
TemplateFilters."filters.categories.{key}").trackServerEvent("page_view", { page: "store" }) inside the page component.content/analytics/events.mdx:
store_template_viewstore_template_demo_clickstore_filter_appliedstore_initiate_checkoutStoreContactCTA emits contact_form_start once the user lands on /contato.src/app/test/unit/components/store/ cover TemplateCard, TemplateFilters, etc.src/app/test/integration/actions/products-actions.test.ts ensure ActionResult codes (DUPLICATE_SLUG, NOT_FOUND, etc.).src/app/test/e2e/tests/store.spec.ts) navigate the store filters and verify CTAs.Template['category'], TemplateFilters options, translations, and consider adding a new filter icon/tag.Intl.NumberFormat in TemplateCard to display localized pricing (look at Store.priceNote). For multi-currency checkout, see /pricing doc.?template=<id> to the URL. TemplatesGrid scrolls it into view automatically.trackServerEvent calls (e.g., store-contact-cta) in page.tsx.Keep this page updated whenever the store gains new filters, data fields, or payment flows so marketing, product, and engineering teams stay aligned.