Skip to content

Conversation

@softmarshmallow
Copy link
Member

@softmarshmallow softmarshmallow commented Jan 10, 2026

cleanups

@vercel
Copy link

vercel bot commented Jan 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
backgrounds Ready Ready Preview, Comment Jan 11, 2026 5:36am
blog Ready Ready Preview, Comment Jan 11, 2026 5:36am
docs Ready Ready Preview, Comment Jan 11, 2026 5:36am
grida Ready Ready Preview, Comment Jan 11, 2026 5:36am
viewer Ready Ready Preview, Comment Jan 11, 2026 5:36am
2 Skipped Deployments
Project Deployment Review Updated (UTC)
code Ignored Ignored Jan 11, 2026 5:36am
legacy Ignored Ignored Jan 11, 2026 5:36am

@coderabbitai
Copy link

coderabbitai bot commented Jan 10, 2026

Walkthrough

This PR migrates template imports from west-referral to enterprise-specific paths, introduces a reusable ComponentDemo wrapper for UI demonstrations, integrates the wrapper across nine demo pages, implements a comprehensive EnterpriseWestReferralDuo001Editor component with tabbed interface and live preview, simplifies campaign design routing, and reorganizes the developer UI to include a new Forms section.

Changes

Cohort / File(s) Summary
Import Path Migrations to Enterprise
editor/app/(api)/private/west/campaigns/new/route.ts, editor/app/(dev)/canvas/examples/with-templates/002/page.tsx, editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/invitation.tsx, editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/referrer.tsx, editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/page.tsx, editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
Updated TemplateData and template component imports from west-referral/... to enterprise/west-referral/... paths for centralized enterprise template management.
ComponentDemo Component & Integration
editor/app/(dev)/ui/components/component-demo.tsx (new), editor/app/(dev)/ui/components/degree/page.tsx, editor/app/(dev)/ui/components/phone-input/page.tsx, editor/app/(dev)/ui/components/progress/page.tsx, editor/app/(dev)/ui/components/rich-text-editor/page.tsx, editor/app/(dev)/ui/components/spinner/page.tsx, editor/app/(dev)/ui/components/tags/page.tsx, editor/app/(dev)/ui/components/timeline/page.tsx, editor/app/(dev)/ui/components/tree/page.tsx
Introduced reusable ComponentDemo wrapper (29 lines) for consistent demo UI styling with optional notes, then integrated across nine demo pages to replace inline styling with standardized wrapped demos.
Enterprise Template Editor
editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx (new)
New 536-line editor component providing tabbed interface (referrer, share, invitation, theme tabs), live CampaignTemplateDuo001Viewer preview pane, form-based field editing (images, titles, descriptions, CTAs, rich text), state management for active tab and canvas focus, save/publish actions with toast feedback, and locale/logo editing capabilities.
Campaign Design Page Routing
editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
Simplified from multi-tab editor UI to DesignerRouter that loads templates, routes to EnterpriseWestReferralDuo001Editor for grida_west_referral.duo-000 templates, and provides explicit feedback for missing or unsupported templates.
Enterprise Template Enhancements
editor/theme/templates/enterprise/west-referral/invitation/coupon.tsx, editor/theme/templates/enterprise/west-referral/invitation/page.tsx, editor/theme/templates/enterprise/west-referral/referrer/page.tsx, editor/theme/templates/enterprise/west-referral/referrer/share.tsx
Updated Standard component imports to enterprise paths, added data-testid attributes for improved testing (west-referral-invitation-coupon, west-referral-invitation-page, west-referral-referrer-page, west-referral-referrer-share-dialog), and added accessibility DrawerTitle in share component.
Developer UI Organization
editor/app/(dev)/ui/page.tsx
Removed Tag Input and Phone Input from Component Library, introduced new Forms section with Email Challenge, Tag Input, and Phone Input entries, reorganized layout to display Forms section between Component Library and Showcases.
Documentation
editor/theme/templates/enterprise/README.md, supabase/TODO.md
Added enterprise templates directory documentation explaining purpose, guidelines, and future plans; added migration TODO for grida_forms block consolidation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Editor as EnterpriseWestReferralDuo001Editor
    participant Form as Form Fields
    participant Preview as CampaignTemplateDuo001Viewer
    participant API as template.save()

    User->>Editor: Load template (template_id)
    Editor->>Editor: Initialize with TemplateData
    Editor->>Editor: Compute canvas focus per tab
    Editor->>Form: Render tab content (referrer/invitation/theme)
    User->>Form: Edit field (title/description/image/CTA)
    Form->>Editor: props.set(field, value)
    Editor->>Editor: Update template data state
    Editor->>Preview: Re-render with updated data
    Preview-->>Editor: Display live preview
    User->>Editor: Click Save/Publish
    Editor->>API: template.save() with new data
    API-->>Editor: Response + toast feedback
    Editor->>Editor: Update dirty/saving state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • kmk142789

