@millerbyte/react-logging

Client API

Last updated: 2/22/2026

The createLoggingClient helper creates a configured client with methods for fetching sessions, actions, and analytics from your logging API.

createLoggingClient

import { createLoggingClient } from "@millerbyte/react-logging";

const loggingClient = createLoggingClient({
  baseUrl: "/api/logging",
  headers: () => {
    const token = localStorage.getItem("token");
    return token ? { Authorization: `Bearer ${token}` } : {};
  },
  responseCase: "camel",
});

Options

OptionTypeDefaultDescription
baseUrlstring/api/loggingBase URL for API requests
fetchertypeof fetchfetchCustom fetch implementation
headersHeadersInit | () => HeadersInit-Static or dynamic headers
requestInitRequestInit | (ctx) => RequestInit-Per-request overrides
responseCase"camel" | "pascal""camel"API response casing

Headers Configuration

Headers can be static or dynamic (async function):

// Static headers
const client = createLoggingClient({
  headers: { "X-API-Key": "my-key" },
});

// Dynamic headers (useful for auth tokens)
const client = createLoggingClient({
  headers: async () => {
    const token = await getAuthToken();
    return { Authorization: `Bearer ${token}` };
  },
});

Request Init

Pass additional fetch options per request:

const client = createLoggingClient({
  requestInit: ({ path, method }) => ({
    signal: abortController.signal,
    credentials: "include",
  }),
});

Response Casing

By default, the client expects ASP.NET-style camelCase JSON responses. If your API returns PascalCase, set responseCase: "pascal":

// For PascalCase API responses
const client = createLoggingClient({
  responseCase: "pascal",
});

// Expected response format:
{
  Data: [...],
  TotalCount: 100,
  PageIndex: 0,
  PageSize: 10,
  TotalPages: 10
}

Client Methods

The client returns 7 pre-configured fetch methods:

fetchSessions

const result = await loggingClient.fetchSessions({
  pageIndex: 0,
  pageSize: 10,
  sorting: [{ id: "LoginTime", desc: true }],
  filters: { isActive: true },
});
// Returns: PaginatedResponse<LoginSessionDto>

fetchSessionById

const session = await loggingClient.fetchSessionById("session-id-here");
// Returns: LoginSessionDto

fetchActions

const result = await loggingClient.fetchActions({
  pageIndex: 0,
  pageSize: 25,
  sorting: [],
  filters: { statusCodes: [500, 503] },
});
// Returns: PaginatedResponse<ApiActionDto>

fetchActionById

const action = await loggingClient.fetchActionById("action-id-here");
// Returns: ApiActionDto

fetchSessionActions

const result = await loggingClient.fetchSessionActions("session-id", {
  pageIndex: 0,
  pageSize: 50,
  sorting: [],
  filters: {},
});
// Returns: PaginatedResponse<ApiActionDto>

fetchUsers

const result = await loggingClient.fetchUsers({
  pageIndex: 0,
  pageSize: 25,
  sorting: [{ id: "LastActivity", desc: true }],
  filters: { searchText: "john" },
});
// Returns: PaginatedResponse<UserSummaryDto>

fetchAnalytics

const metrics = await loggingClient.fetchAnalytics({
  from: "2024-01-01T00:00:00Z",
  to: "2024-01-31T23:59:59Z",
});
// Returns: AnalyticsMetrics

buildLoggingQueryParams

Utility function to convert query params to URL search string. Useful for custom fetch implementations.

import { buildLoggingQueryParams } from "@millerbyte/react-logging";

const params = {
  pageIndex: 0,
  pageSize: 10,
  sorting: [{ id: "TimeStamp", desc: true }],
  filters: {
    userId: "user123",
    statusCodes: [200, 201],
    dateRange: { from: "2024-01-01", to: "2024-01-31" },
  },
};

const queryString = buildLoggingQueryParams(params);
// Result: "PageIndex=0&PageSize=10&Sorting[0].Id=TimeStamp&Sorting[0].Desc=true&..."

Custom Fetch Implementation

You can skip the client helper entirely and implement your own fetch functions. Just match the expected signature:

const myFetchSessions = async (params: QueryParams): Promise<PaginatedResponse<LoginSessionDto>> => {
  const query = buildLoggingQueryParams(params);
  const response = await fetch(`/my-api/sessions?${query}`, {
    headers: { Authorization: `Bearer ${token}` },
  });
  
  if (!response.ok) {
    throw new Error("Failed to fetch sessions");
  }
  
  return response.json();
};

// Use with components
<SessionList fetchSessions={myFetchSessions} />

Utility Functions

The package also exports these utility functions:

Formatters

import { 
  formatDate, 
  formatDuration, 
  formatNumber,
  getStatusTone,
  stringifyJson 
} from "@millerbyte/react-logging";

// Format ISO date string
formatDate("2024-01-15T10:30:00Z"); // "Jan 15, 2024, 10:30 AM"

// Format duration in milliseconds
formatDuration(1500); // "1.5s"
formatDuration(45);   // "45ms"

// Format numbers with locale
formatNumber(12345); // "12,345"

// Get CSS class based on status code
getStatusTone(200); // "success"
getStatusTone(404); // "warning"
getStatusTone(500); // "error"

// Stringify JSON with formatting
stringifyJson({ user: "john" }); // Pretty-printed JSON

Filter Utilities

import { 
  applySessionFilters, 
  applyActionFilters 
} from "@millerbyte/react-logging";

// Client-side filtering for client mode
const filteredSessions = applySessionFilters(sessions, {
  userId: "user123",
  isActive: true,
});

const filteredActions = applyActionFilters(actions, {
  statusCodes: [500, 503],
  methods: ["POST", "PUT"],
});

Analytics & Timeline Builders

import { 
  buildAnalyticsMetrics, 
  buildTimelineItems 
} from "@millerbyte/react-logging";

// Build metrics from raw data
const metrics = buildAnalyticsMetrics(sessions, actions);
// { totalSessions, activeSessions, totalActions, ... }

// Build timeline items for Timeline component
const timelineItems = buildTimelineItems(sessions, actions);
// Sorted chronological list of session/action events

Default Labels

import { 
  defaultCommonLabels, 
  defaultTableLabels, 
  defaultFilterLabels 
} from "@millerbyte/react-logging";

// Extend defaults with your own labels
const customLabels = {
  ...defaultTableLabels,
  loading: "Fetching data...",
  empty: "No records found",
};

<SessionList labels={customLabels} />