# HTML Script Demo

This HTML template showcases the following features:

1. **XCE Script Integration:** The template seamlessly integrates the XCE script into the page's `<head>` section, establishing a connection with the XCE platform.
2. **Standard Signal Utilization:** The template effectively employs standard XCE signals, namely `set` and `listen`, to interact with the XCE platform.
   1. **`set` signal:** The `set` signal is utilized to request an offer from the XCE platform and configure currency formatting. Upon successful offer retrieval, the template stores the offer response and element is rendered. In case of an error, it logs the error message to the developer console and element is hidden.
   2. **`listen` signal:** The `listen` signal keeps track of the selected option and logs the selected option and in case the option selected was the 'Yes' option it also logs the previously stored offer response to the developer console.
3. **Custom CTA for Error Handling:** The template showcases a custom CTA button that programmatically updates the element state to an error state if no option was previously selected, highlighting the importance of making a selection before proceeding.

To utilize this template, copy and paste it into your IDE, save it as an `.html` file, and open it in your web browser. Don't forget to open your DevTools!

### HTML Examples

Currently we have a script configured with two different elements: Travel demo and Ticketing demo. Each required their own specific body request.

Copy the desired HTML snippet bellow and paste on your sandbox for testing.

{% hint style="info" %}
Difference between snippets are:  `offer_request` data and the element names: `xce-travel-demo` and `xce-ticket-demo` .
{% endhint %}

{% hint style="warning" %}
**These are Demo scripts.**

`xce-travel-demo` , `xce-ticket-demo` and the  `offer_request` only work for Demo scripts. Partner scripts would have their own elements with different names as well as expect different request body.
{% endhint %}

{% tabs fullWidth="false" %}
{% tab title="Travel" %}

### Travel: Comprehensive protection Offer

This is an example of what you should be seeing:

<div data-with-frame="true"><figure><img src="https://3618586084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwxvN7gOsbkm2yvOydLG3%2Fuploads%2FeHhsRf6QlCYwdL5QhY3b%2Fimage.png?alt=media&#x26;token=0b158750-dff2-4606-821a-51eea6e6373f" alt="XCE Travel Demo"><figcaption></figcaption></figure></div>

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700&family=Roboto&display=swap"
      rel="stylesheet"
    />
    <title>XCE TRAVEL DEMO</title>
    <script type="module" src="https://sandbox.xce.xcover.com/offers-demo/v1/xcover-elements.js" async></script>
    <style>
      html {
        font-family: 'Roboto', sans-serif;
        font-size: 14px;
      }

      main {
        padding: 12px;
      }

      .offer-container {
        border: 1px solid rgba(0, 0, 0, 0.2);
        padding: 16px;
        border-radius: 5px;
      }

      .button {
        display: inline-block;
        padding: 8px 16px;
        margin-bottom: 22px;
        font-size: 12px;
        color: white;
        background-color: #04aa6d;
        border: 2px solid #04aa6d;
        border-radius: 30px;
        text-transform: uppercase;
        text-align: center;
        transition-duration: 0.4s;
      }

      .button:hover {
        background-color: white;
        color: black;
      }
    </style>
  </head>

  <body>
    <main>
      <h1 id="header">Hello World!</h1>
      <p id="description">This is an XCover Elements Travel demo.</p>
      <p>Before selecting an option, click on the following "Checkout" CTA to trigger the element error state</p>
      <button class="button" onclick="onCheckout()">Checkout</button>
      <div class="offer-container">
        <!-- XCover Element tag -->
        <xce-travel-demo></xce-travel-demo>
      </div>
    </main>
    <script>
      /** Define signalLayer in global scope */
      window.signalLayer = window.signalLayer || [];
      let responseData;
      let selectedOption;

      // Helper function to generate ISO date strings
      const getDateRange = (daysFromNow = 8) => {
        const now = new Date();
        const after5Seconds = new Date(now.getTime() + 5 * 1000);
        const endDate = new Date(now.getTime() + daysFromNow * 24 * 60 * 60 * 1000);
        return {
          startDate: after5Seconds.toISOString(),
          endDate: endDate.toISOString(),
        };
      };

      const { startDate, endDate } = getDateRange(8);

      /** Offer request body */
      const offer_request = {
        customer: {
          currency: 'AUD',
          country: 'AU',
          language: 'en',
          ip: '124.168.10.55',
        },
        schema: '',
        partner: {
          transaction_id: '4f3a9e1b-7c2d-4b8a-9e5f-1a2b3c4d5e6g',
          metadata: {
            device:
              'Browser: Mozilla Version: 0.0 Platform: MixAndMatchAU|Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Mobile/15E148 Safari/604.1',
            session_id: '1ebaf939-af73-4232-8ea5-7ce084d8f050',
          },
        },
        context: {
          insured: [
            {
              first_name: 'First',
              last_name: 'Last',
              country: 'AU',
            },
          ],
          total_tickets_price: 344,
          policy_start_date: startDate,
          policy_end_date: endDate,
          departure_country: 'AU',
          destination_country: 'US',
          is_return: false,
          flights: [
            {
              legs: [
                {
                  departure_datetime: startDate,
                  arrival_datetime: endDate,
                  flight_number: 'SK1530',
                  marketing_airline_iata_code: 'SK',
                  marketing_airline_icao_code: 'SAS',
                  operating_airline_iata_code: 'SK',
                  operating_airline_icao_code: 'SAS',
                  departure_airport: 'LHR',
                  arrival_airport: 'ARN',
                  departure_country: 'IT',
                  arrival_country: 'IT',
                },
              ],
            },
          ],
          number_of_children: 0,
          number_of_adults: 1,
          number_of_infants: 0,
          trip_start_date: startDate,
          trip_end_date: endDate,
        },
        extra_fields: ['tax'],
      };

      /** Set signal onSet promise function */
      const onSet = async (request) => {
        try {
          const res = await request;
          responseData = res;
        } catch (err) {
          console.error(err);
        }
      };

      /** Listen signal onChange function */
      const onChange = (args) => {
        if (args.selectedOption !== 'reject') {
          console.log('Insurance selected: ', args);
        } else {
          console.log('No insurance selected: ', args);
        }
        selectedOption = args.selectedOption;
      };

      const onCheckout = () => {
        if (selectedOption) {
          console.log('Valid selection - Checking Out 🎉');
          alert('Valid selection - Checking Out 🎉');
          return;
        }
        console.log('No protection option selected - Block checkout');

        /** Update signal to programatically set error state to true */
        window.signalLayer.push({
          signal: 'update',
          element: 'xce-travel-demo',
          isError: true,
        });
      };

      /** Set signal */
      window.signalLayer.push({
        signal: 'set',
        element: 'xce-travel-demo',
        data: {
          offer_request,
          currency_config: {
            trailingZeroDisplay: 'stripIfInteger',
            customOptions: {
              format: '$%v AUD',
            },
          },
        },
        onSet,
      });

      /** Listen signal */
      window.signalLayer.push({
        signal: 'listen',
        element: 'xce-travel-demo',
        onChange,
      });
    </script>
  </body>
</html>