Poem

🐰 A rabbit's ode to templates organized,
ComponentDemo wraps with style,
Enterprise paths now harmonized,
The editor flows, tab by file!
Forms and previews dance with care,
Data saved through the mountain air. 🏔️

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'chore' is vague and generic, failing to convey the substantial changes across multiple files including new component creation, template path restructuring, and UI refactoring. Replace with a specific title describing the main change, such as 'Refactor UI component demos and migrate templates to enterprise namespace' or 'Introduce ComponentDemo wrapper and consolidate enterprise templates'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch task-20260110

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cursor
Copy link

cursor bot commented Jan 11, 2026

You have run out of free Bugbot PR reviews for this billing cycle. This will reset on February 5.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
editor/app/(api)/private/west/campaigns/new/route.ts (1)

101-101: Remove unnecessary type assertion.

The as any cast on line 101 defeats the purpose of the satisfies operator and bypasses TypeScript's type safety. If the type doesn't satisfy TemplateData.West_Referrral__Duo_001, the underlying issue should be resolved rather than suppressed with as any.

♻️ Proposed fix to remove the type assertion
-      } satisfies TemplateData.West_Referrral__Duo_001 as any,
+      } satisfies TemplateData.West_Referrral__Duo_001,

If this causes a TypeScript error, please investigate and fix the underlying type mismatch rather than suppressing it.

🤖 Fix all issues with AI agents
In
@editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx:
- Around line 297-309: The input is reading from
values?.components?.referrer?.cta but writing to
"components.referrer-share.cta", causing a mismatch; make the getter and setter
use the same component path. Either change the value prop to
values?.components?.["referrer-share"]?.cta to match
props.set("components.referrer-share.cta", ...) or change the setter to
props.set("components.referrer.cta", e.target.value) so both read and write the
same key.

In
@editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx:
- Around line 37-49: The hook useWWWTemplate is being called conditionally after
an early return based on template_id, violating the Rules of Hooks; move the
call to useWWWTemplate(template_id) (and the typed generic
TemplateData.West_Referrral__Duo_001) above the if (!template_id) check so hooks
run unconditionally, or alternatively extract the UI that depends on template
into a child component (e.g., TemplateViewer) that is only rendered when
template_id exists and calls useWWWTemplate internally.

In @supabase/TODO.md:
- Line 5: Update the checklist item text to correct punctuation and improve
clarity: change "remove each mime specific block, (image, video, pdf, etc) and
replace with 'viewer' block. with extra attributes." to a clearer sentence such
as "Remove each MIME-specific block (image, video, PDF, etc.) and replace it
with a 'viewer' block that includes extra attributes." Ensure "etc." includes a
period, "PDF" is capitalized, and remove the erroneous period between "block."
and "with".
🧹 Nitpick comments (5)
editor/app/(dev)/ui/components/component-demo.tsx (2)

10-29: Consider using a className utility for better handling.

The component is well-structured and serves its purpose effectively. However, the className concatenation on line 22 could benefit from using a utility like cn from clsx or tailwind-merge for more robust handling of conditional classes and deduplication.

♻️ Proposed improvement using cn utility

If not already available, add the cn utility (commonly used in shadcn/ui projects):

// lib/utils.ts
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Then update the component:

+import { cn } from "@/lib/utils";
+
 export function ComponentDemo({
   children,
   notes,
   className,
 }: {
   children: React.ReactNode;
   notes?: React.ReactNode;
   className?: string;
 }) {
   return (
     <div className="space-y-4">
       <div
-        className={`flex items-center justify-center min-h-[400px] p-12 border border-gray-200 rounded-lg ${className || ""}`}
+        className={cn(
+          "flex items-center justify-center min-h-[400px] p-12 border border-gray-200 rounded-lg",
+          className
+        )}
       >
         {children}
       </div>
       {notes && <div className="text-sm text-gray-600">{notes}</div>}
     </div>
   );
 }

