Help with getting symbol to work

Builder public api key
869cdfafcf774c72803307f3946c15b0

Symbol - LP nearby workshops

I have a symbol created that should be able to display any nearby events available that meet the criteria. I currently have it toggled on to show these nearby events, but it doesn’t seem to be working. I’m not sure if it’s the symbol or it could be the code entirely.

This is what I currently have showing and this is what it’s supposed to look like.


Code for the Nearby Workshop Wrapper

import React, { ReactNode, useEffect, useState } from "react";
import { Builder, withChildren, StateProvider } from "@builder.io/react";
import { Domain, Venue, Vertical, Workshop } from "@/functions/alfred";
import { uniqBy } from "lodash";

type GeocodeResponse = {
  results: { geometry: { location: { lat: number; lng: number } } }[];
};

const stateCountry = [
  {
    country: "United States",
    countryAbbr: "US",
    statesLong: [
      "Alabama",
      "Alaska",
      "Arizona",
      "Arkansas",
      "California",
      "Colorado",
      "Connecticut",
      "Delaware",
      "District of Columbia",
      "Florida",
      "Georgia",
      "Hawaii",
      "Idaho",
      "Illinois",
      "Indiana",
      "Iowa",
      "Kansas",
      "Kentucky",
      "Louisiana",
      "Maine",
      "Maryland",
      "Massachusetts",
      "Michigan",
      "Minnesota",
      "Mississippi",
      "Missouri",
      "Montana",
      "Nebraska",
      "Nevada",
      "New Hampshire",
      "New Jersey",
      "New Mexico",
      "New York",
      "North Carolina",
      "North Dakota",
      "Ohio",
      "Oklahoma",
      "Oregon",
      "Pennsylvania",
      "Rhode Island",
      "South Carolina",
      "South Dakota",
      "Tennessee",
      "Texas",
      "Utah",
      "Vermont",
      "Virginia",
      "Washington",
      "West Virginia",
      "Wisconsin",
      "Wyoming",
    ],
    statesAbbr: [
      "AL",
      "AK",
      "AZ",
      "AR",
      "CA",
      "CO",
      "CT",
      "DE",
      "FL",
      "GA",
      "HI",
      "ID",
      "IL",
      "IN",
      "IA",
      "KS",
      "KY",
      "LA",
      "ME",
      "MD",
      "MA",
      "MI",
      "MN",
      "MS",
      "MO",
      "MT",
      "NE",
      "NV",
      "NH",
      "NJ",
      "NM",
      "NY",
      "NC",
      "ND",
      "OH",
      "OK",
      "OR",
      "PA",
      "RI",
      "SC",
      "SD",
      "TN",
      "TX",
      "UT",
      "VT",
      "VA",
      "WA",
      "WV",
      "WI",
      "WY",
    ],
  },
  {
    country: "Canada",
    countryAbbr: "CA",
    statesLong: [
      "Alberta",
      "British Columbia",
      "Manitoba",
      "New Brunswick",
      "Newfoundland and Labrador",
      "Northwest Territories",
      "Nova Scotia",
      "Nunavut",
      "Ontario",
      "Prince Edward Island",
      "Quebec",
      "Saskatchewan",
      "Yukon Territory",
    ],
    statesAbbr: [
      "AB",
      "BC",
      "MB",
      "NB",
      "NL",
      "NS",
      "ON",
      "PE",
      "QC",
      "SK",
      "NT",
      "NU",
      "YT",
    ],
  },
];

class NearbyVisual {
  firstRun: Boolean = true;
  venue: Venue;
  vertical: Vertical;
  workshop: Workshop;
  domain: Domain;
  numberOfWorkshops: number;

  constructor({
    venue,
    vertical,
    workshop,
    numberOfWorkshops,
    domain,
  }: {
    venue: Venue;
    vertical: Vertical;
    workshop: Workshop;
    numberOfWorkshops: number;
    domain: Domain;
  }) {
    this.venue = venue;
    this.vertical = vertical;
    this.workshop = workshop;
    this.numberOfWorkshops = numberOfWorkshops;
    this.domain = domain;
  }

  getCountryForState(venueState: string) {
    const countryFound = stateCountry.filter((country) =>
      country.statesAbbr.includes(venueState)
    );
    return countryFound;
  }

  getLocationForState(country: string, venueState: string) {
    const uri = `https://maps.googleapis.com/maps/api/geocode/json?address=${venueState}&components=country:${country}&sensor=false&key=AIzaSyDybLJkmeSefOVacWnRAtDEFWr6Env-YhA`;
    return this.sendGet<GeocodeResponse>(uri);
  }

  async getStateGeoLocation(venueState: string) {
    const countryFound = this.getCountryForState(venueState);

    if (Array.isArray(countryFound) && countryFound.length > 0) {
      const country = countryFound[0].countryAbbr;
      const googleMapReturn = await this.getLocationForState(
        country,
        venueState
      );
      if ("status" in googleMapReturn && googleMapReturn.status == "OK") {
        const result = googleMapReturn.results[0];
        const latitude = result.geometry.location.lat;
        const longitude = result.geometry.location.lng;
        const geo = {
          coordinates: [longitude, latitude],
          type: "Point",
        };
        return geo;
      }
    }
  }

