# `@digilabscz/business-hours-js`

Browser widget for editing weekly business hours and storing the result as JSON in a form field.

The package renders a business-hours UI next to an element with the `.js-business-hours` class, keeps the field value synchronized, validates incomplete intervals, and automatically merges overlapping time ranges.

## Installation

```bash
npm install @digilabscz/business-hours-js
```

## What It Does

- Creates an editor for Monday through Sunday
- Lets users add multiple time intervals per day
- Writes the result back to the original field as JSON
- Validates missing `from` / `to` values
- Prevents identical `from` and `to` times
- Reorders reversed ranges like `17:00` -> `09:00`
- Merges overlapping intervals automatically
- Localizes labels from the page `<html lang="...">`

## Usage

Add a form field that will hold the JSON output:

```html
<input
    type="hidden"
    name="business_hours"
    class="js-business-hours"
>
```

Import the package and initialize it manually:

```js
import DigiBusinessHours from '@digilabscz/business-hours-js';

DigiBusinessHours.init();
```

If you render more `.js-business-hours` fields later, you can re-scan the page and initialize only the widgets that were not initialized yet:

```js
DigiBusinessHours.reinit();
```

You can also pass configuration options:

```js
import DigiBusinessHours from '@digilabscz/business-hours-js';

DigiBusinessHours.init({
    addIconColor: '#2563eb',
    removeIconColor: '#dc2626'
});
```

Currently supported options:

- `addIconColor`: color of the add button icon
- `removeIconColor`: color of the remove button icon
- `iconColor`: shared fallback color for both icons

## Initial Value

If the field contains JSON in `value`, that data is used as the initial state.

```html
<input
    type="hidden"
    name="business_hours"
    class="js-business-hours"
    value='{"monday":[{"from":"09:00","to":"17:00"}]}'
>
```

## Template Business Hours

If the field contains `data-default-business-hours`, the widget expects an array of template objects with `name` and `hours`.

- When the array contains one item, the widget renders the apply button.
- When the array contains two or more items, the widget renders a select with template names and an apply button.

Clicking the button replaces the current form state with the selected template and synchronizes the JSON back into `value`.

```html
<input
    type="hidden"
    name="business_hours"
    class="js-business-hours"
    value='{"monday":[{"from":"10:00","to":"18:00"}]}'
    data-default-business-hours='[
        {
            "name":"Pobočka Bratislava",
            "hours":{
                "monday":[{"from":"08:00","to":"16:00"}],
                "tuesday":[{"from":"08:00","to":"16:00"}]
            }
        },
        {
            "name":"Pobočka Brno",
            "hours":{
                "monday":[{"from":"09:00","to":"17:00"}],
                "tuesday":[{"from":"09:00","to":"17:00"}]
            }
        }
    ]'
>
```

You can also trigger the same behavior from JavaScript:

```js
import DigiBusinessHours from '@digilabscz/business-hours-js';

const input = document.querySelector('.js-business-hours');

DigiBusinessHours.applyTemplate(input);
```

You can optionally apply a specific template by index:

```js
DigiBusinessHours.applyTemplate(input, 1);
```

Or replace the editor state directly:

```js
DigiBusinessHours.update(input, {
    monday: [{ from: '08:00', to: '16:00' }],
    tuesday: [{ from: '08:00', to: '16:00' }]
});
```

## Output Format

The widget stores the final value as JSON on the original field.

```json
{
  "monday": [
    { "from": "09:00", "to": "12:00" },
    { "from": "13:00", "to": "17:00" }
  ],
  "tuesday": [
    { "from": "10:00", "to": "16:00" }
  ]
}
```

Only days with at least one valid interval are included.

Supported day keys:

- `monday`
- `tuesday`
- `wednesday`
- `thursday`
- `friday`
- `saturday`
- `sunday`

## Validation

When the user edits intervals:

- empty rows are ignored
- partially filled rows are marked invalid
- partially filled rows keep the last valid JSON output until fixed
- identical `from` and `to` times are invalid
- reversed ranges are automatically swapped
- overlapping intervals are merged into one

The source field also receives a validation flag:

```html
<input
    class="js-business-hours"
    data-business-hours-valid="true"
>
```

When any day contains an invalid interval, the attribute becomes:

```html
data-business-hours-valid="false"
```

## Localization

Labels are selected from `<html lang="...">`.

Built-in translations:

- `cs`
- `sk`
- `en`
- `fr`
- `it`
- `es`
- `de`

If no supported language is found, Czech is used as the fallback.

## Styling

The package injects its own CSS into `document.head` on first initialization. No separate stylesheet import is required.

## Requirements

- Browser environment
- A form field with the `.js-business-hours` class

## License

MIT
