get ticket from api

This commit is contained in:
2026-06-25 11:03:19 +07:00
parent a06d0badfc
commit c539fe47af
3 changed files with 109 additions and 16 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import AppSidebar from '@/components/AppSidebar.vue'
<div class="wrapper d-flex flex-column min-vh-100"> <div class="wrapper d-flex flex-column min-vh-100">
<AppHeader /> <AppHeader />
<div class="body flex-grow-1"> <div class="body flex-grow-1">
<CContainer class="px-4" lg> <CContainer class="px-4" fluid>
<router-view /> <router-view />
</CContainer> </CContainer>
</div> </div>
+5 -1
View File
@@ -74,6 +74,10 @@ export const useTicketStore = defineStore('ticket', () => {
const approvedTickets = ref([]) const approvedTickets = ref([])
const rejectedTickets = ref([]) const rejectedTickets = ref([])
function setTickets(data) {
tickets.value = data
}
function addTicket(ticket) { function addTicket(ticket) {
tickets.value.push({ ...ticket }) tickets.value.push({ ...ticket })
} }
@@ -101,5 +105,5 @@ export const useTicketStore = defineStore('ticket', () => {
tickets.value[index].status = 'Rejected' tickets.value[index].status = 'Rejected'
} }
return { tickets, addTicket, updateTicket, deleteTicket, approveTicket, rejectTicket } return { tickets, setTickets, addTicket, updateTicket, deleteTicket, approveTicket, rejectTicket }
}) })
+103 -14
View File
@@ -1,8 +1,55 @@
<script setup> <script setup>
import { ref, reactive } from 'vue' import { ref, reactive, onMounted } from 'vue'
import { useTicketStore } from '@/stores/ticket.js' import { useTicketStore } from '@/stores/ticket.js'
const store = useTicketStore() const store = useTicketStore()
const loading = ref(false)
function capitalize(str) {
if (!str) return ''
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()
}
const token = 'Bearer uZ1vM4UON3CsDV9niGD1gLS4sHpCxT9nzadkITmc6caf2ea2'
async function fetchTickets() {
loading.value = true
try {
const res = await fetch('https://api.radiq.my.id/api/tickets', {
headers: { Authorization: token },
})
const json = await res.json()
const mapped = (json.data?.data || []).map((item) => ({
ticket_no: item.ticket_no,
tenant_id: item.tenant_id,
customer_id: item.customer_id,
deskripsi: item.description,
kode_tiket: item.title,
status: capitalize(item.status),
prioritas: capitalize(item.priority),
sla_minutes: item.sla_minutes,
ditugaskan_untuk: '',
created_by: item.created_by,
approved_by: item.approved_by || '',
approved_at: item.approved_at || '',
rejected_by: item.rejected_by || '',
rejected_at: item.rejected_at || '',
rejection_reason: item.rejection_reason || '',
assigned_at: item.assigned_at || '',
resolved_at: item.resolved_at || '',
closed_at: item.closed_at || '',
created_at: item.created_at || '',
updated_at: item.updated_at || '',
}))
store.setTickets(mapped)
} catch (err) {
console.error('Failed to fetch tickets:', err)
} finally {
loading.value = false
}
}
onMounted(fetchTickets)
const ticketModal = ref(false) const ticketModal = ref(false)
const detailModal = ref(false) const detailModal = ref(false)
@@ -82,13 +129,43 @@ function openDetail(item) {
detailModal.value = true detailModal.value = true
} }
function saveTicket() { async function saveTicket() {
if (isEdit.value && editingIndex.value >= 0) { const body = {
store.updateTicket(editingIndex.value, form) ticket_no: form.ticket_no,
} else { tenant_id: form.tenant_id,
store.addTicket(form) customer_id: form.customer_id,
title: form.kode_tiket,
description: form.deskripsi,
priority: form.prioritas?.toLowerCase(),
status: form.status?.toLowerCase(),
sla_minutes: form.sla_minutes,
}
try {
if (isEdit.value && editingIndex.value >= 0) {
const res = await fetch(
`https://api.radiq.my.id/api/tickets/${form.ticket_no}`,
{
method: 'PUT',
headers: { Authorization: token, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
},
)
if (res.ok) store.updateTicket(editingIndex.value, form)
} else {
const res = await fetch('https://api.radiq.my.id/api/tickets', {
method: 'POST',
headers: { Authorization: token, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
})
if (res.ok) {
const json = await res.json()
store.addTicket(json.data || form)
}
}
ticketModal.value = false
} catch (err) {
console.error('Save ticket failed:', err)
} }
ticketModal.value = false
} }
function deleteTicket(index) { function deleteTicket(index) {
@@ -101,10 +178,24 @@ function openApproveModal(index) {
approveModal.value = true approveModal.value = true
} }
function confirmApprove() { async function confirmApprove() {
if (approverName.value.trim()) { if (!approverName.value.trim()) return
store.approveTicket(approveIndex.value, approverName.value.trim()) const ticket = store.tickets[approveIndex.value]
approveModal.value = false try {
const res = await fetch(`https://api.radiq.my.id/api/tickets/${ticket.ticket_no}/approve`, {
method: 'PATCH',
headers: {
Authorization: token,
'Content-Type': 'application/json',
},
body: JSON.stringify({ approved_by: approverName.value.trim() }),
})
if (res.ok) {
store.approveTicket(approveIndex.value, approverName.value.trim())
approveModal.value = false
}
} catch (err) {
console.error('Approve failed:', err)
} }
} }
@@ -147,9 +238,7 @@ function isPending(item) {
<CTableRow> <CTableRow>
<CTableHeaderCell scope="col">No</CTableHeaderCell> <CTableHeaderCell scope="col">No</CTableHeaderCell>
<CTableHeaderCell scope="col" class="text-center">Ticket No</CTableHeaderCell> <CTableHeaderCell scope="col" class="text-center">Ticket No</CTableHeaderCell>
<CTableHeaderCell scope="col" class="text-center w-25" <CTableHeaderCell scope="col" class="text-center w-25">Title</CTableHeaderCell>
>Kode Tiket</CTableHeaderCell
>
<CTableHeaderCell scope="col">Deskripsi</CTableHeaderCell> <CTableHeaderCell scope="col">Deskripsi</CTableHeaderCell>
<CTableHeaderCell scope="col">Status</CTableHeaderCell> <CTableHeaderCell scope="col">Status</CTableHeaderCell>
<CTableHeaderCell scope="col">Prioritas</CTableHeaderCell> <CTableHeaderCell scope="col">Prioritas</CTableHeaderCell>