  async getNearbyWorkshopsWithGeo(
    geo: Venue["geo"],
    venueState: string,
    radius = 25,
    stateFilter = false
  ) {
    const results = await this.getNearByEvents(this.vertical?.id, geo, radius);
    const workshops = results.filter(
      (record: { distance: any; workshop: any }) => {
        const { distance, workshop = {} } = record;
        if (workshop._id && workshop._id.value == this.workshop?.id) {
          return false;
        }
        if (
          !workshop.page ||
          !workshop.title ||
          !workshop.status ||
          !workshop.type ||
          workshop.status.toUpperCase() != "ACTIVE"
        ) {
          return false;
        }
        if ("is_full" in workshop && workshop.is_full == true) {
          return false;
        }
        if (stateFilter && "state" in workshop.venue_details) {
          const workshopState = workshop.venue_details.state.toUpperCase();
          if (workshopState != venueState) {
            return false;
          }
        }

        const events = workshop.events;
        if (events && Array.isArray(events) && events.length > 0) {
          const filteredEvents = events
            .filter((event_record) => {
              const { cur_registrants = 0, max_registrants = 0 } = event_record;
              return Number(cur_registrants) < Number(max_registrants);
            })
            .filter((event_record) => {
              const { is_full = false } = event_record;
              return !is_full;
            })
            .filter((event_record) => {
              const { event_status = "ACTIVE" } = event_record;
              return event_status.toUpperCase() === "ACTIVE";
            })
            .filter((event_record) => {
              const { date = 0 } = event_record;
              return date > new Date().getTime();
            });
          return Array.isArray(filteredEvents) && filteredEvents.length > 0;
        }

        return true;
      }
    );

    return workshops;
  }

  // Entry point
  async getNearbyWorkshops() {
    const { geo = null, ...venue } = this.venue || {};
    const numberOfWorkshops = this.numberOfWorkshops;
    if (!geo) {
      console.log("no geo");
      return [];
    }
    const venueState = this.venue.state?.toUpperCase() || "";
    const nearWorkshops = await this.getNearbyWorkshopsWithGeo(
      geo,
      venueState,
      25,
      false
    );
    const stateWorkshops = await (async function (c) {
      if (!(nearWorkshops.length < numberOfWorkshops)) {
        if (venueState.length == 2) {
          const stateGeo = await c.getStateGeoLocation(venueState);
          return await c.getNearbyWorkshopsWithGeo(
            stateGeo,
            venueState,
            600,
            true
          );
        }
      }
      return [];
    })(this);

    const workshops = uniqBy(
      [...nearWorkshops, ...stateWorkshops],
      "workshop.title"
    )
      .sort((a: { distance: number }, b: { distance: number }) => {
        return a.distance - b.distance;
      })
      .slice(0, this.numberOfWorkshops);

    if (workshops.length > 0) return workshops;

    return [];
  }

  getVenueLocation(id: string) {
    const uri = `${this.domain?.baseUrl}/api/v1/venues/${id}`;
    return this.sendGet(uri);
  }

  getNearByEvents(verticalId: string, geo: Venue["geo"], radius = 25) {
    const uri = `${this.domain?.baseUrl}/api/v1/workshops:nearby`;
    const body = {
      verticals: [
        {
          value: verticalId,
        },
      ],
      radius: radius,
      isOnlyAvailable: true,
      center: geo,
      status: "ACTIVE",
    };
    return this.sendPost<{ distance: number; workshop: { title: string } }[]>(
      uri,
      body
    );
  }

  sendGet<T = {}>(uri: string): Promise<T>;
  sendGet(uri: string) {
    return fetch(uri, {
      method: "GET",
    }).then((response) => {
      if (response.ok) {
        return response.json();
      }
      return {};
    });
  }

  sendPost<T = {}>(uri: string, body: object): Promise<T>;
  sendPost(uri: string, body: object) {
    return fetch(uri, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
      mode: "cors",
    }).then((response) => {
      return response.json();
    });
  }
}

export { NearbyVisual };

type NearbyWorkshopsWrapperComponentProps = {
  builderState: any;
  children: ReactNode;
  numberOfWorkshops: number;
};

export const NearbyWorkshopsWrapperComponent = ({
  children,
  builderState,
  numberOfWorkshops,
}: NearbyWorkshopsWrapperComponentProps) => {
  const [nearbyWorkshops, setNearbyWorkshops] = useState<any[]>([]);

  useEffect(() => {
    const nearbyWorkshopsService = new NearbyVisual({
      venue: builderState.rootState.venue,
      vertical: builderState.rootState.vertical,
      workshop: builderState.rootState.workshop,
      domain: builderState.rootState.domain,
      numberOfWorkshops,
    });

    nearbyWorkshopsService
      .getNearbyWorkshops()
      .then((nearbyWorkshops) => setNearbyWorkshops(nearbyWorkshops));
  }, [
    numberOfWorkshops,
    builderState.rootState.venue,
    builderState.rootState.vertical,
    builderState.rootState.workshop,
    builderState.rootState.domain,
  ]);

  return <StateProvider state={{ nearbyWorkshops }}>{children}</StateProvider>;
};

export const NearbyWorkshopsWrapper = Builder.registerComponent(
  withChildren(NearbyWorkshopsWrapperComponent),
  {
    name: "Nearby Workshops Wrapper",
    inputs: [
      {
        name: "numberOfWorkshops",
        type: "number",
        defaultValue: 5,
        required: true,
      },
    ],
  }
);

Hello @dalia,

There seems to be an issue with symbols using incorrect API of Production instead of Staging, could you please verify the symbol integration code and make sure it’s using the correct API key from staging

Production apiKey=ce289f18ea2a4567bfcc5038d6ea2892
Staging apiKey=869cdfafcf774c72803307f3946c15b0

Let us know how that works for you.

Thank you!

Hey, it seems there’s a mix-up with API keys. Verify the integration code using the correct key from Staging (apiKey=869cdfafcf774c72803307f3946c15b0). Test it out and let me know! For more tech tips, visit

Summary

Azure auto detailing

.
Cheers