22-22: Consider making min-height configurable.

The hardcoded min-h-[400px] works well for most cases, but making it configurable could improve reusability for components that need different heights.

♻️ Optional: Add minHeight prop
 export function ComponentDemo({
   children,
   notes,
   className,
+  minHeight = "400px",
 }: {
   children: React.ReactNode;
   notes?: React.ReactNode;
   className?: string;
+  minHeight?: string;
 }) {
   return (
     <div className="space-y-4">
       <div
+        style={{ minHeight }}
-        className={`flex items-center justify-center min-h-[400px] p-12 border border-gray-200 rounded-lg ${className || ""}`}
+        className={`flex items-center justify-center p-12 border border-gray-200 rounded-lg ${className || ""}`}
       >
         {children}
       </div>
       {notes && <div className="text-sm text-gray-600">{notes}</div>}
     </div>
   );
 }
editor/app/(dev)/ui/components/tree/page.tsx (1)

29-29: Redundant min-height specification.

The className="min-h-[400px]" prop is redundant since ComponentDemo already applies min-h-[400px] by default. You can simplify this to just <ComponentDemo>.

♻️ Simplify by removing redundant className
-          <ComponentDemo className="min-h-[400px]">
+          <ComponentDemo>
editor/theme/templates/enterprise/README.md (1)

1-48: Excellent documentation for the enterprise templates directory.

This README clearly articulates the purpose, scope, and guidelines for enterprise-specific templates. The distinction between standard and enterprise templates is well-explained, and the acknowledgment of this as a temporary solution with future plans is transparent and helpful.

Optional style refinements

If you'd like to address the minor style suggestions from static analysis:

Lines 38-40: Consider rewording to avoid three consecutive sentences starting with "It":

-It increases maintenance cost and makes releases riskier.
-It does not scale as customers request divergent behavior.
-It mixes "product" templates with customer-specific implementation details.
+This approach increases maintenance cost and makes releases riskier.
+It does not scale as customers request divergent behavior.
+Additionally, it mixes "product" templates with customer-specific implementation details.

Line 48: Consider hyphenating the compound adjective:

-This is an open source repository: please treat enterprise templates as...
+This is an open-source repository: please treat enterprise templates as...

These are purely stylistic and optional.

editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx (1)

76-81: Consider preserving the generic type parameter.

