Files
weeklyreport/frontend/report/weekly/index.vue
2026-01-04 20:58:47 +09:00

123 lines
3.6 KiB
Vue

<template>
<div>
<AppHeader />
<div class="container py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="mb-0">
<i class="bi bi-journal-text me-2"></i> 주간보고
</h4>
<NuxtLink to="/report/weekly/write" class="btn btn-primary">
<i class="bi bi-plus me-1"></i>작성하기
</NuxtLink>
</div>
<div class="card">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="table-light">
<tr>
<th style="width: 150px">주차</th>
<th style="width: 200px">기간</th>
<th>프로젝트</th>
<th style="width: 100px">상태</th>
<th style="width: 150px">작성일</th>
</tr>
</thead>
<tbody>
<tr v-if="isLoading">
<td colspan="5" class="text-center py-4">
<span class="spinner-border spinner-border-sm me-2"></span>로딩 ...
</td>
</tr>
<tr v-else-if="reports.length === 0">
<td colspan="5" class="text-center py-5 text-muted">
<i class="bi bi-inbox display-4"></i>
<p class="mt-2 mb-0">작성한 주간보고가 없습니다.</p>
</td>
</tr>
<tr v-else v-for="r in reports" :key="r.reportId"
@click="router.push(`/report/weekly/${r.reportId}`)"
style="cursor: pointer;">
<td>
<strong>{{ r.reportYear }} {{ r.reportWeek }}주차</strong>
</td>
<td>{{ formatDate(r.weekStartDate) }} ~ {{ formatDate(r.weekEndDate) }}</td>
<td>
<span class="badge bg-primary">{{ r.projectCount }} 프로젝트</span>
</td>
<td>
<span :class="getStatusBadgeClass(r.reportStatus)">
{{ getStatusText(r.reportStatus) }}
</span>
</td>
<td>{{ formatDateTime(r.createdAt) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const { fetchCurrentUser } = useAuth()
const router = useRouter()
const reports = ref<any[]>([])
const isLoading = ref(true)
onMounted(async () => {
const user = await fetchCurrentUser()
if (!user) {
router.push('/login')
return
}
loadReports()
})
async function loadReports() {
isLoading.value = true
try {
const res = await $fetch<any>('/api/report/weekly/list')
reports.value = res.reports || []
} catch (e) {
console.error(e)
} finally {
isLoading.value = false
}
}
function formatDate(dateStr: string) {
if (!dateStr) return ''
return dateStr.split('T')[0]
}
function formatDateTime(dateStr: string) {
if (!dateStr) return ''
const d = new Date(dateStr)
return d.toLocaleDateString('ko-KR')
}
function getStatusBadgeClass(status: string) {
const classes: Record<string, string> = {
'DRAFT': 'badge bg-secondary',
'SUBMITTED': 'badge bg-success',
'AGGREGATED': 'badge bg-info'
}
return classes[status] || 'badge bg-secondary'
}
function getStatusText(status: string) {
const texts: Record<string, string> = {
'DRAFT': '작성중',
'SUBMITTED': '제출완료',
'AGGREGATED': '취합완료'
}
return texts[status] || status
}
</script>