Skip to content

Commit

Permalink
Add VoteMatch Europe support
Browse files Browse the repository at this point in the history
  • Loading branch information
krystof-k committed May 12, 2024
1 parent d0748d0 commit 979f5c5
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 1 deletion.
1 change: 1 addition & 0 deletions frontend/public/images/votematcheurope-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
140 changes: 139 additions & 1 deletion frontend/src/routes/result/ResultPage.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, onBeforeMount, ref, type ComputedRef, type Ref } from 'vue';
import { computed, onMounted, onBeforeMount, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import {
Expand Down Expand Up @@ -225,6 +225,119 @@ const handleSubscribe = async () => {
message.value = t('routes.index.IndexPage.error');
}
};
// VoteMatch integration
const scriptElement = ref<null | HTMLScriptElement>(null);
const loadExternalScript = () => {
const script = document.createElement('script');
script.src = 'https://assets.votematch.eu/embed.min.js';
script.async = true;
document.body.appendChild(script);
scriptElement.value = script;
};
const removeExternalScript = () => {
if (scriptElement.value) {
document.body.removeChild(scriptElement.value);
}
};
const questionMapping = {
// 1: "1687289f-5c80-4ba7-970d-193dbd92dd7d",
2: "34fc9af7-cb43-4081-8e21-a32bb176174e",
3: "d5525dd2-3460-4960-95b8-e80fb76336a3",
4: "594d25eb-955d-420b-892a-16f1e440c976",
5: "1892f2a0-15b1-4a87-b1ee-3ea2bfe62807",
6: "fe511b84-e29e-441d-ac17-efcaa2c3d592",
7: "ac59bb82-2670-4c89-a856-8ca8ee3c3cf0",
8: "71349d6f-6495-4b41-af41-571e16723c7a",
9: "978eabc6-4b90-42bd-8779-bdd1a4273239",
10: "dd7bacb7-80f1-4730-8000-58f52f5cb8aa",
11: "097000bd-ecf3-4219-94b2-5f33ba3ef516",
12: "8a2962b1-32b8-4eb6-9a99-a165492b9e5b",
13: "3a9a1367-76c1-4696-bae1-74fa891cfe7b",
14: "f59d633a-ee3b-44f5-9611-e0cf6765783a",
15: "fbe6cf2b-878f-4031-9edf-883e684eba54",
16: "856aa09a-3368-4570-ae78-559dd0ad009f",
17: "e406e6aa-f9ba-4667-b7ba-d21527df7f2d",
18: "d5bb5b9d-b5bf-4404-adae-c166c0c00026",
19: "29464668-00cb-45a1-bafe-8436aa552cbc",
20: "9569ce88-4ba1-46df-8cf6-b9aeb0917f74",
21: "90d8acec-2741-4dd4-83d6-4adc260d49be",
22: "0936db85-56c2-4d63-89ee-ae6b329ba7d9",
23: "d431ef34-8499-4895-93b7-a0d208d4543f",
24: "1c97cbfb-bc4e-4a73-93bc-103d3fe9baa2",
25: "1cbc2791-3803-4688-91e5-3f8c357593a5",
};
const candidateMapping = {
"AT01": "30973f28-a4b6-4093-beb6-cb9c77de2ecd",
"AT02": "fcf86e19-b470-49a7-a350-0044aac8c603",
"AT03": "b02cacf7-c383-4b01-a463-f5bb559e384a",
"AT04": "94bd387b-45bf-4eb6-ae14-0fe8db7a2323",
"AT05": "0148208f-4166-4615-9472-e38a0121045d",
"AT06": "3d8606ba-c130-4615-b3d0-bb5f09d9138d",
// "AT07": "",
};
const voteMatchLanguage = 'DE';
const voteMatchCountry = 'AT';
const mappedAnswers = computed(
() => electionStore.answers.map(answer => {
const answerMapping = { 1: -1, 3: 0, 2: 1 };
const swappedQuestionMapping = Object.fromEntries(
Object.entries(questionMapping).map(([key, value]) => [value, key])
);
if (swappedQuestionMapping[answer.id] === undefined) return [];
let voteMatchID = swappedQuestionMapping[answer.id];
voteMatchID = voteMatchID.toString().padStart(2, "0");
return {
[`answer${voteMatchID}`]: answerMapping[answer.answer]
};
})
.filter(item => Object.keys(item).length > 0)
.reduce((result, item) => ({ ...result, ...item }), {})
);
const showVoteMatch = computed(() => !!(Object.keys(mappedAnswers.value).length >= 15));
onMounted(() => {
if (showVoteMatch) {

Check failure on line 308 in frontend/src/routes/result/ResultPage.vue

View workflow job for this annotation

GitHub Actions / Build, test & lint

Must use `.value` to read or write the value wrapped by `computed()`
loadExternalScript();
const swappedCandidateMapping = Object.fromEntries(
Object.entries(candidateMapping).map(([key, value]) => [value, key])
);
let bestmatch: string[] = [];

Check failure on line 314 in frontend/src/routes/result/ResultPage.vue

View workflow job for this annotation

GitHub Actions / Build, test & lint

'bestmatch' is never reassigned. Use 'const' instead
resultsGeneral.value.forEach((result, index) => {
if (index === 0) {
bestmatch.push(swappedCandidateMapping[result.cId]);
} else if (result.result.result_percent === resultsGeneral.value[0].result.result_percent) {
bestmatch.push(swappedCandidateMapping[result.cId]);
}
});
const bestscore = resultsGeneral.value[0].result.result_percent;
document.addEventListener('VotematchEU-ready', function() {
(window as any).VotematchEU.update({
lang: voteMatchLanguage,
action:'https://acc-app.votematch.eu',
});
(window as any).VotematchEU.results({
country: voteMatchCountry,
bestmatch: bestmatch,
bestscore: bestscore,
...mappedAnswers.value,
});
});
}
});
onBeforeUnmount(removeExternalScript);
</script>
<template>
<BackgroundComponent :is-image="false">
Expand Down Expand Up @@ -377,6 +490,31 @@ const handleSubscribe = async () => {
>{{ $t('routes.result.ResultPage.in-table') }}</a
>.
</BodyText>
<CardComponent
v-if="showVoteMatch"
background-color="#153288"
corner="bottom-left"
>
<StackComponent spacing="medium">
<img style="max-height: 1rem;" :src="'/images/votematcheurope-logo.svg'" />
<StackComponent spacing="medium">
<TitleText tag="p" size="medium" color="white">
What party in the EU is your best match?
</TitleText>
<BodyText tag="p" size="medium" color="white">
Compare your results with political parties in other European countries.
</BodyText>
</StackComponent>
<ButtonComponent
kind="outlined"
color="white"
target="_blank"
class="VotematchEU-button"
>
Show my results in VoteMatch Europe
</ButtonComponent>
</StackComponent>
</CardComponent>
<ResultCategory
:result="resultsGeneral"
category="general"
Expand Down

0 comments on commit 979f5c5

Please sign in to comment.