403Webshell
Server IP : 65.108.144.40  /  Your IP : 216.73.217.165
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux ubuntu-8gb-hel1-1 5.15.0-173-generic #183-Ubuntu SMP Fri Mar 6 13:29:34 UTC 2026 x86_64
User : dev ( 1000)
PHP Version : 8.2.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/html/support/vue-app/src/components/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/support/vue-app/src/components/tyreWizard.vue
<template>
  <div class="container">
    <div class="cooper-timeline" v-if="currentStep !== 5">
      <timeline :currentStep="currentStep" :currentData="currentData" />
    </div>
    <div class="tyre-wizard" :class="currentStep == 5 ? 'resultsPage' : ''">
      <template v-if="currentStep == 5">
        <div class="tyre-wizard-results-header">
          <svg width="1440" height="370" viewBox="0 0 1440 370" xmlns="http://www.w3.org/2000/svg" class="icon">
            <path d="M0-20h1440v390s-356-17.571-720-17.571S0 370 0 370V-20z"></path>
          </svg>
          <div class="tyre-wizard-results-header-logo">
            <a :href="siteUrl" class=""></a>
          </div>
        </div>
      </template>
      <div class="tyre-wizard-step" :class="currentStep == 5
        ? 'results-header'
        : currentStep == 4
          ? 'inputFormBox'
          : ''
        ">
        <div v-for="data in getCurrentStepData" :key="data.stepNumber">
          <!-- <div class="step-subtitle" :class="currentStep == 5 ? 'results-header' : ''"> -->
          <!-- {{ data.stepSubtitle }} -->
          <!-- </div> -->
          <div class="step-title">
            <h1>{{ data.stepTitle }}</h1>
          </div>
          <div class="step-subtitle" v-if="data.stepInstructions">
            {{ data.stepInstructions }}
          </div>
          <div class="step-options stepOptionParent" v-if="currentStep !== 5" :class="[
            currentStep === 3 ? 'two-columns' : '',
            currentStep === 4 ? 'form-field' : '',
          ]">
            <div v-for="value in data.stepValues" :key="value.value" class="option-single stepOption"
              :class="[value.valueIconType, getActiveClass(value.value)]" @click="
                handleStepValue(value.value);
              toggleActive(value.value);
              ">
              <div class="step-options-imgCard" :style="{
                backgroundImage: `url(${value.valueImg})`,
                backgroundSize: 'cover',
                backgroundRepeat: 'no-repeat',
              }">
                <div class="step-icon" v-if="value.valueIconType == 'text'">
                  <div class="subtitle">
                    {{ value.valueIconSubtitle }}
                    <span class="title">{{ value.valueIconTitle }}</span>
                  </div>
                  <div class="description stepthreeDescription">
                    {{ value.valueDescription }}
                  </div>
                </div>
                <div class="step-ico stepIcon" v-if="value.valueIconType == 'icon'">
                  <div class="icon-single" :class="[value.valueIconTitle, value.valueIconType]">
                    <img v-if="getActiveClass(value.value) == 'active'" :src="value?.checkImg" alt="" />
                    <img v-if="getActiveClass(value.value) != 'active'" :src="value?.unCheckImg" alt="" />
                  </div>
                  <div class="description icon-description">
                    <span>{{ value.valueDescription }}</span>
                    <!-- <span v-if="value.valueIconType == 'icon'" class="learnMore"
                      >Learn more
                      <i class="fa ms-1 fa-angle-right" aria-hidden="true"></i
                    ></span> -->
                  </div>
                </div>
              </div>
            </div>
            <template v-if="currentStep == 4">
              <size-finder @fitment-set="setFitment" tyreWizard />
            </template>
          </div>
        </div>
      </div>

      <section class="tyre-types tyreResultPage" v-if="currentStep === 5">
        <div class="row" :class="paginatedData?.length == 3 ? 'justifyContentCenter' : ''" id="product-container" v-if="paginatedData.length > 0">
          <div class="col-md-3" v-for="product in paginatedData" :key="product.title">
            <div class="cards tyre-info warranty-tag" :class="product.warranty == true ? 'eighty-tag' : ''">
              <a :href="product.link + `?getFilterData=`+ getFilterData" target="_blank">
                <div class="tyre-img">
                  <img :src="product.image[0]" alt="ProControll_RR_Square" />
                </div>
                <div class="tyre-desc">
                  <label>{{ product.tagline }}</label>
                </div>
                <div class="card-footer tyre-detail">
                  <h5>{{ product.title }}</h5>
                  <i class="fa-solid fa-arrow-right"></i>
                  <span>Learn More</span>
                </div>
              </a>
            </div>
          </div>
        </div>
        <!-- Display message if no compatible tyre size is found -->
        <div class="text-center notice-box" v-else>
          <h4>No Compatible Tyre Size Found - Please Review Your Tyre Fit</h4>
          <button @click="prevStep()">Go Back</button>
        </div>
        <!-- <div class="pagination" v-if="productData.length < 12">
          <span class="prev page-numbers" :class="{ disabled: currentPage === 1 }" @click="prevPage">
            Prev
          </span>
          <button v-for="page in totalPages" :key="page" class="page-numbers" :class="{ current: currentPage === page }"
            @click="goToPage(page)">
            {{ page }}
          </button>
          <span class="next page-numbers" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
            Next
          </span>
        </div> -->
      </section>




      <div class="tyre-wizard-footer tyre_wizard_footer" :class="{ 'discover-option': currentStep == 5 }">
        <div class="content grid-container">
          <button class="button-back webBtn" v-if="currentStep != 1" :class="currentStep == 1 ? 'disabled' : ''"
            @click="prevStep()">
            {{ currentStep === 5 ? "DISCOVER MORE OPTIONS" : "Previous" }}
          </button>
          <button v-if="currentStep !== 4" class="button-next" :class="currentData[currentStep] == undefined ||
            currentData[currentStep].length == 0
            ? 'disabled'
            : ''
            " @click="currentData[currentStep].length != 0 ? nextStep() : ''">
            Next
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import SizeFinder from "./sizeFinder.vue";
let baseUrl = "https://coopertiredev.demandtech.org/wp-json/cooper/v1/";
const url = window.location.pathname;
import timeline from "../components/TimeLine.vue";
export default {
  components: { SizeFinder, timeline },
  props: {
    siteUrl: String,
  },
  data: function () {
    return {
      currentStep: 1,
      totalSteps: 5,
      currentData: {
        1: "",
        2: [],
        3: "",
        4: "",
      },
      active: "",
      productData: [],
      currentPage: 1,
      productsPerPage: 5,
      wizardData: {
        steps: [
          {
            stepNumber: 1,
            stepTitle: "How often do you go off road?",
            stepValues: [
              {
                valueIconType: "text",
                valueIconSubtitle: "2",
                valueDescription: "TIMES PER YEAR",
                value: 1,
              },
              {
                valueIconType: "text",
                valueIconSubtitle: "12",
                valueDescription: "TIMES PER YEAR",
                value: 2,
              },
              {
                valueIconType: "text",
                valueIconSubtitle: "52",
                valueDescription: "TIMES PER YEAR",
                value: "touring",
              },
              {
                valueIconType: "text",
                valueIconSubtitle: "365",
                valueDescription: "TIMES PER YEAR",
                value: "touring+",
              },
            ],
          },
          {
            stepNumber: 2,
            stepTitle: "What are your most common offroad experiences?",
            stepInstructions: "(pick up to two)",
            stepValues: [
              {
                checkImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Check.png",
                unCheckImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Uncheck.png",
                valueIconType: "icon",
                valueDescription: "SAND",
                value: "sand",
                valueImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/09/SAND.webp",
              },
              {
                checkImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Check.png",
                unCheckImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Uncheck.png",
                valueIconType: "icon",
                valueDescription: "DIRT/GRAVEL",
                value: "dirt/gravel",
                valueImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/09/DIRTGRAVEL.webp",
              },
              {
                checkImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Check.png",
                unCheckImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Uncheck.png",
                valueIconType: "icon",
                valueDescription: "MUD",
                value: "mud",
                valueImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/09/MUD.webp",
              },
              {
                checkImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Check.png",
                unCheckImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/08/Icon-Uncheck.png",
                valueIconType: "icon",
                valueDescription: "ROCKS",
                value: "rocks",
                valueImg:
                  "https://coopertiredev.demandtech.org/wp-content/uploads/2024/09/ROCKS.webp",
              },
            ],
          },
          {
            stepNumber: 3,
            stepTitle: "Will you be towing a trailer",
            stepValues: [
              {
                valueIconType: "text",
                valueDescription: "Yes",
                value: "towing",
              },
              {
                valueIconType: "text",
                valueDescription: "No",
                value: 1,
              },
            ],
          },
          {
            stepNumber: 4,
            stepSubtitle: "size",
            stepTitle: "What Tyre Size is your vehicle?",
          },
          {
            stepNumber: 5,
            stepSubtitle: "results",
            stepTitle: "Tyres recommended for you",
          },
        ],
      },
    };
  },
  methods: {
    handleStepValue: function (value) {
      if (this.currentStep !== 2) {
        let x = {};
        x[this.currentStep] = value;
        Object.assign(this.currentData, x);
      } else {
        let choiceArray =
          this.currentData[this.currentStep] == undefined
            ? []
            : this.currentData[this.currentStep];
        if (choiceArray.length == 0) {
          choiceArray.push(value);
          this.currentData[this.currentStep] = [...new Set(choiceArray)];
        } else {
          if (choiceArray.includes(value)) {
            choiceArray = choiceArray.filter((x) => {
              return x !== value;
            });
            this.currentData[this.currentStep] = [...new Set(choiceArray)];
          } else if (choiceArray.length < 2) {
            choiceArray.push(value);
            this.currentData[this.currentStep] = [...new Set(choiceArray)];
          }
        }
      }
    },
    toggleActive(value) {
      if (this.currentStep == 2) {
        if (
          value == undefined &&
          this.currentData[this.currentStep] == undefined
        ) {
          this.active = [];
        }
        if (this.currentData[this.currentStep] !== undefined) {
          this.active = this.currentData[this.currentStep];
        }
      } else {
        if (value !== undefined) {
          this.active = value;
        }
      }
    },
    nextStep() {
      window.scrollTo({
        top: 0,
        behavior: "smooth", // This makes the scroll smooth
      });
      if (
        this.currentData[this.currentStep] == undefined ||
        this.currentData[this.currentStep].length == 0
      ) {
        return;
      }
      if (this.currentStep < this.totalSteps) {
        this.currentStep++;
        this.toggleActive(this.currentData[this.currentStep]);
        this.top();
      }
    },
    prevStep() {
      window.scrollTo({
        top: 0,
        behavior: "smooth", // This makes the scroll smooth
      });
      if (this.currentStep !== 1) {
        this.currentStep--;
        this.toggleActive(this.currentData[this.currentStep]);
        this.top();
      }
    },
    setFitment(fitment) {
      this.handleStepValue(fitment);
      this.toggleActive(fitment);
      this.checkCompatibility();
      this.filteredProducts();
      this.currentStep++;
      this.top();
    },
    getActiveClass(value) {
      if (this.currentStep == 2) {
        if (this.active.includes(value)) return "active";
      } else if (value == this.active) {
        return "active";
      } else {
        return "";
      }
    },
    checkCompatibility() {
      this.productData.forEach((x) => {
        x.compatible = false;
        x.sizes.forEach((y) => {
          if (y == this.currentData[4]) {
            x.compatible = true;
            return;
          }
        });
      });
    },
    prevPage() {
      if (this.currentPage > 1) {
        this.currentPage--;
      }
    },
    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.currentPage++;
      }
    },
    goToPage(page) {
      this.currentPage = page;
    },
    filteredProducts() {
      this.productData.forEach((x) => {
        let score = 0;
        x.ratings.forEach((y) => {
          if (
            (y == "touring" && this.currentData[1] == "touring") ||
            (y == "touring" && this.currentData[1] == "touring+")
          ) {
            score++;
          }
          if (y == this.currentData[2][0]) {
            score++;
          }
          if (y == this.currentData[2][1]) {
            score++;
          }
          if (y == this.currentData[3]) {
            score += 5;
          }
          x.score = score;
        });
      });
      this.productData.sort((a, b) => {
        if (a.compatible !== b.compatible) {
          if (b.compatible) return 1;
          if (!b.compatible) return -1;
        }
        if (a.compatible == b.compatible) {
          return b.score - a.score;
        }
      });
    },
    reset() {
      this.currentStep = 1;
      this.active = "";
      this.currentData = {
        1: "",
        2: [],
        3: "",
        4: "",
      };
    },
    top() {
      document.querySelector(".tyre-wizard").scrollTo(0, 0);
    },
  },
  computed: {
    getFilterData() {
      return this.$store.state.filterData;
    },
    getCurrentStepData() {
      return this.wizardData.steps.filter((x) => {
        return x.stepNumber == this.currentStep;
      });
    },
    totalPages() {
      return Math.ceil(this.productData.length / this.productsPerPage);
    },
    paginatedData() {
      const start = (this.currentPage - 1) * this.productsPerPage;
      const end = start + this.productsPerPage;
      const filterData = this.getFilterData; // Get filter data
      let filteredResults = this.productData.filter((item) => {
        // Check if any of the item's sizes match the filter data
        return item.sizes.some((size) => filterData.includes(size));
      });

      return filteredResults;

    },
  },
  mounted: function () {
    this.fetch = Promise.all([
      fetch(`${baseUrl}wizardProducts`, {
        method: "GET",
        credentials: "same-origin",
        headers: {
          "Content-Type": "application/json",
          accept: "application/json",
        },
      }).then((response) => {
        if (!response.ok) {
          throw new Error("HTTP status " + response.status);
        }
        return response.json();
      }),
    ]).then((results) => {
      let formattedResults = JSON.parse(results);
      formattedResults.forEach((x) => {
        x.ratings = x.ratings.replace(/ \| /g, ",").split(",");
        x.compatible = false;
        x.sizes = Object.values(x.sizes).map((y) => {
          return y;
        });
      });

      this.productData = formattedResults;
    });
    const url = window.location.pathname;
  },
};
</script>

<style>
@import "../assets/style.scss";
</style>

Youez - 2016 - github.com/yon3zu
LinuXploit