Skip to content

Feedback Widget

A centralized feedback system built into the @anglinai/ui CorporateFooter component. Users on any AnglinAI project can submit feedback, which is stored in the tagzen Supabase database and emailed to larry@anglin.com.

How It Works

  1. User clicks Send Feedback in the footer
  2. A compact form appears with a comment field and optional email
  3. On submit, the widget POSTs to the centralized Supabase Edge Function
  4. The function inserts into the feedback table and sends an email notification via Resend

Adding to a Project

Pass the feedbackEndpoint prop to CorporateFooter:

import { CorporateFooter } from '@anglinai/ui';
<CorporateFooter
feedbackEndpoint="https://dktmitcptketnziahoho.supabase.co/functions/v1/feedback"
feedbackProjectName="my-project-name"
versionProps={...}
/>
PropTypeRequiredDescription
feedbackEndpointstringNoURL of the feedback Edge Function. Widget only renders when this is set.
feedbackProjectNamestringNoIdentifies which project the feedback came from. Falls back to the page hostname.

If feedbackEndpoint is omitted, the footer behaves exactly as before β€” no widget is rendered.

Using the FeedbackWidget Standalone

The widget is also exported on its own if you want to place it somewhere other than the footer:

import { FeedbackWidget } from '@anglinai/ui';
<FeedbackWidget
feedbackEndpoint="https://dktmitcptketnziahoho.supabase.co/functions/v1/feedback"
projectName="my-project"
/>

Edge Function

URL: https://dktmitcptketnziahoho.supabase.co/functions/v1/feedback

Method: POST

Request body:

{
"pageUrl": "https://example.com/dashboard",
"comment": "The export button doesn't work on mobile",
"email": "user@example.com",
"project": "my-project",
"userAgent": "Mozilla/5.0 ..."
}
FieldTypeRequiredDescription
pageUrlstringYesFull URL of the page the user was on (auto-captured)
commentstringYesUser’s feedback (max 5000 chars)
emailstringNoUser’s email for follow-up
projectstringNoProject identifier (auto-extracted from URL hostname if omitted)
userAgentstringNoBrowser user agent (auto-captured)

Success response (201):

{
"success": true,
"data": { "message": "Feedback submitted successfully" },
"meta": { "timestamp": "2026-02-21T12:00:00.000Z" }
}

Database

Table: public.feedback (tagzen Supabase instance)

ColumnTypeNotes
iduuidPrimary key, auto-generated
page_urltextNOT NULL
commenttextNOT NULL
emailtextNullable
projecttextExtracted from URL or passed by client
user_agenttextNullable
created_attimestamptzAuto-set

RLS: Anyone can insert. Only service role can read (admin-only access).

Index: idx_feedback_project_created on (project, created_at DESC).

Querying Feedback

Use the Supabase dashboard or the service role key:

-- All feedback, newest first
SELECT * FROM feedback ORDER BY created_at DESC;
-- Feedback for a specific project
SELECT * FROM feedback WHERE project = 'accessible-org-chart' ORDER BY created_at DESC;
-- Feedback with email (users who want a reply)
SELECT * FROM feedback WHERE email IS NOT NULL ORDER BY created_at DESC;

Email Notifications

Every submission triggers an email to larry@anglin.com via Resend with:

  • Subject line showing the project name and a preview of the comment
  • The full comment, page URL, and email (if provided)
  • AnglinAI branded template (royal blue header, white body)

The email send is non-blocking β€” if Resend is down, the feedback is still saved to the database.

Files

FileLocationPurpose
feedback-widget.tsxanglinai-monorepo/packages/ui/src/components/React component
corporate-footer.tsxanglinai-monorepo/packages/ui/src/components/Footer integration
feedback/index.tstagzen/supabase/functions/Supabase Edge Function
20260221000001_feedback_table.sqltagzen/supabase/migrations/Database migration