# Strategies and Steps Architecture

This document outlines the architectural patterns used in the Tulip Appointments Web Widget to manage the flow of user selection ("Steps") and the logic for data retrieval ("Strategies").

## Overview

The application is built around a "Wizard" concept where a user progresses through a series of choices (e.g., Select a Store -> Select a Service -> Book). 
- **Steps** define the *configuration* and *state* of each stage in this wizard.
- **Strategies** define the *logic* for fetching and filtering the data shown in each step.

## Strategies

Located in `src/Strategy/`, Strategies encapsulate the logic for interacting with the TimeKit API to retrieve specific types of projects (Stores, Services, etc.).

### Key Components

*   **`ProjectsStrategy.js` (The Factory)**
    *   Acts as the central registry and factory for all strategies.
    *   Exposes `getStrategy(type)` which returns a specific strategy instance based on a string key (e.g., `'store_project'`, `'service_project'`).
    *   Manages the singleton instances of the specific strategies.

*   **`LocationsStrategy.js` (`store_project`)**
    *   Responsible for fetching "Store" projects.
    *   Handles filtering by `t_store_id`.
    *   Used when the step requires the user to pick a physical location.

*   **`ServiceProjectsStatergy.js` (`service_project`)**
    *   Responsible for fetching "Service" or "Appointment Type" projects.
    *   Handles filtering by `t_service_id` (and potentially cross-referencing with selected stores).

*   **`DefaultProjectStrategy.js`**
    *   Provides a fallback or combined logic flow, often chaining location and service retrieval.

### Usage
The UI layer typically requests a strategy via the factory:
```javascript
const strategy = projectsStrategy.getStrategy('store_project');
const projects = await strategy.getProjects(filters);
```

## Steps

Located in `src/Steps/`, the Steps system manages the configuration provided by the user (via `selectorOptions`) and tracks the user's progress.

### Key Components

*   **`StepsFactory.js` (The Manager)**
    *   Initialized with the `selectorOptions` object from the main configuration.
    *   Converts the configuration object into an array of `Step` instances.
    *   Tracks the `currentStepNum`.
    *   Provides methods for navigation (`nextStep()`, `previousStep()`, `currentStep()`).

*   **`Step.js`**
    *   Represents a single screen or stage in the widget.
    *   **Links to Strategy:** Contains a `projectType` or `strategy` field (e.g., `'store_project'`) that tells the UI which Strategy to use to fetch data for this step.
    *   **Filters:** Holds `defaultFilters` (configured globally) and `stepFilters` (dynamic filters for this specific step).

*   **`StepOptions.js`**
    *   Encapsulates configuration for the step's container UI.
    *   Properties: `title`, `description`, `searchBar` config, `geoSearchBar` config.

*   **`StepDataOptions.js`**
    *   Encapsulates configuration for how *items* within the step are rendered (the cards).
    *   Properties: `cardTitle`, `cardBody`, `cardFooter`, `cardImage`.
    *   Supports template strings (e.g., `{{[meta]city}}`).

## Interaction Flow

1.  **Initialization:**
    *   The user configures `selectorOptions` in `timekit_project_selector.init()`.
    *   `StepsFactory` reads this and creates a list of `Step` objects.

2.  **Rendering a Step:**
    *   The UI asks `StepsFactory` for the `currentStep()`.
    *   The UI reads the `StepOptions` to render the header (Title, Search Bar).
    *   The UI reads the `strategy` key from the `Step`.
    *   The UI uses `ProjectsStrategy` to get the actual Strategy object.
    *   The UI calls `strategy.getProjects()` to get the data.

3.  **Rendering Items:**
    *   The UI iterates over the returned projects.
    *   It uses `StepDataOptions` from the current `Step` to resolve template strings and render the cards.

4.  **Navigation:**
    *   When a user selects an item, the UI captures the selection.
    *   It may add a filter to the `StepsFactory` for the *next* step (e.g., "User selected Store A, so filter Services by Store A").
    *   The UI calls `StepsFactory.nextStep()` and repeats the process.
