Files
supabase/apps/studio/pages
barcofourieandGildas Garcia c8c12a87b4 feat(studio): add support satisfaction survey page (#51648)
## Problem

After a support ticket is resolved, customers receive an email with a
link to a satisfaction survey. That survey page is currently served from
a standalone function outside this repo. We are consolidating it into
the dashboard so it is deployed, monitored and tested with everything
else.

Linear:
[TOOLING-1425](https://linear.app/supabase/issue/TOOLING-1425/build-csat-in-supase-studio)

## Solution

Adds a public page at `/support/csat` that collects the survey answer
and posts it to a new Platform endpoint, `POST /platform/support/csat`,
which records the answer on the support conversation.

Key choices:

- **Pre-auth page**, modelled on `/verify-email`. Customers arrive from
an email and may not have a dashboard session. Hosted platform only;
self-hosted routes to 404.
- **URL shape** `?conversation_id=cnv_…&helpful=yes|no` matches the
links already sent in survey emails, so the email template only needs
its host changed. `helpful` preselects the answer, defaulting to Yes.
- **Copy and behaviour match the existing survey page**: same title,
question, labels, button text, and result messages.
- **Form** uses react-hook-form + zod; Yes/No are toggle buttons, the
comment is optional.
- **States**: missing or malformed ticket reference, already submitted
(409), ticket mismatch (404), and a generic error that keeps the form so
the customer can retry.
- The mutation uses `fetchHandler` directly, like the email-verification
mutation, because the endpoint is not in the generated API types yet.

Screenshot:

<img width="977" height="801" alt="image"
src="https://github.com/user-attachments/assets/2331861e-e8e9-43e1-84fc-3bf5786c145e"
/>


Depends on the Platform endpoint
https://github.com/supabase/platform/pull/40027. Until it is deployed,
submissions fail with the generic error state.

## Review instructions

1. Run Studio against a Platform stack that has the `POST
/platform/support/csat` endpoint.
2. Open `/support/csat?conversation_id=<a support conversation
id>&helpful=yes` while logged out. The page renders without redirecting
to sign in, with Yes preselected.
3. Pick an answer, optionally add a comment, and submit. The success
message appears and the answer is recorded on the conversation.
4. Submit again for the same conversation: the page reports that the
survey has already been submitted.
5. Open the page with no `conversation_id`: the page reports an invalid
ticket.
6. `pnpm --filter studio exec vitest --run
components/interfaces/Support/CsatSurvey` passes (18 tests).

## Checklist

Check all before review:

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which applies the docs
[style
guide](https://github.com/supabase/supabase/tree/master/apps/docs/style-guide)

---------

Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-10-15 10:03:47 +02:00
..
…

Writing pages

Rough guidelines

  • Try to break down your pages into smaller building blocks - components which are tightly coupled to a page can be placed within the folder components/interfaces/xxx/... (Refer to the README.md under the components folder)
  • Keep to using useState hooks for any UI related logic, do not create MobX local stores to handle UI logic.

Template for building pages

import { NextPage } from 'next'
import { withAuth } from 'hooks/misc/withAuth'

// Import the corresponding layout based on the page
import { Layout } from 'components/layouts'

// Import the main building blocks of the page
import { ... } from 'components/interfaces/xxx'

// Import reusable UI components if needed
import { ... } from 'components/ui/xxx'

// Name your page accordingly
const Page: NextPage = () => {

  return (
    <Layout>
      <div>Page content</div>
    </Layout>
  )
}

export default withAuth(Page)