The internal TemplateEditor uses WWWTemplateEditorInstance<any>, losing type safety. Since this component is only used for West_Referrral__Duo_001, consider keeping the specific type.

 function TemplateEditor({
   template,
 }: {
-  template: WWWTemplateEditorInstance<any>;
+  template: WWWTemplateEditorInstance<TemplateData.West_Referrral__Duo_001>;
 }) {
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bcf779d and a825ccc.

📒 Files selected for processing (26)
  • editor/app/(api)/private/west/campaigns/new/route.ts
  • editor/app/(dev)/canvas/examples/with-templates/002/page.tsx
  • editor/app/(dev)/ui/components/component-demo.tsx
  • editor/app/(dev)/ui/components/degree/page.tsx
  • editor/app/(dev)/ui/components/phone-input/page.tsx
  • editor/app/(dev)/ui/components/progress/page.tsx
  • editor/app/(dev)/ui/components/rich-text-editor/page.tsx
  • editor/app/(dev)/ui/components/spinner/page.tsx
  • editor/app/(dev)/ui/components/tags/page.tsx
  • editor/app/(dev)/ui/components/timeline/page.tsx
  • editor/app/(dev)/ui/components/tree/page.tsx
  • editor/app/(dev)/ui/page.tsx
  • editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/invitation.tsx
  • editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/referrer.tsx
  • editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/page.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
  • editor/theme/templates/enterprise/README.md
  • editor/theme/templates/enterprise/west-referral/invitation/coupon.tsx
  • editor/theme/templates/enterprise/west-referral/invitation/page.tsx
  • editor/theme/templates/enterprise/west-referral/referrer/page.tsx
  • editor/theme/templates/enterprise/west-referral/referrer/share.tsx
  • editor/theme/templates/enterprise/west-referral/standard.tsx
  • editor/theme/templates/enterprise/west-referral/templates.ts
  • supabase/TODO.md
🧰 Additional context used
📓 Path-based instructions (4)
editor/app/(tenant)/**

📄 CodeRabbit inference engine (AGENTS.md)

Use /editor/app/(tenant) for tenant-site rendered pages

Files:

  • editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/page.tsx
  • editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/referrer.tsx
  • editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/invitation.tsx
supabase/**

📄 CodeRabbit inference engine (AGENTS.md)

Do not use supabase edge functions; migrations should be managed with supabase migration commands

Files:

  • supabase/TODO.md
editor/app/(workbench)/**

📄 CodeRabbit inference engine (AGENTS.md)

Use /editor/app/(workbench) for the main editor page and workspace pages

Files:

  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
editor/app/(api)/private/**

📄 CodeRabbit inference engine (AGENTS.md)

Private editor-only API routes should be placed in /editor/app/(api)/private

Files:

  • editor/app/(api)/private/west/campaigns/new/route.ts
🧠 Learnings (11)
📚 Learning: 2025-12-01T00:21:55.314Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: apps/docs/AGENTS.md:0-0
Timestamp: 2025-12-01T00:21:55.314Z
Learning: Applies to apps/docs/docs/** : DO NOT edit files under `apps/docs/docs/` directory directly - this directory is auto-generated and will be overwritten on build

Applied to files:

  • editor/theme/templates/enterprise/README.md
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : When adding new parameters to the halftone tool, add state with useState, include in useEffect dependency array, pass to renderHalftone() function, use in rendering logic, and add UI control

Applied to files:

  • editor/app/(dev)/ui/components/progress/page.tsx
  • editor/app/(dev)/ui/components/phone-input/page.tsx
  • editor/app/(dev)/ui/components/tags/page.tsx
  • editor/app/(dev)/ui/components/degree/page.tsx
📚 Learning: 2026-01-10T04:48:31.415Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T04:48:31.415Z
Learning: Use /editor/components for generally reusable components and /editor/components/ui for shadcn UI components

Applied to files:

  • editor/app/(dev)/ui/components/progress/page.tsx
  • editor/app/(dev)/canvas/examples/with-templates/002/page.tsx
  • editor/app/(dev)/ui/page.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : Use React hooks for state management (imageSrc, shape, grid, maxRadius, gamma, jitter, opacity, color, customShapeImage, imageDataRef, sizeRef)

Applied to files:

  • editor/app/(dev)/ui/components/progress/page.tsx
  • editor/app/(dev)/canvas/examples/with-templates/002/page.tsx
  • editor/app/(dev)/ui/components/rich-text-editor/page.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
  • editor/theme/templates/enterprise/west-referral/invitation/page.tsx
  • editor/app/(dev)/ui/components/tags/page.tsx
  • editor/app/(dev)/ui/components/degree/page.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
📚 Learning: 2025-12-01T00:22:19.083Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: crates/grida-canvas-wasm/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:19.083Z
Learning: Applies to crates/grida-canvas-wasm/**/main.rs : Update `grida-canvas-wasm.d.ts` TypeScript definitions file when new APIs are introduced via `main.rs`

Applied to files:

  • editor/app/(dev)/canvas/examples/with-templates/002/page.tsx
📚 Learning: 2026-01-10T04:48:31.415Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T04:48:31.415Z
Learning: Use /editor/scaffolds for feature-specific larger components, pages, and editors

Applied to files:

  • editor/app/(dev)/canvas/examples/with-templates/002/page.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : Cache ImageData and dimensions in refs (imageDataRef, sizeRef) for efficient exports

Applied to files:

  • editor/app/(dev)/canvas/examples/with-templates/002/page.tsx
📚 Learning: 2025-12-01T00:22:56.899Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: editor/app/(tools)/tools/halftone/AGENTS.md:0-0
Timestamp: 2025-12-01T00:22:56.899Z
Learning: Applies to editor/app/(tools)/tools/halftone/app/(tools)/tools/halftone/_page.tsx : When adding new shape types, update the Shape type union, add cases in drawShape() function, add cases in shapeToSVG() function, and add SelectItem in UI

Applied to files:

  • editor/app/(dev)/ui/page.tsx
📚 Learning: 2026-01-10T04:48:31.415Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T04:48:31.415Z
Learning: Applies to editor/app/*/layout.{ts,tsx} : Each app in /editor/app directory should have its own root layout, not shared

Applied to files:

  • editor/app/(dev)/ui/components/rich-text-editor/page.tsx
  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
📚 Learning: 2026-01-10T04:48:31.415Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T04:48:31.415Z
Learning: Use React.js 19 for web applications

Applied to files:

  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
📚 Learning: 2026-01-10T04:48:31.415Z
Learnt from: CR
Repo: gridaco/grida PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T04:48:31.415Z
Learning: Use DOM canvas (plain dom as canvas) for website builder canvas, bound with React

Applied to files:

  • editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx
🧬 Code graph analysis (8)
editor/app/(dev)/ui/components/progress/page.tsx (1)
editor/app/(dev)/ui/components/component-demo.tsx (1)
  • ComponentDemo (10-29)
editor/app/(dev)/ui/page.tsx (1)
editor/lib/supabase/server.ts (1)
  • forms (101-102)
editor/app/(dev)/ui/components/timeline/page.tsx (1)
editor/app/(dev)/ui/components/component-demo.tsx (1)
  • ComponentDemo (10-29)
editor/app/(dev)/ui/components/rich-text-editor/page.tsx (1)
editor/app/(dev)/ui/components/component-demo.tsx (1)
  • ComponentDemo (10-29)
editor/app/(dev)/ui/components/spinner/page.tsx (2)
editor/app/(dev)/ui/components/component-demo.tsx (1)
  • ComponentDemo (10-29)
editor/components/ui/spinner.tsx (1)
  • Spinner (16-16)
editor/app/(dev)/ui/components/phone-input/page.tsx (1)
editor/app/(dev)/ui/components/component-demo.tsx (1)
  • ComponentDemo (10-29)
editor/app/(dev)/ui/components/tree/page.tsx (1)
editor/app/(dev)/ui/components/component-demo.tsx (1)
  • ComponentDemo (10-29)
editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx (2)
editor/scaffolds/platform/www/www-layout-provider.tsx (2)
  • WWWLayoutProvider (51-69)
  • useWWWLayout (71-77)
editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx (1)
  • EnterpriseWestReferralDuo001Editor (33-39)
🪛 LanguageTool
editor/theme/templates/enterprise/README.md

[style] ~40-~40: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...customers request divergent behavior. - It mixes “product” templates with customer...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[uncategorized] ~48-~48: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...mers, then iterate/fix. This is an open source repository: please treat enterprise tem...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

supabase/TODO.md

[style] ~5-~5: In American English, abbreviations like “etc.” require a period.
Context: ...ime specific block, (image, video, pdf, etc) and replace with 'viewer' block. with ...

(ETC_PERIOD)

🔇 Additional comments (30)
editor/app/(dev)/ui/page.tsx (2)

45-62: LGTM! Well-structured Forms section.

The new Forms section follows the established pattern for organizing UI components. The data structure is consistent with the existing components and showcases arrays, and the descriptions are clear and informative.


127-143: LGTM! Consistent rendering pattern.

The Forms section rendering follows the same pattern as Component Library and Showcases sections. The color differentiation (green for forms) helps visually distinguish between different categories.

editor/app/(dev)/ui/components/degree/page.tsx (1)

6-6: LGTM! Consistent ComponentDemo integration.

The ComponentDemo wrapper is used consistently across all demo sections. The notes prop effectively displays state feedback where relevant (Size Variants and Constrained Mode), while sections like Disabled State appropriately omit it. The integration maintains all existing DegreeControl functionality while improving visual consistency.

Also applies to: 35-78, 91-129, 142-153, 221-227

editor/app/(dev)/ui/components/spinner/page.tsx (1)

5-5: LGTM! Clean ComponentDemo integration.

The ComponentDemo wrapper is properly integrated for the Default Spinner section, maintaining consistency with other demo pages in the project.

Also applies to: 27-29

editor/app/(dev)/ui/components/phone-input/page.tsx (1)

5-5: LGTM! Excellent ComponentDemo integration.

The ComponentDemo wrapper is consistently applied across all sections with appropriate use of the notes prop to display current phone values. The Form Example section correctly uses the wrapper without notes, as the form context provides its own visual structure. This change improves visual consistency while preserving all functionality.

Also applies to: 31-36, 50-55, 67-74, 86-116

editor/app/(dev)/ui/components/timeline/page.tsx (1)

5-5: LGTM! Clean adoption of ComponentDemo wrapper.

The Timeline component is now wrapped with the standardized ComponentDemo layout, providing consistent presentation across UI demo pages without altering the Timeline's functionality.

Also applies to: 27-31

editor/app/(dev)/ui/components/tree/page.tsx (1)

5-5: LGTM! Consistent ComponentDemo integration.

The Tree component demo now uses the standardized ComponentDemo wrapper, maintaining consistency with other UI demo pages.

Also applies to: 30-33

editor/app/(dev)/ui/components/rich-text-editor/page.tsx (1)

5-5: LGTM! Proper integration of ComponentDemo wrapper.

Both MinimalTiptapEditor instances are now wrapped with ComponentDemo for consistent presentation. The editor-specific height constraints and state management remain unchanged, preserving all functionality.

Also applies to: 33-49, 63-79

editor/app/(dev)/ui/components/tags/page.tsx (1)

5-5: LGTM! Effective use of ComponentDemo with contextual notes.

All three TagInput variations are now wrapped with ComponentDemo, utilizing the notes prop to provide helpful user guidance. The tag management functionality remains fully intact across all variants.

Also applies to: 57-71, 83-99, 111-118

editor/app/(dev)/ui/components/progress/page.tsx (1)

7-7: LGTM! Comprehensive ComponentDemo integration.

All three progress sections (Standard Progress, Progress Variants, and Editor Progress) are now wrapped with ComponentDemo for consistent presentation. The progress animation logic, state management, and button handlers remain unchanged. The use of the notes prop for the indeterminate variant provides helpful context.

Also applies to: 53-71, 83-121, 135-139

editor/app/(api)/private/west/campaigns/new/route.ts (2)

13-13: Import path migration verified successfully.

The new import path @/theme/templates/enterprise/west-referral/templates exists and correctly exports the TemplateData type with the West_Referrral__Duo_001 property. The template_id reference in the type definition (grida_west_referral.duo-000) matches the usage on line 101. The import change aligns with the file relocation and is correct.


80-80: Template ID and type are correctly aligned; no mismatch exists.

The template_id on line 80 ("grida_west_referral.duo-000") correctly matches the type constraint defined in the interface West_Referrral__Duo_001. The interface itself (at editor/theme/templates/enterprise/west-referral/templates.ts:3) declares template_id: "grida_west_referral.duo-000", so the type name suffix (001) and template_id suffix (000) serve different purposes and are intentionally distinct. The type name is simply the interface identifier, not a version indicator. Code at lines 80 and 101 are consistent and correct.

The "Referrral" spelling (three R's) is consistent throughout the codebase and appears intentional.

Likely an incorrect or invalid review comment.

editor/theme/templates/enterprise/west-referral/referrer/page.tsx (1)

245-245: LGTM! Test IDs improve testability.

The addition of data-testid attributes enhances E2E testing capabilities without affecting runtime behavior. The Card formatting adjustment maintains readability.

Also applies to: 282-285

editor/theme/templates/enterprise/west-referral/referrer/share.tsx (1)

7-7: Excellent accessibility improvement.

Adding a screen-reader-only DrawerTitle ensures that assistive technologies can properly announce the dialog purpose. The data-testid attribute enhances testability. Both changes follow accessibility and testing best practices.

Also applies to: 47-48

editor/app/(dev)/canvas/examples/with-templates/002/page.tsx (1)

7-7: Import path migration is correct and properly resolves.

The file exists at the new location and ReferrerPageTemplate is properly exported as the default function. The change aligns with the enterprise template reorganization.

editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/referrer.tsx (1)

5-6: Import migration is consistent and correct.

Both enterprise imports resolve correctly:

  • ReferrerPageTemplate is exported as default from @/theme/templates/enterprise/west-referral/referrer/page
  • TemplateData is exported as a namespace from @/theme/templates/enterprise/west-referral/templates

The file location follows the coding guidelines for tenant-site rendered pages, and the component API remains compatible with its usage.

editor/theme/templates/enterprise/west-referral/invitation/coupon.tsx (2)

7-7: LGTM! Import path aligned with enterprise template structure.

The Standard module import has been correctly updated to the enterprise-specific path.


49-52: LGTM! Test identifier added for improved testability.

The data-testid attribute follows a consistent naming pattern and will facilitate automated testing of the invitation coupon component.

editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/template-duo-001-viewer.tsx (1)

3-6: LGTM! Template imports migrated to enterprise namespace.

All template component imports (ReferrerPageTemplate, ShareDialog, InvitationCouponTemplate, InvitationPageTemplate) and TemplateData have been correctly updated to reference the enterprise/west-referral path. The viewer logic remains unchanged.

Also applies to: 22-22

editor/theme/templates/enterprise/west-referral/invitation/page.tsx (2)

33-33: LGTM! Standard import updated to enterprise template path.

The import path has been correctly updated to align with the enterprise template structure.


129-129: LGTM! Comprehensive test identifiers added.

Test IDs have been added to key UI elements following a consistent naming pattern:

  • Root page container
  • Main invitation card
  • Claimed status card
  • Signup form drawer

This significantly improves the testability of the invitation page template.

Also applies to: 173-176, 233-236, 317-317

editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/_components/invitation.tsx (1)

7-9: LGTM! Template imports migrated to enterprise paths.

All three invitation-related imports (InvitationPageTemplate, InvitationCouponTemplate, and TemplateData) have been consistently updated to reference the enterprise/west-referral namespace.

editor/app/(tenant)/~/[tenant]/(r)/r/[slug]/t/[code]/page.tsx (1)

12-12: LGTM! Import path updated to enterprise-specific template.

Verification confirms all old imports have been fully migrated from @/theme/templates/west-referral/templates to the enterprise-specific path. No remaining legacy imports found in the codebase.

editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx (1)

59-61: Verify template ID prefix matches intended template.

The check uses "grida_west_referral.duo-000" but renders EnterpriseWestReferralDuo001Editor. Please confirm this is the intended mapping (e.g., "duo-000" is the template family prefix, "duo-001" is the editor version).

editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx (6)

33-39: LGTM!

Clean entry point that properly delegates to the internal TemplateEditor while maintaining type safety through the generic WWWTemplateEditorInstance.


146-160: Verify intentional use of mock campaign data.

The viewer receives hardcoded empty values (id: "", title: "", etc.) while actual campaign data is available from useCampaign(). If this is intentional for preview isolation, consider adding a comment. If the viewer needs real campaign data, this should use the campaign variable.


126-138: LGTM!

Good use of toast.promise for save feedback and proper disabled state management based on dirty and saving states.


104-104: LGTM!

Good use of unsaved changes warning to prevent accidental data loss.


167-259: LGTM!

The referrer tab form fields have consistent value/onChange paths and proper structure.


481-529: LGTM!

Theme tab properly handles navbar logo editing and locale selection with clean form structure.

Comment on lines +297 to +309
<div className="grid gap-2">
<Label>Button Text</Label>
<Input
value={values?.components?.referrer?.cta}
onChange={(e) => {
props.set(
"components.referrer-share.cta",
e.target.value
);
}}
placeholder="Button Text"
/>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Bug: Button Text reads from wrong component path.

The input displays values?.components?.referrer?.cta but writes to "components.referrer-share.cta". This causes the field to show the wrong value and edits won't appear to persist.

🐛 Proposed fix
                     <div className="grid gap-2">
                       <Label>Button Text</Label>
                       <Input
-                        value={values?.components?.referrer?.cta}
+                        value={values?.components?.["referrer-share"]?.cta}
                         onChange={(e) => {
                           props.set(
                             "components.referrer-share.cta",
                             e.target.value
                           );
                         }}
                         placeholder="Button Text"
                       />
                     </div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="grid gap-2">
<Label>Button Text</Label>
<Input
value={values?.components?.referrer?.cta}
onChange={(e) => {
props.set(
"components.referrer-share.cta",
e.target.value
);
}}
placeholder="Button Text"
/>
</div>
<div className="grid gap-2">
<Label>Button Text</Label>
<Input
value={values?.components?.["referrer-share"]?.cta}
onChange={(e) => {
props.set(
"components.referrer-share.cta",
e.target.value
);
}}
placeholder="Button Text"
/>
</div>
🤖 Prompt for AI Agents
In
@editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/_enterprise/west-referral-duo-001-editor.tsx
around lines 297 - 309, The input is reading from
values?.components?.referrer?.cta but writing to
"components.referrer-share.cta", causing a mismatch; make the getter and setter
use the same component path. Either change the value prop to
values?.components?.["referrer-share"]?.cta to match
props.set("components.referrer-share.cta", ...) or change the setter to
props.set("components.referrer.cta", e.target.value) so both read and write the
same key.

Comment on lines +37 to 49
if (!template_id) {
return (
<div className="h-full flex items-center justify-center">
<span className="text-sm text-muted-foreground">
No template selected.
</span>
</div>
);
}

// NOTE: `template_id` here is the DB `template.id` (UUID), not the template key.
const template =
useWWWTemplate<TemplateData.West_Referrral__Duo_001>(template_id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

React hooks violation: useWWWTemplate is called conditionally.

The early return on lines 37-45 causes useWWWTemplate (line 48-49) to be called conditionally, violating the Rules of Hooks. Hooks must be called in the same order on every render.

🐛 Proposed fix: Move hook call before the early return
 function DesignerRouter() {
   const { template_id } = useWWWLayout();

+  // NOTE: `template_id` here is the DB `template.id` (UUID), not the template key.
+  // Hook must be called unconditionally - pass null/undefined and handle in loading state
+  const template =
+    useWWWTemplate<TemplateData.West_Referrral__Duo_001>(template_id ?? "");
+
   // TODO: make this dynamic.
   // This page is currently statically wired to a specific enterprise template editor.
   // In the future, we should dispatch based on `template.data.template_id` (or template metadata)
   // to support multiple templates without adding more enterprise code here.

   if (!template_id) {
     return (
       <div className="h-full flex items-center justify-center">
         <span className="text-sm text-muted-foreground">
           No template selected.
         </span>
       </div>
     );
   }

-  // NOTE: `template_id` here is the DB `template.id` (UUID), not the template key.
-  const template =
-    useWWWTemplate<TemplateData.West_Referrral__Duo_001>(template_id);
-
   if (template.loading || !template.data) {

Alternatively, if useWWWTemplate doesn't support empty strings, consider extracting the conditional logic into a separate component that only renders when template_id exists.

🧰 Tools
🪛 Biome (2.1.2)

[error] 49-49: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.

Hooks should not be called after an early return.

For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level

(lint/correctness/useHookAtTopLevel)

🤖 Prompt for AI Agents
In
@editor/app/(workbench)/[org]/[proj]/(console)/(campaign)/campaigns/[campaign]/design/page.tsx
around lines 37 - 49, The hook useWWWTemplate is being called conditionally
after an early return based on template_id, violating the Rules of Hooks; move
the call to useWWWTemplate(template_id) (and the typed generic
TemplateData.West_Referrral__Duo_001) above the if (!template_id) check so hooks
run unconditionally, or alternatively extract the UI that depends on template
into a child component (e.g., TemplateViewer) that is only rendered when
template_id exists and calls useWWWTemplate internally.


## `grida_forms`

- [ ] remove each mime specific block, (image, video, pdf, etc) and replace with 'viewer' block. with extra attributes.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix grammar and punctuation in checklist item.

The checklist item has two issues: the abbreviation "etc" should be "etc.", and the phrase "block. with" contains awkward punctuation. Consider rephrasing for clarity:

✏️ Suggested revision
-- [ ] remove each mime specific block, (image, video, pdf, etc) and replace with 'viewer' block. with extra attributes.
+- [ ] Remove each mime-specific block (image, video, pdf, etc.) and replace with a single 'viewer' block with extra attributes.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- [ ] remove each mime specific block, (image, video, pdf, etc) and replace with 'viewer' block. with extra attributes.
- [ ] Remove each mime-specific block (image, video, pdf, etc.) and replace with a single 'viewer' block with extra attributes.
🧰 Tools
🪛 LanguageTool

[style] ~5-~5: In American English, abbreviations like “etc.” require a period.
Context: ...ime specific block, (image, video, pdf, etc) and replace with 'viewer' block. with ...

(ETC_PERIOD)

🤖 Prompt for AI Agents
In @supabase/TODO.md at line 5, Update the checklist item text to correct
punctuation and improve clarity: change "remove each mime specific block,
(image, video, pdf, etc) and replace with 'viewer' block. with extra
attributes." to a clearer sentence such as "Remove each MIME-specific block
(image, video, PDF, etc.) and replace it with a 'viewer' block that includes
extra attributes." Ensure "etc." includes a period, "PDF" is capitalized, and
remove the erroneous period between "block." and "with".

@softmarshmallow softmarshmallow merged commit cf6711e into main Jan 11, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant