Files
traxxx-web/components/entities/report.vue
T

145 lines
2.8 KiB
Vue

<script setup>
import { computed, ref } from 'vue';
import Dialog from '#/components/dialog/dialog.vue';
import Checkbox from '#/components/form/checkbox.vue';
import Ellipsis from '#/components/loading/ellipsis.vue';
import { post } from '#/src/api.js';
import reportReasons from '#/utils/report-reasons.js';
const props = defineProps({
entity: {
type: Object,
required: true,
},
});
const emit = defineEmits(['close', 'reported']);
const reasons = ref(new Set());
const comment = ref('');
const submitted = ref(false);
const canSubmit = computed(() => reasons.value.size > 0 || comment.value.trim().length > 0);
const hasChanges = computed(() => reasons.value.size > 0 || comment.value.length > 0);
function toggleReason(reason, checked) {
const updated = new Set(reasons.value);
if (checked) {
updated.add(reason);
}
else {
updated.delete(reason);
}
reasons.value = updated;
}
async function submitReport() {
submitted.value = true;
try {
await post(`/entities/${props.entity.id}/reports`, {
reasons: Array.from(reasons.value),
comment: comment.value,
}, {
successFeedback: `Reported ${props.entity.name}, thank you!`,
errorFeedback: `Failed to report ${props.entity.name}`,
appendErrorMessage: true,
});
emit('reported');
}
catch (_error) {
submitted.value = false; // feedback is shown by the api module
}
}
</script>
<template>
<Dialog
:title="`Report '${entity.name}'`"
:confirm-close="hasChanges && !submitted"
@close="emit('close')"
>
<form
class="dialog-body"
@submit.prevent="submitReport"
>
<p class="intro">What's wrong with this {{ entity.type || 'site' }} index?</p>
<div class="reasons">
<Checkbox
v-for="(label, reason) in reportReasons"
:key="`reason-${reason}`"
:checked="reasons.has(reason)"
:label="label"
class="reason"
@change="(checked) => toggleReason(reason, checked)"
/>
</div>
<textarea
v-model="comment"
placeholder="Optional details that may help verify or address the problem"
rows="3"
maxlength="2000"
class="input comment"
/>
<div class="dialog-actions">
<Ellipsis v-if="submitted" />
<button
v-else
:disabled="!canSubmit"
class="button button-primary"
>Submit report</button>
</div>
</form>
</Dialog>
</template>
<style scoped>
.dialog-body {
width: 30rem;
max-width: 100%;
box-sizing: border-box;
gap: .75rem;
padding: 1rem;
}
.intro {
margin: 0;
color: var(--glass-strong-10);
}
.reasons {
display: flex;
flex-direction: column;
gap: .5rem;
}
.reason {
padding: .15rem 0;
justify-content: space-between;
}
.comment {
width: 100%;
resize: vertical;
flex-basis: auto;
}
.dialog-actions {
display: flex;
justify-content: center;
.button {
width: 100%;
}
}
</style>