npm package: @rensblitz/customer-instant-feedback-app
Description: A React component library for collecting user feedback with screenshots and annotations
Author: Rens Blitz
Latest version: 3.0.2

# Customer Instant Feedback App

A React component library for collecting user feedback directly within your application. Uses a centralized Supabase backend with reviewer-based authentication.

## Repository layout (this monorepo)

- **`packages/customer-instant-feedback-app`** — the publishable npm package (`npm run build`, `npm publish -w @rensblitz/customer-instant-feedback-app`).
- **`apps/demo`** — local consumer app (workspace `file:` link).
- **`apps/demo-npm`** — same idea, but depends on the **published** package from npm (see `apps/demo-npm/README.md`).
- **`apps/feedback-admin-app`** — standalone admin UI (deploy from repo root; see [`render.yaml`](./render.yaml)).

## Features

- Capture screenshots with feedback
- Annotate specific elements
- Categorize feedback (Bug, UX, Content, Other)
- Reviewer-based authentication (no anonymous feedback)
- Admin UI is a **standalone app** in [`apps/feedback-admin-app/`](./apps/feedback-admin-app/) (not exported from the npm package in v3+)
- Feedback review page for reviewers to see all feedback (including from colleagues)
- Client-side rate limiting
- Input validation

## Installation

In your React project:

```bash
npm install @rensblitz/customer-instant-feedback-app @supabase/supabase-js react react-dom react-router-dom
```

Or with yarn:

```bash
yarn add @rensblitz/customer-instant-feedback-app @supabase/supabase-js react react-dom react-router-dom
```

Or with pnpm:

```bash
pnpm add @rensblitz/customer-instant-feedback-app @supabase/supabase-js react react-dom react-router-dom
```

> **Note:** React, React DOM, React Router, and Supabase are peer dependencies. If your project already has them, you only need to install the feedback package.

### Upgrading from 2.x to 3.x

- **`FeedbackAdminPage` was removed** from the package. Remove any import and route; use the standalone [`apps/feedback-admin-app`](./apps/feedback-admin-app/) (or deploy it separately).
- **`getSupabaseClient`** is now exported if you need direct Supabase access in advanced integrations.

## Quick Start

**Host app integration (typical):** install the package, add Supabase URL + anon key to `.env`, wrap the app with `FeedbackAuthProvider` / `FeedbackProvider`, and pass the `project_id` string from your operator. You do **not** need to run database migrations in your repo—that happens on the Supabase project (see below if you operate that backend). The in-app setup page at `/readme` (`FeedbackReadmePage`) describes only this flow; full operator steps stay in this README.

### 1. Environment variables (host project)

Add these to your **host project's** `.env` file (not this package):

**Vite / Create React App:**
```
VITE_FEEDBACK_SUPABASE_URL=https://your-project.supabase.co
VITE_FEEDBACK_SUPABASE_ANON_KEY=your-anon-key
```

**Next.js:**
```
NEXT_PUBLIC_FEEDBACK_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_FEEDBACK_SUPABASE_ANON_KEY=your-anon-key
```

Get these from Supabase: Project Settings → API. Use the `anon` (public) key.

**TypeScript users:** Add type definitions for these environment variables. For Vite projects, create `src/vite-env.d.ts`:

```typescript
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_FEEDBACK_SUPABASE_URL: string
  readonly VITE_FEEDBACK_SUPABASE_ANON_KEY: string
}
```

For Next.js, add to `next-env.d.ts` or create a similar declaration file.

Alternatively, call `configureFeedbackClient({ url, anonKey })` at app init.

### 2. Database migrations

Run these SQL files in your Supabase SQL editor, in order:

1. `migrations/schema_central.sql` – Creates tables
2. `migrations/extend_feedback_items.sql` – **Skip for new installs.** Only run if you already have `feedback_items` from a previous setup; running on a fresh install will fail.
3. `migrations/rls_central.sql` – RLS policies
4. `migrations/create_admin.sql` – Creates your first admin (replace placeholder UUID)

### 3. Edge Functions (required for admin)

The admin UI uses Edge Functions to create/delete reviewers. Deploy them:

```bash
# From the package root (e.g. node_modules/@rensblitz/customer-instant-feedback-app)
supabase functions deploy create-reviewer
supabase functions deploy delete-reviewer
```

Or copy `supabase/functions/` into your Supabase project and deploy.

### 4. Wrap your app

In your root component (e.g. `App.tsx` or `main.tsx`):

```tsx
import {
  FeedbackAuthProvider,
  FeedbackProvider,
  FeedbackLoginPage,
  FeedbackReviewPage,
} from '@rensblitz/customer-instant-feedback-app';
import '@rensblitz/customer-instant-feedback-app/style.css';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

const projectId = 'your-project-id';

function App() {
  return (
    <FeedbackAuthProvider>
      <BrowserRouter>
        <Routes>
          <Route path="/feedback-login" element={<FeedbackLoginPage />} />
          <Route path="/feedback" element={<FeedbackReviewPage projectId={projectId} />} />
          <Route
            path="/*"
            element={
              <FeedbackProvider projectId={projectId} feedbackReviewPath="/feedback">
                <YourApp />
              </FeedbackProvider>
            }
          />
        </Routes>
      </BrowserRouter>
    </FeedbackAuthProvider>
  );
}
```

