Hooks

useDocyrusTenant

Tenant integration for Docyrus native apps. Fetches tenant preferences, builds dateUtils and numberUtils, and wires DateFormatProvider and NumberFormatProvider so every native component picks up the tenant's date and number formats.

iOSAndroidExpo Go

Installation

pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-tenant
Required Packages(3 packages)
pnpm add @docyrus/app-utils @docyrus/api-client @tanstack/react-query

The module exports:

  • <DocyrusTenantProvider>: fetches /v1/tenant/preferences, normalizes the response and mounts <DateFormatProvider> and <NumberFormatProvider> for everything beneath it.
  • useDocyrusTenant(): read-only hook returning { preferences, dateUtils, numberUtils, isLoading } for ad-hoc formatting.
  • normalizeTenantPreferences(envelope): pure helper that converts the API envelope into the shape the @docyrus/app-utils factories expect.

It needs an authenticated RestApiClient and a QueryClientProvider from @tanstack/react-query above the provider.

Requires @docyrus/app-utils >= 0.20.0 (ships a React Native build; no Metro config needed).

Why this exists

The @docyrus/app-utils factories (createDateUtils, createNumberUtils) read preferences keyed in snake_case (date_format, decimal_precision, …). The /v1/tenant/preferences API returns a { preferences: {...} } envelope with camelCase keys (dateFormat, decimalPrecision, …). Without normalization the factories silently fall back to their defaults. The provider unwraps the envelope, mirrors the keys, builds the utils and installs the contexts.

Usage

Mount the provider once near the root, below your auth and query providers:

import { useDocyrusAuth, useDocyrusClient } from '@docyrus/signin/react-native';

import { DocyrusTenantProvider } from '@/hooks/docyrus-native/use-docyrus-tenant';

export function TenantShell({ children }: { children: React.ReactNode }) {
  const { status } = useDocyrusAuth();
  const client = useDocyrusClient();

  return (
    <DocyrusTenantProvider client={client} enabled={status === 'authenticated'}>
      {children}
    </DocyrusTenantProvider>
  );
}

Every component that reads useDateFormat() or useNumberFormat() then uses the tenant's formats without per-screen wiring.

For ad-hoc formatting, read the utils directly:

import { Text } from 'react-native';

import { useDocyrusTenant } from '@/hooks/docyrus-native/use-docyrus-tenant';

export function ChartHeader({ date }: { date: string }) {
  const { dateUtils, isLoading } = useDocyrusTenant();

  if (isLoading || !dateUtils) return <Text>—</Text>;

  return <Text>{dateUtils.formatDateLong(date)}</Text>;
}

API Reference

<DocyrusTenantProvider>

PropTypeDefaultDescription
clientRestApiClient | null | undefined—API client used to fetch /v1/tenant/preferences.
enabledbooleanBoolean(client)Defer the fetch until auth is ready. The fetch never runs without a client.
userTimezonestringdevice time zoneIANA time zone forwarded to createDateUtils. Native default is getDeviceTimeZone() (react-native-localize when installed, else Intl). Pass the user profile's time zone to override.
staleTimenumber1_800_000 (30 min)TanStack Query stale window for the preferences query.
childrenReactNode—Tree to wrap.

The preferences query uses the key ['docyrus', 'tenant', 'preferences'].

useDocyrusTenant()

Takes no parameters. Returns: DocyrusTenantContextValue.

FieldTypeDescription
preferencesTenantPreferences | nullNormalized preferences. null until loaded (or without a provider).
dateUtilsDateUtils | nullcreateDateUtils({ preferences, userTimezone }).
numberUtilsNumberUtils | nullcreateNumberUtils({ preferences }).
isLoadingbooleanTanStack Query loading flag for the preferences fetch.

Formatters installed by the provider

FormatterBehaviour
formatDatedateUtils.formatDate(value); raw string before preferences load or when formatting throws.
formatDateTimedateUtils.formatDateTime(value); same fallback.
formatTimetoLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' }). The preferences payload has no time format yet.
formatNumbernumberUtils.formatNumber(value, { decimalPrecision?, thousandSeparator? }). 'percent' multiplies by 100 and appends %; 'currency' appends the currency code. Non-numeric input is returned as a string.

normalizeTenantPreferences(envelope)

ParameterTypeDescription
envelopeunknownThe full { preferences, tenant, product, enums } envelope, or the inner preferences object.

Returns: TenantPreferences | null. The input keys are kept, and date_format, date_time_format, long_date_format, thousand_separator, decimal_separator, decimal_precision and locale are filled from their camelCase counterparts. Returns null for non-object input.

import { createDateUtils, getTenantPreferences } from '@docyrus/app-utils';

import { normalizeTenantPreferences } from '@/hooks/docyrus-native/use-docyrus-tenant';

const preferences = normalizeTenantPreferences(await getTenantPreferences(client));

if (preferences) {
  const dateUtils = createDateUtils({ preferences, userTimezone: 'Europe/Istanbul' });
}

Type Exports

TypeDescription
DocyrusTenantContextValueShape returned by useDocyrusTenant().
DocyrusTenantProviderPropsProps of <DocyrusTenantProvider>.

On this page