thainv-dev: tạo lại cấu trúc folder và làm UI

This commit is contained in:
nguyen van thai
2024-06-12 17:17:49 +07:00
parent c217ed82c9
commit 5b1e0af397
44 changed files with 2674 additions and 228 deletions
+83 -29
View File
@@ -1,56 +1,110 @@
<script setup lang="ts">
import { usePollStore } from '~/stores/poll'
import { usePollOptionStore } from '~/stores/poll-option'
import type { Poll } from '~/server/models/poll';
import { usePollStore } from "~/stores/poll";
import { usePollOptionStore } from "~/stores/poll-option";
import { usePollResponseStore } from "~/stores/poll-response";
import type { Poll } from "~/server/models/poll";
import type { PollResponse } from "~/server/models/poll-response";
import type { PollOption } from "~/server/models/poll-option";
const props = defineProps<{ dataId?: string }>();
const store = reactive({
poll: usePollStore(),
pollOptions: usePollOptionStore()
})
pollOptions: usePollOptionStore(),
pollResponse: usePollResponseStore(),
});
const { currentPoll } = storeToRefs(store.poll);
const { currentPollOptions } = storeToRefs(store.pollOptions);
const { currentPollResponses } = storeToRefs(store.pollResponse);
const poll = reactive<Poll | any>({});
const options = ref<PollOption[]>();
async function loadData() {
await store.poll.fetchById(String(props.dataId));
await store.pollOptions.fetchByPollId(String(props.dataId));
await store.pollResponse.fetchByPollId(String(props.dataId));
assignData();
}
const poll = reactive<Poll>(await store.poll.fetchById((String(props.dataId))))
const options = ref<any []>(await store.pollOptions.fetchByPollId((String(props.dataId))))
function assignData() {
Object.assign(poll, currentPoll.value);
options.value = currentPollOptions.value;
}
onBeforeMount(async () => {
await loadData();
});
const selectedOption = ref<any>(null);
const showResult = ref(false);
const alreadyVoted = ref(false);
const canShowResult = computed(() => {
switch (poll.settings?.resultPublication) {
case 0:
return false;
case 1:
return true;
case 2:
return alreadyVoted.value;
case 3:
return alreadyVoted.value && (!poll.endTime || new Date() > new Date(poll.endTime));
}
});
function submitVote () {
console.log(selectedOption, 'id')
async function submitVote() {
if (selectedOption.value) {
let option = options.value?.find((option: PollOption) => option.id === selectedOption.value);
if(option) {
option.responsesCount = Number(option.responsesCount) + 1
}
const totalResponses = options.value?.reduce((sum, option) => sum + Number(option.responsesCount ?? 0), 0);
// const result = await store.pollResponse.create({ optionId: selectedOption.value });
// if (result) {
// alreadyVoted.value = true;
// if (options.value) {
// let option = options.value.find((option: PollOption) => option.id === selectedOption.value);
// // if (option) option?.responsesCount += 1;
// // options.value.filter((option) => {
// // option.votePercentage = (option.responsesCount / currentPollResponses.value.length) * 100;
// // });
// }
// }
}
}
const toggleResults = () => {
if (canShowResult.value) showResult.value = !showResult.value;
};
</script>
<template>
<span class="inline-block px-4 py-2 shadow-xl rounded-lg bg-[#f5f5f5]">
<span class="inline-block px-4 py-2 shadow-xl rounded-lg bg-[#f5f5f5]">
<span class="block">
<span class="underline decoration-gray-500 font-bold">
{{ poll?.title }}
</span>
<!-- <button v-if="showResult && canShowResult" type="button" class="underline text-blue-400" @click="toggleResults">
Câu hỏi
</button>
<button class="underline text-blue-400" v-if="!showResult && canShowResult" type="button" @click="toggleResults">
Kết quả
</button> -->
<button v-if="showResult && canShowResult" type="button" class="underline text-blue-400" @click="toggleResults">Câu hỏi</button>
<button class="underline text-blue-400" v-if="!showResult && canShowResult" type="button" @click="toggleResults">Kết quả</button>
</span>
<span class="p-1 block">
<span v-for="(option, index) in options" :key="index" class="block">
<label class="flex gap-2 m-2">
<input type="radio" :value="option.id" v-model="selectedOption" />
<span class="font-semibold">{{ option?.title }}</span>
</label>
</span>
<button @click="submitVote" class="bg-primary-500 text-white py-1 px-3 rounded-4px cursor-pointer hover:bg-primary-600 float-right">Bình chọn </button>
<span v-if="!showResult" class="p-1 block">
<span v-for="(option, index) in options" :key="index" class="block">
<label class="flex gap-2 m-2">
<input type="radio" :value="option.id" v-model="selectedOption" />
<span class="font-semibold">{{ option?.title }}</span>
</label>
</span>
<button @click="submitVote" class="bg-primary-500 text-white py-1 px-3 rounded-4px cursor-pointer hover:bg-primary-600 float-right">Bình chọn</button>
</span>
<!-- <span v-else class="block">
<span v-for="(answer, index) in options" :key="index" class="block poll-result relative rounded-3xl overflow-hidden my-3">
<span v-else class="block">
hoàn thành
<!-- <span v-for="(answer, index) in options" :key="index" class="block poll-result relative rounded-3xl overflow-hidden my-3">
<span class="absolute top-0 start-0 bottom-0 bg-gradient-to-r from-sky-500 to-indigo-500"
:style="{ width: `${calculatePercentage(answer?.voteCount)}%` }"></span>
<span class="block relative z-0 ps-1">
<span>{{ calculatePercentage(answer?.voteCount).toFixed(2) }}%</span>
<span class="">({{ answer?.voteCount }})</span>
</span>
</span>
</span> -->
</span> -->
</span>
</span>
</template>
</template>