**Admin UI** (companies, projects, reviewers) is **not** part of the npm package. Run the standalone app in [`apps/feedback-admin-app/`](./apps/feedback-admin-app/) (see its README) or deploy it separately (e.g. Render).

**Important:** Always import the CSS file. Without it, the feedback modal has no styles.

### 5. Get your project ID

Use the **Feedback Admin** standalone app (in `apps/feedback-admin-app/` in this repo) to create a company and project, then copy the `project_id` (format: `short-code_uuid`) and pass it to `FeedbackProvider` and `FeedbackReviewPage`.

### 6. Create the first admin

1. Create a user in Supabase: Authentication → Users → Add user (email + password)
2. Copy the user's UUID
3. Run the SQL from `migrations/create_admin.sql` (replace the placeholder UUID)

## How it works

- **Reviewers** visit `/feedback-login` to sign in with credentials provided by an admin. Only logged-in reviewers can see and use the feedback widget. They can visit `/feedback` to see all feedback for the project (including from colleagues).
- **Admins** use the standalone **Feedback Admin** app (`apps/feedback-admin-app/` in this repository, or your deployed instance) to manage companies, projects, and reviewers. Only users in the `admins` table can access it.
- **Feedback** is stored in the centralized Supabase project, scoped by project. Each host app passes its `projectId` to identify which project the feedback belongs to.

## Usage

### FeedbackProvider props

```tsx
<FeedbackProvider
  projectId="acme-dash_abc123-uuid"  // Required for full functionality
  enabled={true}
  rateLimitSeconds={30}
  validation={{
    maxCommentLength: 2000,
    maxNameLength: 100,
    maxScreenshotSize: 500000,
  }}
>
  <YourApp />
</FeedbackProvider>
```

- **projectId**: The project identifier from the admin UI. If omitted, a warning banner is shown.
- **enabled**: Toggle the feedback feature on/off.
- **feedbackReviewPath**: Path to the feedback review page (default: `/feedback`). Used for the "View all" link in the feedback toolbar.
- **rateLimitSeconds**: Minimum seconds between submissions.
- **validation**: Input validation limits.

### Rate limiting

```tsx
<FeedbackProvider projectId="..." rateLimitSeconds={60}>
  <YourApp />
</FeedbackProvider>
```

### Validation

```tsx
<FeedbackProvider
  projectId="..."
  validation={{
    maxCommentLength: 500,
    maxNameLength: 50,
    allowScreenshots: true,
    maxScreenshotSize: 1024 * 1024,
  }}
>
  <YourApp />
</FeedbackProvider>
```

## Migrations (central Supabase project)

Run these migrations in your Supabase SQL editor, in order:

1. `migrations/schema_central.sql` – Creates companies, projects, admins, reviewers, and feedback_items tables
2. `migrations/extend_feedback_items.sql` – **Skip for new installs.** Only run if you are upgrading an existing installation that already has a `feedback_items` table from a prior setup. Running on a fresh install will fail.
3. `migrations/rls_central.sql` – RLS policies
4. `migrations/create_admin.sql` – Template for creating first admin(s)

## TypeScript types

```typescript
interface ValidationConfig {
  maxCommentLength?: number;
  maxNameLength?: number;
  allowScreenshots?: boolean;
  maxScreenshotSize?: number;
}

interface FeedbackProviderProps {
  children: React.ReactNode;
  projectId?: string;
  enabled?: boolean;
  rateLimitSeconds?: number;
  validation?: ValidationConfig;
  feedbackReviewPath?: string;
}

interface FeedbackReviewPageProps {
  projectId: string;
}
```

## Development

### Testing the library locally

The `apps/demo/` folder contains a separate app that imports the library like a real consumer would:

1. **First time setup:**
   ```bash
   npm run demo:install
   npm link
   cd demo && npm link @rensblitz/customer-instant-feedback-app
   ```
   Add `VITE_FEEDBACK_SUPABASE_URL` and `VITE_FEEDBACK_SUPABASE_ANON_KEY` to `apps/demo/.env` (copy from `apps/demo/.env.example` if present).

2. **Build the library:**
   ```bash
   npm run build
   ```

3. **Run the demo app:**
   ```bash
   npm run demo
   ```

The demo app imports from `node_modules` using `npm link`, so it works exactly like a real host app. 

**After making changes to the library:**
- Rebuild: `npm run build`
- The demo will hot-reload automatically

**Demo includes** (typical host routes; see `apps/demo/`):
- `/feedback-login` - Login page for reviewers
- `/feedback` - Feedback review page
- `/readme` - Setup guide (also available as `FeedbackReadmePage` for host apps)
- `/` - Demo page with the feedback widget

**Admin** is a separate Vite app: run `npm run admin:dev` from the repo root (see [`apps/feedback-admin-app/README.md`](./apps/feedback-admin-app/README.md)).

### Building for npm

```bash
npm run build
```

Builds the library (ESM, CommonJS, TypeScript declarations, CSS).

### Publishing to npm

```bash
npm publish --access public
```

The package is configured for npm distribution with proper exports.

## License

MIT © Rens Blitz