Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 31x 31x 31x 31x 1x 96x 87x 96x 9x 96x 7x 96x 1x 96x 1x 96x 96x 96x 1x 1x | <template>
<div class="flex flex-wrap gap-2" data-testid="rsvp-buttons">
<BaseButton
v-for="option in rsvpOptions"
:key="option.status"
:variant="getButtonVariant(option.status)"
:disabled="disabled"
:data-testid="`rsvp-${option.status}`"
size="md"
@click="handleSelect(option.status)"
>
<span class="mr-1.5">{{ option.icon }}</span>
{{ option.label }}
</BaseButton>
</div>
</template>
<script setup lang="ts">
/**
* RSVPButton
* @description Composite component for RSVP status selection (Yes/No/Maybe)
* Shows visual feedback for current selection
*/
import type { AttendanceStatus } from '~/types'
interface Props {
/** Current user's RSVP status */
currentStatus?: AttendanceStatus | null
/** Disabled state (e.g., during submission) */
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
currentStatus: null,
disabled: false
})
const emit = defineEmits<{
/** Emitted when user selects a status */
submit: [status: AttendanceStatus]
}>()
interface RSVPOption {
status: AttendanceStatus
label: string
icon: string
}
/**
* i18n
*/
const { t } = useI18n()
/**
* RSVP options configuration
*/
const rsvpOptions = computed<RSVPOption[]>(() => [
{ status: 'yes', label: t('rsvp.yes'), icon: '✓' },
{ status: 'no', label: t('rsvp.no'), icon: '✗' },
{ status: 'maybe', label: t('rsvp.maybe'), icon: '?' }
])
/**
* Get button variant based on selection state
*/
const getButtonVariant = (status: AttendanceStatus): 'primary' | 'secondary' | 'ghost' | 'danger' => {
if (props.currentStatus !== status) {
return 'secondary'
}
// Selected state - use appropriate variant
switch (status) {
case 'yes':
return 'primary'
case 'no':
return 'danger'
case 'maybe':
return 'secondary'
default:
return 'secondary'
}
}
/**
* Handle status selection
*/
const handleSelect = (status: AttendanceStatus): void => {
emit('submit', status)
}
</script>
|