plan implementation 6, 7, 8, 9, 10
This commit is contained in:
119
resources/js/Components/QuestionCard.vue
Normal file
119
resources/js/Components/QuestionCard.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
question: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: () => ({ value: null, text_value: '' }),
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const hasRadioButtons = computed(() => {
|
||||
return props.question.has_yes || props.question.has_no || props.question.has_na
|
||||
})
|
||||
|
||||
const showDetails = computed(() => {
|
||||
const d = props.question.details
|
||||
if (!d) return false
|
||||
if (d === 'required' || d === 'optional') return true
|
||||
if (d === 'req_on_yes' && props.modelValue.value === 'yes') return true
|
||||
if (d === 'req_on_no' && props.modelValue.value === 'no') return true
|
||||
return false
|
||||
})
|
||||
|
||||
const detailsRequired = computed(() => {
|
||||
const d = props.question.details
|
||||
if (d === 'required') return true
|
||||
if (d === 'req_on_yes' && props.modelValue.value === 'yes') return true
|
||||
if (d === 'req_on_no' && props.modelValue.value === 'no') return true
|
||||
return false
|
||||
})
|
||||
|
||||
const isTextOnly = computed(() => {
|
||||
return !hasRadioButtons.value && props.question.details
|
||||
})
|
||||
|
||||
const updateValue = (value) => {
|
||||
emit('update:modelValue', { ...props.modelValue, value })
|
||||
}
|
||||
|
||||
const updateTextValue = (event) => {
|
||||
emit('update:modelValue', { ...props.modelValue, text_value: event.target.value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="py-4">
|
||||
<p class="text-white mb-3">{{ question.text }}</p>
|
||||
|
||||
<!-- Text-only question (no radio buttons) -->
|
||||
<div v-if="isTextOnly">
|
||||
<textarea
|
||||
:value="modelValue.text_value"
|
||||
@input="updateTextValue"
|
||||
rows="3"
|
||||
class="w-full rounded-lg border border-gray-600 bg-surface px-3 py-2 text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary"
|
||||
placeholder="Enter your response..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Radio button question -->
|
||||
<div v-if="hasRadioButtons">
|
||||
<div class="flex flex-wrap gap-4 mb-3">
|
||||
<label v-if="question.has_yes" class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
:name="`question-${question.id}`"
|
||||
value="yes"
|
||||
:checked="modelValue.value === 'yes'"
|
||||
@change="updateValue('yes')"
|
||||
class="w-4 h-4 text-primary bg-surface border-gray-600 focus:ring-primary focus:ring-offset-surface"
|
||||
/>
|
||||
<span class="text-white">Yes</span>
|
||||
</label>
|
||||
<label v-if="question.has_no" class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
:name="`question-${question.id}`"
|
||||
value="no"
|
||||
:checked="modelValue.value === 'no'"
|
||||
@change="updateValue('no')"
|
||||
class="w-4 h-4 text-primary bg-surface border-gray-600 focus:ring-primary focus:ring-offset-surface"
|
||||
/>
|
||||
<span class="text-white">No</span>
|
||||
</label>
|
||||
<label v-if="question.has_na" class="flex items-center gap-2 cursor-pointer">
|
||||
<input
|
||||
type="radio"
|
||||
:name="`question-${question.id}`"
|
||||
value="not_applicable"
|
||||
:checked="modelValue.value === 'not_applicable'"
|
||||
@change="updateValue('not_applicable')"
|
||||
class="w-4 h-4 text-primary bg-surface border-gray-600 focus:ring-primary focus:ring-offset-surface"
|
||||
/>
|
||||
<span class="text-white">N/A</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Details textarea (conditional) -->
|
||||
<div v-if="showDetails" class="mt-2">
|
||||
<label class="block text-sm text-gray-400 mb-1">
|
||||
Details{{ detailsRequired ? ' (required)' : ' (optional)' }}
|
||||
</label>
|
||||
<textarea
|
||||
:value="modelValue.text_value"
|
||||
@input="updateTextValue"
|
||||
rows="2"
|
||||
class="w-full rounded-lg border border-gray-600 bg-surface px-3 py-2 text-white placeholder-gray-500 focus:border-primary focus:ring-1 focus:ring-primary text-sm"
|
||||
placeholder="Enter details..."
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user