<!-- 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. */
<?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, [
]));
}
}
<?php
namespace Theme\Views\Molecules\rating;
use ACFToolkit\ViewModels\BaseViewModel;
class RatingViewModel extends BaseViewModel
{
}
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')
})
}
}
.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');
}
}
}
}
<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>
{% include '@molecules/rating/rating.twig' with {
} only %}Fields