Supyagent
Connected Accounts

React Components

Dashboard React components for partner registration and profile management — PartnerForm, PartnerRegistration, and PartnerProfileView.

React Components

The Supyagent dashboard includes React components for managing partner profiles. These components handle registration, profile editing, and API key display.

PartnerForm

The top-level component that renders either the registration form (for new partners) or the profile view (for existing partners).

import { PartnerForm } from "@/components/settings/partner-form";

<PartnerForm partner={partnerProfile} apiKeyPrefix={apiKeyPrefix} />

Props

PropTypeDescription
partnerPartnerProfile | nullThe current partner profile, or null if not registered
apiKeyPrefixstring | nullThe first characters of the API key (e.g., sk_live_abc...)

Behavior

  • When partner is null, renders the registration form
  • When partner is provided, renders the profile view with edit capability

Usage in a Server Component

The partner settings page fetches data server-side and passes it to PartnerForm:

app/settings/partner/page.tsx
import { createAdminClient } from "@/lib/supabase/admin";
import { createClient } from "@/lib/supabase/server";
import { PartnerForm } from "@/components/settings/partner-form";

export default async function PartnerSettingsPage() {
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();

  if (!user) redirect("/login");

  const admin = createAdminClient();

  const { data: partner } = await admin
    .from("partner_profiles")
    .select("*")
    .eq("user_id", user.id)
    .single();

  const { data: apiKeyRow } = await admin
    .from("api_keys")
    .select("key_prefix")
    .eq("user_id", user.id)
    .eq("is_active", true)
    .order("created_at", { ascending: false })
    .limit(1)
    .single();

  return (
    <PartnerForm
      partner={partner || null}
      apiKeyPrefix={apiKeyRow?.key_prefix || null}
    />
  );
}

Registration State

When no partner profile exists, PartnerForm renders a registration form with four fields:

FieldInput TypeRequiredValidation
Company NameTextYes1-255 characters
WebsiteURLYesValid URL format
Contact EmailEmailNoValid email format
Use CaseTextNoMax 1000 characters

Registration Flow

  1. User fills in the form and clicks Register
  2. The component calls POST /api/partner with the form data
  3. On success, switches to the RegistrationSuccess view
  4. Shows the Partner ID and API key with copy-to-clipboard buttons
┌─────────────────────────────────────────────┐
│  Become a Partner                           │
│  Register to use the Connected Accounts API │
│                                             │
│  Company Name  [_______________]            │
│  Website       [_______________]            │
│  Contact Email [_______________] (optional) │
│  Use Case      [_______________] (optional) │
│                                             │
│  [ Register ]                               │
└─────────────────────────────────────────────┘

Success View

After registration, the component displays the partner ID and API key:

┌─────────────────────────────────────────────┐
│  Partner Profile Created                    │
│  You can now use the Connected Accounts API │
│                                             │
│  Partner ID    550e8400-...440000  [Copy]   │
│  Company       Acme Inc.                    │
│  Status        ● Active                     │
└─────────────────────────────────────────────┘

┌─────────────────────────────────────────────┐
│  API Key                                    │
│  Save this key now — you won't see it again │
│                                             │
│  sk_live_abc123def456...           [Copy]   │
└─────────────────────────────────────────────┘

The API key is only shown once, immediately after registration. The yellow border on the API key card indicates urgency.


Profile View State

When a partner profile exists, PartnerForm renders a view/edit interface.

View Mode

Displays partner details as a read-only summary:

┌──────────────────────────────────────────────┐
│  Partner Profile                     [Edit]  │
│  Your registration for the Connected         │
│  Accounts API                                │
│                                              │
│  Partner ID  550e8400-...440000      [Copy]  │
│  Company     Acme Inc.                       │
│  Website     https://acme.com                │
│  Email       team@acme.com                   │
│  Use Case    AI workflow platform            │
│  Status      ● Active                        │
│  Tier        free                            │
└──────────────────────────────────────────────┘

┌──────────────────────────────────────────────┐
│  API Key                                     │
│  Use this key to authenticate Connected      │
│  Accounts API requests                       │
│                                              │
│  sk_live_abc...         [Manage Keys]        │
└──────────────────────────────────────────────┘

Edit Mode

Clicking Edit switches to inline editing for all fields:

  • Company Name, Website, Contact Email, and Use Case become editable inputs
  • Save button (disabled until changes are detected)
  • Cancel button resets all fields to their original values
  • Changes are saved via PATCH /api/partner

Status Indicators

StatusBadge ColorMeaning
activeGreen (border-green-500/30 text-green-400)Partner is active and can use the API
suspendedRed (border-red-500/30 text-red-400)Partner is suspended — API calls will return 403

API Key Section

  • Shows the API key prefix (e.g., sk_live_abc...) if a key exists
  • Links to the Manage Keys page for full key management
  • Shows a Create Key button if no active key exists

Dependencies

The PartnerForm component uses:

ImportPackageDescription
Card, CardContent, CardHeader, CardTitle, CardDescription@supyagent/uiCard layout components
Button@supyagent/uiAction buttons
Input@supyagent/uiText input fields
Label@supyagent/uiForm labels
Badge@supyagent/uiStatus badges
Loader2, Copy, Checklucide-reactIcons for loading, copy, and success states
PartnerProfile@supyagent/typesTypeScript type for the partner profile

TypeScript Types

PartnerProfile

interface PartnerProfile {
  id: string;
  user_id: string;
  company_name: string;
  website: string;
  contact_email: string | null;
  description: string | null;
  status: "active" | "suspended";
  tier: string;
  created_at: string;
  updated_at: string;
}

ConnectedAccount

interface ConnectedAccount {
  id: string;
  platform_user_id: string;
  external_id: string;
  display_name: string | null;
  metadata: Record<string, unknown>;
  created_at: string;
}

ConnectSession

type ConnectSessionStatus = "pending" | "completed" | "expired" | "failed";

interface ConnectSession {
  id: string;
  connected_account_id: string;
  platform_user_id: string;
  provider: IntegrationProvider;
  status: ConnectSessionStatus;
  redirect_url: string;
  scopes: string[] | null;
  state: string;
  code_verifier: string | null;
  error: string | null;
  created_at: string;
  expires_at: string;
}

All types are exported from @supyagent/types in packages/types/src/database.ts.


Dashboard Navigation

The partner settings page is accessible from the dashboard sidebar:

Settings
  ├── General
  ├── API Keys
  └── Partner      ← /settings/partner

The navigation item uses the Building2 icon from Lucide React.