# QuoteForm



The `QuoteForm` is a comprehensive component for creating and updating
a quote. It serves as a primary interface during the quoting process,
dynamically assembling various sections—product-specific fields, general
policy details, advanced settings, and coverage terms—into a single,
cohesive form. It is designed to be highly configurable and supports
complex, backend-driven field dependencies through constraint
evaluation.

Usage [#usage]

To use the `QuoteForm`, you must provide the `quote` object to be
modified, the full `dataModel`, and a `handleSubmit` function. The
form’s appearance and behavior can be extensively customized through
various `hide...` props and by optionally enabling constraint
evaluation.

```ts
import { QuoteForm } from '@socotra/ec-react-components';
import {
    DataModel,
    QuoteResponse,
    EvaluateConstraintsRequest,
    EvaluateConstraintsResponse,
    DependencyMapResponse,
} from '@socotra/ec-react-schemas';

// Example Usage
const MyQuotePage = ({
    quote,
    dataModel,
    dependencyMap,
}: {
    quote: QuoteResponse,
    dataModel: DataModel,
    dependencyMap: DependencyMapResponse,
}) => {
    const handleSubmit = (quoteRequest) => {
        console.log('Quote Update Request:', quoteRequest);
        // Handle API call to update the quote
    };

    const handleEvaluateConstraints = async (
        request: EvaluateConstraintsRequest,
    ): Promise<EvaluateConstraintsResponse | undefined> => {
        console.log('Evaluating constraints:', request);
        // API call to the backend to get calculated values
        return fetch(/*...- /constraints/evaluate ...*/).then((res) => res.json());
    };

    return (
        <QuoteForm
            quote={quote}
            dataModel={dataModel}
            handleSubmit={handleSubmit}
            dependencyMap={dependencyMap}
            getEvaluatedConstraints={handleEvaluateConstraints}
            submitButtonText='Update Quote'
        />
    );
};
```

Props [#props]

| Prop                      | Type                                                                                        | Description                                                                                                   | Default      |
| ------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------ |
| `quote`                   | `QuoteResponse`                                                                             | The quote object being edited.                                                                                | **Required** |
| `dataModel`               | `DataModel`                                                                                 | The entire resolved data model for the tenant.                                                                | **Required** |
| `handleSubmit`            | `(data: QuoteRequest) => void`                                                              | Callback triggered on submit, receiving the `QuoteRequest` payload.                                           | **Required** |
| `dependencyMap`           | `DependencyMapResponse`                                                                     | Optional map of field dependencies, required to enable constraint evaluation.                                 | `undefined`  |
| `getEvaluatedConstraints` | `(request, tenantLocator, locator) => Promise&lt;EvaluateConstraintsResponse \| undefined>` | Optional async function to call the backend for constraint evaluation. Required for the feature to be active. | `undefined`  |
| `hideDefaultFields`       | `boolean`                                                                                   | If `true`, hides the default “Details” section (e.g., currency, timezone).                                    | `false`      |
| `hideAdvancedFields`      | `boolean`                                                                                   | If `true`, hides the collapsible “Advanced Fields” section.                                                   | `false`      |
| `hideCoverageTerms`       | `boolean`                                                                                   | If `true`, hides the “Coverage Terms” section.                                                                | `false`      |
| `hideAllFields`           | `boolean`                                                                                   | If `true`, hides all dynamically generated sections (Default, Advanced, Coverage Terms, and Product data).    | `false`      |
| `hiddenExceptions`        | `string[]`                                                                                  | When `hideAllFields` is true, provide an array of field names from the product model to still display.        | `[]`         |
| `titles`                  | `object`                                                                                    | An object to override default labels for form sections and fields. See “Labels and Translations” below.       | `{}`         |

…plus other standard form props (`isSubmitting`, `disabled`,
`submitButtonText`, etc.).

State Management [#state-management]

The form manages its state internally using `useState` and
`useEffect`.

* **Data Initialization:** The form’s data is initialized by
  `getDefaultQuoteValues`, which combines data from the `quote`
  object, the relevant `productModel`, and the overall `dataModel`.
* **Prop Synchronization:** A `useEffect` hook tracks changes to the
  incoming `quote` prop. If the prop is updated externally (e.g.,
  after a save operation), the form’s internal state is re-initialized
  to reflect the latest data.
* **Constraint State:** The component maintains an
  `evaluatedConstraints` state. This state is populated by the
  response from the `getEvaluatedConstraints` function and is cleared
  whenever the user modifies the form data, ensuring that constraints
  are re-evaluated on the next relevant change.

Constraint Evaluation [#constraint-evaluation]

This form supports a powerful constraint evaluation system to create
dynamic relationships between fields.

* **Purpose:** To automatically calculate or update the values of
  certain fields based on user input in other fields, without requiring
  a full form submission. For example, selecting a specific “Region”
  could automatically populate a “Tax Rate” field.
* **Activation:** The feature is enabled by providing both the
  `dependencyMap` and `getEvaluatedConstraints` props.
* **Mechanism:**
  1. The `dependencyMap` tells the form which fields depend on others.
  2. When a user changes a field that is a dependency for another, a
     `useEffect` hook is triggered.
  3. This hook calls the `getEvaluatedConstraints` function with a
     payload of the changed data.
  4. The backend service evaluates the data and returns a
     `EvaluateConstraintsResponse` containing the new values for any
     dependent fields.
  5. This response is stored in the `evaluatedConstraints` state,
     which triggers a re-render.
  6. The `dataModelToJSONSchema` utility uses this response to update
     the JSON Schema, making the calculated fields read-only and
     displaying their new values.

Validation [#validation]

Client-side validation is handled by [Ajv ](https://ajv.js.org/). The
schema used for validation is highly dynamic, built on the fly by the
`dataModelToJSONSchema` utility. It combines definitions for default
fields, advanced fields, coverage terms, and product-specific fields.
The `hide...` props directly affect which sections are included in the
schema. When constraint evaluation is active, the schema is further
modified to reflect the calculated values.

Labels and Translations [#labels-and-translations]

The text for UI labels and validation messages can be customized.

**UI Labels**

Labels for sections and fields can be overridden by passing a `titles`
object prop.

| Key                   | Description                                   | Default Value            |
| --------------------- | --------------------------------------------- | ------------------------ |
| `details`             | Title for the main “Details” section.         | `'Details'`              |
| `seeAdvancedDetails`  | Title for the collapsible “Advanced” section. | `'See Advanced Details'` |
| `coverageTerms`       | Title for the “Coverage Terms” section.       | `'Coverage Terms'`       |
| `currency`            | Label for the “Currency” field.               | `'Currency'`             |
| `timezone`            | Label for the “Timezone” field.               | `'Timezone'`             |
| `billingLevel`        | Label for the “Billing Level” field.          | `'Billing Level'`        |
| `billingTrigger`      | Label for the “Billing Trigger” field.        | `'Billing Trigger'`      |
| `durationBasis`       | Label for the “Duration Basis” field.         | `'Duration Basis'`       |
| `delinquencyPlanName` | Label for the “Delinquency Plan” field.       | `'Delinquency Plan'`     |
| `autoRenewalPlanName` | Label for the “Auto-Renewal Plan” field.      | `'Auto-renewal Plan'`    |
| `installmentPlanName` | Label for the “Installment Plan” field.       | `'Installment Plan'`     |
| `truthyLabel`         | Text for a “true” boolean value.              | `'Yes'`                  |
| `falsyLabel`          | Text for a “false” boolean value.             | `'No'`                   |
