Rating

<!-- Error rendering component -->
<!-- TwigException: getLang function does not exist and is not defined in the context -->
<!-- Error: TwigException: getLang function does not exist and is not defined in the context
    at /builds/michaelhulsman/footballrs.net/htdocs/content/themes/footballrs.net/node_modules/@frctl/twig/src/adapter.js:156:24
    at new Promise (<anonymous>)
    at TwigAdapter.render (/builds/michaelhulsman/footballrs.net/htdocs/content/themes/footballrs.net/node_modules/@frctl/twig/src/adapter.js:134:16)
    at ComponentSource._renderVariant (/builds/michaelhulsman/footballrs.net/htdocs/content/themes/footballrs.net/node_modules/@frctl/fractal/src/api/components/source.js:212:30)
    at _renderVariant.next (<anonymous>)
    at onFulfilled (/builds/michaelhulsman/footballrs.net/htdocs/content/themes/footballrs.net/node_modules/co/index.js:65:19) -->
{# ! HAS VUE COMPONENT ! #}
<div class="rating" data-rating-id="{{ rating_id }}">
    <div>
        <div class="inner">
            {% for i in 5..1 %}
                <input type="radio"{% if rating == i %} checked {% endif %}id="{{ rating_id }}_star{{ i }}" name="{{ rating_id }}_rate" value="{{ i }}" />
                <label for="{{ rating_id }}_star{{ i }}" title="{{ t(':n Stern(e)', {'n': i}) }}">
                    {% include '@atoms/icon/icon.twig' with {
                        icon: 'star',
                    } %}
                </label>
            {% endfor %}
        </div>
    </div>
    {% include '@atoms/button/button.twig' with {
        cta: t('Jetzt bewerten'),
        type: 'x-btn--primary',
        className: 'not-logged-in',
        href: {url : route('login.' ~ getLang())}
    } %}
    {% include '@atoms/button/button.twig' with {
        cta: t('Jetzt bewerten'),
        type: 'x-btn--primary',
        className: 'rate !hidden'
    } %}
</div>
/* No context defined. */
  • Content:
    <?php
    
    namespace Theme\Views\Molecules\rating;
    
    use ACFToolkit\Types\CustomMolecule;
    
    
    class Rating extends CustomMolecule
    {
        public string $name = 'rating';
        public string $label = 'Rating';
        public int $needsJs = 1;
        public int $needsVue = 0;
        public int $needsVueInitialisation = 0;
    
        public function __construct($name = '', $title = '', $children = [])
        {
            parent::__construct($name, $title);
            $this->addChildren(array_merge($children, [
            ]));
        }
    }
  • URL: /components/raw/rating/Rating.php
  • Filesystem Path: resources/Views/Molecules/rating/Rating.php
  • Size: 497 Bytes
  • Content:
    <?php
    
    namespace Theme\Views\Molecules\rating;
    
    use ACFToolkit\ViewModels\BaseViewModel;
    
    class RatingViewModel extends BaseViewModel
    {
    }
    
  • URL: /components/raw/rating/RatingViewModel.php
  • Filesystem Path: resources/Views/Molecules/rating/RatingViewModel.php
  • Size: 138 Bytes
  • Content:
    export class Rating {
        static CSS_SELECTOR = '.rating'
    
        static init = () => {
            document.querySelectorAll(Rating.CSS_SELECTOR).forEach(rating => {
                new Rating(rating)
            })
        }
    
        constructor(el) {
            this.el = el
            this.el.querySelector('button.rate').addEventListener('click', e => {
                this.el.classList.add('is-rating')
            })
        }
    }
  • URL: /components/raw/rating/rating.js
  • Filesystem Path: resources/Views/Molecules/rating/rating.js
  • Size: 395 Bytes
  • Content:
    .rating {
      @apply text-center;
    
      > div {
        @apply flex justify-center mb-1;
    
        &:after {
          content: '';
          @apply block clear-both;
        }
      }
    
      input, label {
        @apply pointer-events-none;
      }
    
      &.loading {
        button.rate {
          @apply hidden;
        }
      }
    
      &.is-rating {
        input, label {
          @apply pointer-events-auto;
        }
        .inner {
          &:not(:checked) {
            > label:hover,
            > label:hover ~ label {
              svg g {
                fill: theme('colors.primary');
              }
            }
    
            > input:checked + label:hover,
            > input:checked + label:hover ~ label,
            > input:checked ~ label:hover,
            > input:checked ~ label:hover ~ label,
            > label:hover ~ input:checked ~ label {
              svg g {
                fill: theme('colors.primary');
              }
            }
          }
        }
      }
    
      &.is-selected {
        > input:checked ~ label {
          svg g {
            fill: theme('colors.primary');
          }
        }
      }
    
      .inner {
        @apply float-left inline-block;
    
        &:not(:checked) {
          > input {
            position: absolute;
            top: -9999px;
          }
    
          > label {
            float: right;
            overflow: hidden;
            white-space: nowrap;
            cursor: pointer;
            color: #fff;
            padding-right: 4px;
            width: 20px;
    
            &:first-of-type {
              padding-right: 0;
            }
          }
        }
    
        > input:checked ~ label {
          svg g {
            fill: theme('colors.primary');
          }
        }
      }
    }
  • URL: /components/raw/rating/rating.scss
  • Filesystem Path: resources/Views/Molecules/rating/rating.scss
  • Size: 1.5 KB
  • Content:
    <template>
      <div :class="{
        rating: 1,
        'is-rating': ([modes.select, modes.selected].indexOf(mode) !== -1),
        'is-selected': (mode === modes.selected && selectedRating !== 0)
      }">
        <div>
          <div class="inner" v-if="rating">
            <template v-for="i in 5">
              <input
                type="radio"
                :checked="(mode === modes.selected && i === (selectedRating)) ||
                ([modes.idle, modes.submitted].indexOf(mode) !== -1 && i === (6 - parseInt(rating)))"
                :id="`${ratingId}_star${i}`"
                :name="`${ratingId}_rate`"
                :value="i"
              />
              <label @click.prevent="selectRating(i)" :for="`${ratingId}_star${i}`" :title="i + ' ' + ('Sterne')">
                <i>
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
                    <g fill="none">
                      <path
                        d="M 3.672626256942749 15.12704563140869 L 4.259429931640625 10.57510471343994 C 4.297019958496094 10.28360462188721 4.205160140991211 9.991744995117188 4.007410049438477 9.774334907531738 L 0.9705299735069275 6.435404777526855 L 5.253520011901855 5.618764877319336 C 5.558730125427246 5.560575008392334 5.814949989318848 5.368555068969727 5.956470012664795 5.091935157775879 L 7.999836444854736 1.098075032234192 L 7.999937534332275 1.098075032234192 L 10.04354000091553 5.091935157775879 C 10.18504047393799 5.368545055389404 10.44126033782959 5.560575008392334 10.74647998809814 5.618764877319336 L 15.02947044372559 6.435404777526855 L 11.99258041381836 9.774345397949219 C 11.79483985900879 9.991744995117188 11.70298004150391 10.28360462188721 11.74057006835938 10.57509517669678 L 12.32755088806152 15.12692165374756 L 8.451860427856445 13.16400527954102 C 8.312479972839355 13.09340476989746 8.156229972839355 13.05609512329102 8 13.05609512329102 C 7.843770027160645 13.05609512329102 7.687520027160645 13.09340476989746 7.548140048980713 13.16399478912354 L 3.672626256942749 15.12704563140869 Z"
                        stroke="none"/>
                      <path
                        d="M 8.000001907348633 2.195515632629395 L 6.401590347290039 5.319675445556641 C 6.189310073852539 5.73459529876709 5.804989814758301 6.022624969482422 5.347169876098633 6.109914779663086 L 1.941055297851562 6.759360313415527 L 4.377280235290527 9.437894821166992 C 4.673919677734375 9.764015197753906 4.811710357666016 10.20181465148926 4.755330085754395 10.6390552520752 L 4.289128303527832 14.2542839050293 L 7.322190284729004 12.7179651260376 C 7.531259536743164 12.61206531524658 7.765640258789062 12.55608463287354 8 12.55608463287354 C 8.234330177307129 12.55608463287354 8.468689918518066 12.6120548248291 8.677789688110352 12.71795463562012 L 11.7108736038208 14.2542839050293 L 11.24466991424561 10.63903522491455 C 11.18828964233398 10.20181465148926 11.32608032226562 9.764015197753906 11.62269020080566 9.437925338745117 L 14.05894470214844 6.759360313415527 L 10.65283966064453 6.109914779663086 C 10.19499969482422 6.022624969482422 9.810669898986816 5.734575271606445 9.598409652709961 5.319675445556641 L 8.000001907348633 2.195515632629395 M 8 0.5977535247802734 C 8.176128387451172 0.5977535247802734 8.352254867553711 0.6885051727294922 8.445119857788086 0.8700151443481445 L 10.48865985870361 4.864194869995117 C 10.55891036987305 5.00151538848877 10.6886100769043 5.098725318908691 10.84012985229492 5.127614974975586 L 15.12312030792236 5.944254875183105 C 15.50691986083984 6.017435073852539 15.66224956512451 6.482794761657715 15.39935970306396 6.771835327148438 L 12.36246967315674 10.11077499389648 C 12.26377010345459 10.2192850112915 12.21770000457764 10.36566543579102 12.23645973205566 10.51114463806152 L 12.82347011566162 15.06319522857666 C 12.87479972839355 15.46130466461182 12.45973014831543 15.75456523895264 12.10163974761963 15.57318496704102 L 8.225930213928223 13.61004447937012 C 8.08389949798584 13.53810501098633 7.91610050201416 13.53810501098633 7.774069786071777 13.61004447937012 L 3.898360252380371 15.57318496704102 C 3.540267944335938 15.75456619262695 3.125190734863281 15.46130466461182 3.176529884338379 15.06319522857666 L 3.763540267944336 10.511155128479 C 3.782299995422363 10.36566543579102 3.73622989654541 10.2192850112915 3.637530326843262 10.11077499389648 L 0.6006402969360352 6.771835327148438 C 0.3377504348754883 6.482794761657715 0.4930801391601562 6.017435073852539 0.8768796920776367 5.944254875183105 L 5.159870147705078 5.127614974975586 C 5.311389923095703 5.098725318908691 5.441089630126953 5.00151538848877 5.511340141296387 4.864205360412598 L 7.554880142211914 0.8700151443481445 C 7.647740364074707 0.6885099411010742 7.823870658874512 0.5977535247802734 8 0.5977535247802734 Z"
                        stroke="none" fill="#203d5d"/>
                    </g>
                  </svg>
                </i>
              </label>
            </template>
          </div>
        </div>
        <template v-if="id && loggedIn && ratings">
          <CustomButton
            v-if="getRatingMode === modes.idle"
            type="x-btn--primary"
            :cta="$t('Jetzt bewerten')"
            @click="startRating"
          />
          <CustomButton
            v-if="getRatingMode === modes.select"
            type="x-btn--primary"
            :cta="$t('Bewertung auswählen')"
          />
          <CustomButton
            v-if="getRatingMode === modes.selected"
            type="x-btn--primary"
            :cta="$t('Bewertung abschicken')"
            @click="submitRating"
          />
          <CustomButton
            v-if="getRatingMode === modes.submitted"
            type="x-btn--primary"
            :cta="$t('Danke für die Bewertung')"
          />
          <CustomButton
            v-if="getRatingMode === modes.alreadyRated"
            type="x-btn--outline"
            :cta="$t('Bereits bewertet')"
          />
        </template>
        <CustomButton
          v-if="!loggedIn"
          :loading="loading"
          type="x-btn--primary"
          :cta="$t('Jetzt bewerten')"
          @click="$store.dispatch('Login/showLayer')"
        />
      </div>
    </template>
    <script>
    
    import CustomButton from '../../Atoms/button/button.vue';
    import {mapGetters} from 'vuex';
    import RatingService from '../../Assets/src/js/services/RatingService';
    
    export default {
      name: 'Rating',
      components: {CustomButton},
      props: {
        ratingId: {
          type: String
        },
        area: {
          type: String
        },
        rating: {
          type: Number,
        },
        canRate: {
          type: Boolean,
          default: false
        }
      },
      data: () => {
        return {
          selectedRating: 0,
          mode: 0,
          modes: {
            idle: 0,
            select: 1,
            selected: 2,
            submitted: 3,
            alreadyRated: 4
          }
        }
      },
      computed: {
        ...mapGetters('Member', ['loading', 'loggedIn', 'id', 'ratings']),
        getRatingMode() {
          const areaRatings = this.ratings[this.area] || []
          if (areaRatings.indexOf(parseInt(this.ratingId)) !== -1) {
            return this.modes.alreadyRated
          }
          return this.mode
        }
      },
      methods: {
        startRating() {
          this.mode = this.modes.select
        },
        selectRating(value) {
          if ([this.modes.idle, this.modes.submitted].indexOf(this.mode) !== -1) {
            return
          }
          this.selectedRating = value
          this.mode = this.modes.selected
        },
        async submitRating() {
          this.mode = this.modes.submitted
          await RatingService.rate({
            rating: 6 - this.selectedRating,
            id: this.ratingId,
            area: this.area
          })
        },
      },
      created() {
    
      }
    }
    </script>
  • URL: /components/raw/rating/rating.vue
  • Filesystem Path: resources/Views/Molecules/rating/rating.vue
  • Size: 7.5 KB

title: Rating

{% include '@molecules/rating/rating.twig' with {

} only %}

ACF

Fields