```

{% endcode %}
{% endtab %}

{% tab title="Ticketing" %}

### Ticketing: Event ticket protection Offer

This is an example of what you should be seeing:

<div data-with-frame="true"><figure><img src="https://3618586084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwxvN7gOsbkm2yvOydLG3%2Fuploads%2FSO33jleW3pMwjYgxPr3O%2Fimage.png?alt=media&#x26;token=c61a20c6-4891-4b1c-a135-6c98881d4b16" alt="XCE Ticketing Demo"><figcaption></figcaption></figure></div>

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700&family=Roboto&display=swap"
      rel="stylesheet"
    />
    <title>XCE TICKET DEMO</title>
    <script type="module" src="https://sandbox.xce.xcover.com/offers-demo/v2/xcover-elements.js" async></script>
    <style>
      html {
        font-family: 'Roboto', sans-serif;
        font-size: 14px;
      }

      main {
        padding: 12px;
      }

      .offer-container {
        border: 1px solid rgba(0, 0, 0, 0.2);
        padding: 16px;
        border-radius: 5px;
      }

      .button {
        display: inline-block;
        padding: 8px 16px;
        margin-bottom: 8px;
        font-size: 12px;
        color: white;
        background-color: #04aa6d;
        border: 2px solid #04aa6d;
        border-radius: 30px;
        text-transform: uppercase;
        text-align: center;
        transition-duration: 0.4s;
      }

      .button:hover {
        background-color: white;
        color: black;
      }
    </style>
  </head>

  <body>
    <main>
      <h1 id="header">Hello World!</h1>
      <p id="description">This is an XCover Elements Ticket demo.</p>
      <p>Before selecting an option, click on the following "Checkout" CTA to trigger the element error state</p>
      <button class="button" onclick="onCheckout()">Checkout</button>
      <div class="offer-container">
        <xce-ticket-demo></xce-ticket-demo>
      </div>
    </main>
    <script>
      window.signalLayer = window.signalLayer || [];

      let responseData;
      let selectedOption;

      // Helper function to generate ISO date strings
      const getDateRange = (daysFromNow = 20) => {
        const now = new Date();
        const futureDate = new Date(now.getTime() + daysFromNow * 24 * 60 * 60 * 1000);
        return {
          startDate: now.toISOString(),
          endDate: futureDate.toISOString(),
        };
      };

      const { endDate } = getDateRange(20);
      // For multiple events
      const { endDate: endDate2 } = getDateRange(27);

      const offer_request = {
        customer: {
          currency: 'AUD',
          country: 'AU',
          language: 'en',
          region: 'NY',
          postcode: '10036',
        },
        schema: '',
        partner: {
          transaction_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
          subsidiary: 'subsidiary',
          customer_id: '123456',
          metadata: {
            context_id: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
            event_id: 'c3d4e5f6-a7b8-9012-cdef-123456789012',
          },
        },
        context: {
          events: [
            {
              id: crypto.randomUUID(),
              start_date: endDate,
              name: 'Event name',
              venue: 'Premium Venue',
              country: 'AU',
              city: 'Sydney',
              ticket_count: 2,
              multiday_event: false,
              total_amount: 852,
              tickets: [
                {
                  price: 426,
                  type: 'GA',
                  status: 'purchased',
                  id: '459624186',
                  seat_info: 'Section A, Row 5, Seat 12',
                },
                {
                  price: 426,
                  type: 'GA',
                  status: 'purchased',
                  id: '459624187',
                  seat_info: 'Section A, Row 5, Seat 13',
                },
              ],
            },
            {
              id: crypto.randomUUID(),
              start_date: endDate2,
              name: 'Event 2 name',
              venue: 'Premium Venue',
              country: 'AU',
              city: 'Sydney',
              ticket_count: 2,
              multiday_event: false,
              total_amount: 900,
              tickets: [
                {
                  price: 450,
                  type: 'VIP',
                  status: 'purchased',
                  id: '459624188',
                  seat_info: 'VIP Section B, Row 2, Seat 8',
                },
                {
                  price: 450,
                  type: 'VIP',
                  status: 'purchased',
                  id: '459624189',
                  seat_info: 'VIP Section B, Row 2, Seat 9',
                },
              ],
            },
          ],
        },
      };

      const onSet = async (request) => {
        try {
          const res = await request;
          responseData = res;
        } catch (err) {
          console.error(err);
        }
      };

      const onChange = (args) => {
        if (args.selectedOption !== 'reject') {
          console.log('Insurance selected: ', args);
        } else {
          console.log('No insurance selected: ', args);
        }
        selectedOption = args.selectedOption;
      };

      const onCheckout = () => {
        if (selectedOption) {
          console.log('Valid selection - Checking Out 🎉');
          alert('Valid selection - Checking Out 🎉');
          return;
        }
        console.log('No protection option selected - Block checkout');
        window.signalLayer.push({
          signal: 'update',
          element: 'xce-ticket-demo',
          isError: true,
        });
      };

      window.signalLayer.push({
        signal: 'set',
        element: 'xce-ticket-demo',
        data: {
          offer_request,
          currency_config: {
            trailingZeroDisplay: 'stripIfInteger',
            customOptions: {
              format: '%m%v USD',
            },
          },
        },
        onSet,
      });

      window.signalLayer.push({
        signal: 'listen',
        element: 'xce-ticket-demo',
        onChange,
      });
    </script>
  </body>
</html>
```

{% endcode %}
{% endtab %}
{% endtabs %}
