Skip to content

@msflib/react-support

Multi-Tenant Support module built on TanStack Query, following the same approach as other @msflib/react-* modules.

Install

pnpm add @msflib/core @msflib/react-support

Peer dependencies

  • react >= 18
  • @tanstack/react-query >= 5

Wrap your app with SupportProvider inside your QueryClientProvider.

API Reference

SupportProvider

A React context provider that manages support tickets and categories for the current user and workspace.

import { SupportProvider } from '@msflib/react-support';

<QueryClientProvider client={queryClient}>
  <SupportProvider>{/* your app */}</SupportProvider>
</QueryClientProvider>;

Props

Prop Type Required Description
children React.ReactNode Yes Child component tree.
options object No Configuration options for the provider. See below for details.

options Configuration

Key Type Default Description
isWorkspaceScoped boolean true If true, support tickets are isolated per workspace.
requireAuth boolean false If true, data will only be fetched when isAuthenticated is true.
isAuthenticated boolean false The authentication status of the user (e.g. from useAuth().status).

In Next.js App Router, SupportProvider must be in a client component ("use client").

'use client';

import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { SupportProvider } from '@msflib/react-support';

const qc = new QueryClient();

export default function Providers({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={qc}>
      <SupportProvider options={{ isWorkspaceScoped: true }}>{children}</SupportProvider>
    </QueryClientProvider>
  );
}

Multi-Tenancy

This module supports multi-tenancy using the options.isWorkspaceScoped setting and the useActiveWorkspace hook from @msflib/react-shared. All API calls are automatically scoped to the current workspace if isWorkspaceScoped is true (default).

Configuration

Configure the support endpoints using the configureApplication function:

import { configureApplication } from '@msflib/core';

configureApplication({
  baseURL: process.env.NEXT_PUBLIC_API_URL!,
  accessTokenKey: 'access_token',
  endpoints: {
    support: {
      support: '/support', // default
    },
  },
});

API & Hook Methods

list

Fetches all support issues for the current workspace from /support (GET) on mount.

getIssue

Synchronous local lookup by issue id from the cached list. Returns undefined if not found.

const issue = getIssue('abc-123');

createIssue

Creates a new support issue (POST).

Payload:

{
  title: string;
  category: string; // e.g. 'general'
  message: string;
}

refetch

Manually refetch the issues list.

Hook Usage

import { useSupport } from '@msflib/react-support';

function SupportPage() {
  const { issues, getIssue, createIssue, refetch, loading } = useSupport();

  if (loading.issues) return <div>Loading...</div>;

  const handleSubmit = async () => {
    await createIssue({
      title: 'Cannot access dashboard',
      category: 'general',
      message: 'I get a 403 error when visiting /dashboard.',
    });
  };

  return (
    <div>
      <button onClick={handleSubmit} disabled={loading.create}>
        Submit Issue
      </button>
      <ul>
        {issues.map((issue) => (
          <li key={issue.id}>
            [{issue.status}] {issue.title}
          </li>
        ))}
      </ul>
    </div>
  );
}

Returned Hook Shape

const {
  issues,
  getIssue,
  createIssue,
  refetch,
  loading,
} = useSupport();

// Shape:
{
  issues: SupportIssue[];
  getIssue: (id: string) => SupportIssue | undefined;
  createIssue: (data: CreateSupportPayload, options?: MutateOptions) => Promise<SupportIssue>;
  refetch: () => void;
  loading: {
    issues: boolean;
    create: boolean;
  };
}

Types

export type SupportIssue = {
  id: string;
  title: string;
  category: string;
  message: string;
  created_at: string;
  status: 'pending' | string;
};

export type CreateSupportPayload = {
  title: string;
  category: string;
  message: string;
};

Notes

  • SupportProvider must be rendered in a client component in Next.js ("use client").
  • The issues query is cached for 60 seconds by default.
  • All API calls are workspace-aware if isWorkspaceScoped is true (default).
  • getIssue performs a local cache lookup — it does not fire a network request.