Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/juanmatz/inspection-form-euroautos/llms.txt

Use this file to discover all available pages before exploring further.

The inspection form is composed of reusable field components. Each component handles a specific input type within a checklist item, and all of them honour the shared readOnly pattern — when readOnly is true, the component renders its current value in a non-interactive display state rather than an editable control. These components can be used independently outside of InspectionForm if you need to build custom inspection section layouts.

ChecklistItemField

ChecklistItemField renders a single row within an inspection checklist. It combines a descriptive label, a three-state StatusSelector, a free-text notes textarea, and a PhotoAttachment button into one cohesive unit. It is the primary building block of every checklist section.

Import

import { ChecklistItemField } from '@/components/fields/ChecklistItemField';

Usage

<ChecklistItemField
  item={{
    id: 'brake-pads-front',
    label: 'Front brake pads',
    required: true,
    allowPhotos: true,
    allowNotes: true,
    status: 'attention',
    notes: 'Approx. 30% remaining — advise replacement within 5,000 km.',
    photos: [],
  }}
  onChange={(updatedItem) => handleItemChange(updatedItem)}
/>

Props

item
ChecklistItem
required
The checklist item data object. The component is fully controlled — all current values (status, notes, photos) are read from this object and written back through onChange.
interface ChecklistItem {
  id: string;
  label: string;
  required?: boolean;
  allowPhotos?: boolean;
  allowNotes?: boolean;
  status: 'ok' | 'attention' | 'critical' | null;
  notes: string;
  photos: string[]; // base64 data URLs
}
onChange
(item: ChecklistItem) => void
Callback invoked whenever the inspector changes the status, edits the notes textarea, or adds or removes a photo. Receives the full updated ChecklistItem object. Wire this to your section state updater to keep the form data in sync.
readOnly
boolean
default:"false"
When true, the status selector, notes textarea, and photo attachment button are all rendered in non-interactive display mode. The existing status badge, note text, and photo thumbnails remain visible.
If item.required is true and item.status is null at form submission time, InspectionForm will block submission and scroll to this field, highlighting it with a validation error border.

StatusSelector

StatusSelector is a three-state toggle that lets the inspector classify a checklist item as OK, Attention, or Critical. Each state is represented by a distinct colour and icon: green check for OK, amber warning for Attention, and red alert for Critical. The selected state is also communicated via aria-pressed for screen reader users.

Import

import { StatusSelector } from '@/components/fields/StatusSelector';

Usage

<StatusSelector
  value="attention"
  onChange={(newStatus) => setStatus(newStatus)}
/>

Props

value
'ok' | 'attention' | 'critical' | null
required
The currently selected status. Pass null to render the selector in its initial unselected state, where all three buttons appear at equal visual weight.
onChange
(value: 'ok' | 'attention' | 'critical') => void
Callback fired when the inspector selects a status. Receives the newly selected status string. Tapping an already-selected status does not deselect it — use a separate clear action if you need to allow returning to null.
disabled
boolean
default:"false"
Disables all three buttons. Visually identical to the readOnly state but semantically communicated via disabled attributes on the underlying buttons.
To allow deselection, wrap StatusSelector and add a clear button that calls onChange(null). The component itself does not render a clear control by default to keep the checklist row compact.

PhotoAttachment

PhotoAttachment provides a photo capture and upload interface within a checklist item. On mobile devices, tapping the attachment button opens the native camera. On desktop, it opens a file picker filtered to image types. Accepted photos are stored as base64 data URLs and displayed as a scrollable thumbnail grid below the attachment button.

Import

import { PhotoAttachment } from '@/components/fields/PhotoAttachment';

Usage

<PhotoAttachment
  photos={item.photos}
  onChange={(updatedPhotos) => handlePhotosChange(updatedPhotos)}
  maxPhotos={6}
  maxSizeMb={8}
/>

Props

