Appearance
useSupportApi Composable ​
File Information ​
- Path:
app/composables/api/useSupportApi.ts - Purpose: Support and feedback API operations
- Category: API Composable
Overview ​
The useSupportApi composable provides API operations for sending feedback and support requests to the system administrators.
Functions ​
sendFeedback ​
Sends feedback or support request to the system.
Signature:
typescript
sendFeedback(body: any): Promise<any>Parameters:
body: any- Feedback data (can be FormData for file uploads or plain object)
Returns:
Promise<any>- Response data
Features:
- Supports both FormData (for file attachments) and plain objects
- Handles file uploads in feedback
Usage:
typescript
const { sendFeedback } = useSupportApi()
// Send text feedback
await sendFeedback({
subject: 'Bug Report',
message: 'Found an issue with the search feature',
category: 'bug',
email: '[email protected]'
})
// Send feedback with file attachment
const formData = new FormData()
formData.append('subject', 'Feature Request')
formData.append('message', 'Please add dark mode')
formData.append('file', fileBlob, 'screenshot.png')
await sendFeedback(formData)API Endpoint: POST /digital/feedback
Request Body Formats ​
Text Feedback ​
typescript
{
subject: string // Feedback subject
message: string // Feedback message
category?: string // Feedback category (bug, feature, etc.)
email?: string // User email (optional)
name?: string // User name (optional)
}Feedback with File Attachment ​
typescript
FormData {
subject: string
message: string
category?: string
file: File // Attached file
email?: string
name?: string
}Complete Usage Example ​
typescript
const { sendFeedback } = useSupportApi()
const snackbar = useSnackbar()
// Text feedback
const submitTextFeedback = async () => {
try {
await sendFeedback({
subject: 'Bug Report',
message: 'The search filter is not working correctly',
category: 'bug'
})
snackbar.showSuccess('Feedback submitted successfully')
} catch (error) {
snackbar.showError('Failed to submit feedback')
}
}
// Feedback with screenshot
const submitFeedbackWithScreenshot = async (file: File) => {
try {
const formData = new FormData()
formData.append('subject', 'UI Issue')
formData.append('message', 'The button alignment looks off')
formData.append('category', 'ui')
formData.append('file', file)
await sendFeedback(formData)
snackbar.showSuccess('Feedback with screenshot submitted')
} catch (error) {
snackbar.showError('Failed to submit feedback')
}
}Integration with Feedback Form ​
vue
<script setup lang="ts">
const { sendFeedback } = useSupportApi()
const snackbar = useSnackbar()
const form = ref({
subject: '',
message: '',
category: 'general',
file: null as File | null
})
const loading = ref(false)
const submitFeedback = async () => {
if (!form.value.subject || !form.value.message) {
snackbar.showError('Please fill in all required fields')
return
}
loading.value = true
try {
if (form.value.file) {
// With file attachment
const formData = new FormData()
formData.append('subject', form.value.subject)
formData.append('message', form.value.message)
formData.append('category', form.value.category)
formData.append('file', form.value.file)
await sendFeedback(formData)
} else {
// Text only
await sendFeedback({
subject: form.value.subject,
message: form.value.message,
category: form.value.category
})
}
snackbar.showSuccess('Thank you for your feedback!')
// Reset form
form.value = { subject: '', message: '', category: 'general', file: null }
} catch (error) {
snackbar.showError('Failed to submit feedback. Please try again.')
} finally {
loading.value = false
}
}
const handleFileSelect = (event: Event) => {
const input = event.target as HTMLInputElement
if (input.files && input.files[0]) {
form.value.file = input.files[0]
}
}
</script>
<template>
<v-form @submit.prevent="submitFeedback">
<v-text-field
v-model="form.subject"
label="Subject"
required
/>
<v-textarea
v-model="form.message"
label="Message"
required
/>
<v-select
v-model="form.category"
:items="['bug', 'feature', 'ui', 'general']"
label="Category"
/>
<v-file-input
label="Attachment (optional)"
@change="handleFileSelect"
/>
<v-btn
type="submit"
:loading="loading"
color="primary"
>
Submit Feedback
</v-btn>
</v-form>
</template>Error Handling ​
The composable includes error handling with logging:
typescript
catch (error: any) {
console.error('[SupportAPI] sendFeedback - Error:', error)
throw error
}Use Cases ​
Bug Report ​
typescript
const { sendFeedback } = useSupportApi()
const reportBug = async (description: string, screenshot?: File) => {
const body: any = {
subject: 'Bug Report',
message: description,
category: 'bug'
}
if (screenshot) {
const formData = new FormData()
Object.keys(body).forEach(key => formData.append(key, body[key]))
formData.append('file', screenshot)
await sendFeedback(formData)
} else {
await sendFeedback(body)
}
}Feature Request ​
typescript
const { sendFeedback } = useSupportApi()
const requestFeature = async (feature: string, description: string) => {
await sendFeedback({
subject: `Feature Request: ${feature}`,
message: description,
category: 'feature'
})
}Related Documentation ​
- Support Page - Support page documentation
- API Composables - Other API composables