photos
string[]
required
The current array of photo data URLs. The component is fully controlled — pass the current array and handle updates via onChange. An empty array renders only the attachment button.
onChange
(photos: string[]) => void
Callback fired when photos are added or removed. Receives the full updated photos array. Individual photo removal is handled by an overlay delete button on each thumbnail.
maxPhotos
number
default:"10"
Maximum number of photos allowed for this field. Once the limit is reached, the attachment button is hidden and a count label (10 / 10) is shown instead.
maxSizeMb
number
default:"5"
Maximum allowed file size per photo in megabytes. Photos exceeding this limit are rejected and an inline error message is shown beneath the attachment button. The check is applied before base64 encoding.
readOnly
boolean
default:"false"
When true, the attachment button is hidden and photo thumbnails are displayed without their delete overlay buttons, making the grid purely presentational.
Photos are stored as base64 data URLs in IndexedDB. For inspections with many high-resolution images, this can significantly increase the size of the stored record. Encourage inspectors to use the in-app camera rather than uploading raw files from a DSLR or high-resolution device camera to keep record sizes manageable.

SignaturePad

SignaturePad renders an HTML <canvas> element on which the inspector draws their signature using a pointer, touch, or stylus input. The captured signature is exported as a base64-encoded SVG string. A Clear button allows the inspector to erase and redraw. When readOnly is true, the canvas is replaced with an <img> tag rendering the stored signature.

Import

import { SignaturePad } from '@/components/fields/SignaturePad';

Usage

<SignaturePad
  value={inspection.signature}
  onChange={(signatureSvg) => setSignature(signatureSvg)}
  width={500}
  height={180}
/>

Props

value
string | null
required
The current signature as a base64-encoded SVG data URL, or null if no signature has been captured yet. When a non-null value is provided on mount, it is rendered onto the canvas immediately.
onChange
(value: string | null) => void
Callback fired when the inspector lifts their pointer after a stroke (on pointerup), and also when they tap the Clear button (which passes null). Debounced by 200 ms to avoid excessive re-renders during fast drawing.
width
number
default:"400"
Width of the signature canvas in CSS pixels. The underlying <canvas> element is also sized using the devicePixelRatio for crisp rendering on high-DPI screens.
height
number
default:"150"
Height of the signature canvas in CSS pixels.
readOnly
boolean
default:"false"
When true, replaces the interactive canvas with a static <img> element rendering the stored signature SVG. The Clear button is also hidden.
On narrow mobile viewports, set width to undefined and apply width: 100% via the component’s className prop. The canvas will stretch to fill its container while maintaining the aspect ratio defined by height.

VehicleInfoFields

VehicleInfoFields renders a grouped set of labelled inputs for vehicle identification details — make, model, year, licence plate, VIN, mileage, and fuel level. These fields appear at the top of the inspection form in the Vehicle Info section. The component accepts a partial Vehicle object, so it can be rendered with only the data that is already known (for example, licence plate pre-populated from the workshop management system) while leaving the rest blank for the inspector to complete.

Import

import { VehicleInfoFields } from '@/components/fields/VehicleInfoFields';

Usage

<VehicleInfoFields
  vehicle={{
    plate: 'BCD-123',
    make: 'BMW',
    model: '320i',
    year: 2019,
  }}
  onChange={(updatedVehicle) => setVehicleInfo(updatedVehicle)}
/>

Props

vehicle
Partial<Vehicle>
required
The current vehicle data object. Only the fields present in the object are pre-populated; all others render as empty inputs. The full Vehicle shape is:
interface Vehicle {
  id: string;
  plate: string;       // Licence plate number
  vin: string;         // Vehicle Identification Number
  make: string;        // e.g. "BMW"
  model: string;       // e.g. "320i"
  year: number;        // e.g. 2019
  colour: string;      // e.g. "Pearl White"
  mileageKm: number;   // Odometer reading at time of inspection
  fuelLevel: number;   // Fuel level 0–100 (percentage)
}
onChange
(vehicle: Partial<Vehicle>) => void
Callback fired on every input change. Receives the merged Partial<Vehicle> object with the updated field value included. Wire this to the inspection form state to keep vehicle data in sync with the rest of the form.
readOnly
boolean
default:"false"
When true, all input fields are rendered as plain text values inside <span> elements styled to match the form grid layout. Use this mode when displaying the vehicle info section inside InspectionReport.
The fuelLevel field is rendered as a visual fuel-gauge slider (0–100) in addition to a numeric input. Both controls are kept in sync. On read-only mode, a static fuel gauge icon is displayed at the appropriate fill level.

Build docs developers (and LLMs) love