오류 수정
This commit is contained in:
@@ -325,7 +325,7 @@ router.get('/features/stats', async (req, res) => {
|
|||||||
router.get('/users', async (req, res) => {
|
router.get('/users', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const users = await User.findAll({
|
const users = await User.findAll({
|
||||||
attributes: ['id', 'name', 'email', 'role', 'createdAt'],
|
attributes: ['id', 'name', 'email', 'role', 'status', 'createdAt'],
|
||||||
order: [['createdAt', 'DESC']]
|
order: [['createdAt', 'DESC']]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -33,13 +33,13 @@
|
|||||||
|
|
||||||
<div class="col-12 md:col-6">
|
<div class="col-12 md:col-6">
|
||||||
<label for="startDate">시작일 *</label>
|
<label for="startDate">시작일 *</label>
|
||||||
<Datepicker id="startDate" v-model="eventModel.startDate" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :stepMinute="5" :class="{'p-invalid': submitted && !eventModel.startDate, 'w-full': true}" />
|
<DatePicker id="startDate" v-model="eventModel.startDate" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :stepMinute="5" :class="{'p-invalid': submitted && !eventModel.startDate, 'w-full': true}" />
|
||||||
<small class="p-error" v-if="submitted && !eventModel.startDate">시작일은 필수입니다.</small>
|
<small class="p-error" v-if="submitted && !eventModel.startDate">시작일은 필수입니다.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 md:col-6">
|
<div class="col-12 md:col-6">
|
||||||
<label for="endDate">종료일</label>
|
<label for="endDate">종료일</label>
|
||||||
<Datepicker id="endDate" v-model="eventModel.endDate" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :stepMinute="5" :class="{'p-invalid': submitted && !eventModel.endDate, 'w-full': true}" />
|
<DatePicker id="endDate" v-model="eventModel.endDate" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :stepMinute="5" :class="{'p-invalid': submitted && !eventModel.endDate, 'w-full': true}" />
|
||||||
<small class="p-error" v-if="submitted && !eventModel.endDate">종료일은 필수입니다.</small>
|
<small class="p-error" v-if="submitted && !eventModel.endDate">종료일은 필수입니다.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
<div class="col-12 md:col-6">
|
<div class="col-12 md:col-6">
|
||||||
<label for="registrationDeadline">신청마감</label>
|
<label for="registrationDeadline">신청마감</label>
|
||||||
<Datepicker id="registrationDeadline" v-model="eventModel.registrationDeadline" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :stepMinute="5" :class="{'p-invalid': submitted && !eventModel.registrationDeadline, 'w-full': true}" />
|
<DatePicker id="registrationDeadline" v-model="eventModel.registrationDeadline" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :stepMinute="5" :class="{'p-invalid': submitted && !eventModel.registrationDeadline, 'w-full': true}" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 md:col-6">
|
<div class="col-12 md:col-6">
|
||||||
|
|||||||
@@ -274,7 +274,7 @@
|
|||||||
|
|
||||||
<div class="field mb-4">
|
<div class="field mb-4">
|
||||||
<label for="startDate" class="field-label">시작일 <span class="text-red-500">*</span></label>
|
<label for="startDate" class="field-label">시작일 <span class="text-red-500">*</span></label>
|
||||||
<Datepicker
|
<DatePicker
|
||||||
id="startDate"
|
id="startDate"
|
||||||
v-model="eventData.startDate"
|
v-model="eventData.startDate"
|
||||||
dateFormat="yy-mm-dd"
|
dateFormat="yy-mm-dd"
|
||||||
@@ -287,7 +287,7 @@
|
|||||||
|
|
||||||
<div class="field mb-4">
|
<div class="field mb-4">
|
||||||
<label for="endDate" class="field-label">종료일</label>
|
<label for="endDate" class="field-label">종료일</label>
|
||||||
<Datepicker
|
<DatePicker
|
||||||
id="endDate"
|
id="endDate"
|
||||||
v-model="eventData.endDate"
|
v-model="eventData.endDate"
|
||||||
dateFormat="yy-mm-dd"
|
dateFormat="yy-mm-dd"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ import Badge from 'primevue/badge'
|
|||||||
import InputNumber from 'primevue/inputnumber'
|
import InputNumber from 'primevue/inputnumber'
|
||||||
import Divider from 'primevue/divider'
|
import Divider from 'primevue/divider'
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import Datepicker from 'primevue/datepicker'
|
import DatePicker from 'primevue/datepicker'
|
||||||
import Tag from 'primevue/tag'
|
import Tag from 'primevue/tag'
|
||||||
import FloatLabel from 'primevue/floatlabel';
|
import FloatLabel from 'primevue/floatlabel';
|
||||||
import Tooltip from 'primevue/tooltip';
|
import Tooltip from 'primevue/tooltip';
|
||||||
@@ -109,7 +109,7 @@ app.component('Badge', Badge)
|
|||||||
app.component('InputNumber', InputNumber)
|
app.component('InputNumber', InputNumber)
|
||||||
app.component('Divider', Divider)
|
app.component('Divider', Divider)
|
||||||
app.component('ProgressSpinner', ProgressSpinner)
|
app.component('ProgressSpinner', ProgressSpinner)
|
||||||
app.component('Datepicker', Datepicker)
|
app.component('DatePicker', DatePicker)
|
||||||
app.component('Tag', Tag)
|
app.component('Tag', Tag)
|
||||||
app.component('FloatLabel', FloatLabel);
|
app.component('FloatLabel', FloatLabel);
|
||||||
app.component('FileUpload', FileUpload);
|
app.component('FileUpload', FileUpload);
|
||||||
|
|||||||
@@ -1,4 +1,17 @@
|
|||||||
// enumMappings.js: 영어 enum 값을 한글 라벨로 변환하는 매핑 및 함수 모음
|
export const ROLE_OPTIONS = [
|
||||||
|
{ name: '관리자', value: 'admin' },
|
||||||
|
{ name: '클럽 관리자', value: 'clubadmin' },
|
||||||
|
{ name: '일반 사용자', value: 'user' }
|
||||||
|
];
|
||||||
|
|
||||||
|
export const ROLE_LABELS = ROLE_OPTIONS.reduce(
|
||||||
|
(acc, cur) => ({ ...acc, [cur.value]: cur.name }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
export function getRoleName(role) {
|
||||||
|
return ROLE_LABELS[role] || role;
|
||||||
|
}
|
||||||
|
|
||||||
export const GENDER_OPTIONS = [
|
export const GENDER_OPTIONS = [
|
||||||
{ name: '남성', value: 'male' },
|
{ name: '남성', value: 'male' },
|
||||||
@@ -93,33 +106,60 @@ export const AVERAGE_CALCULATION_PERIOD_LABELS = AVERAGE_CALCULATION_PERIOD_OPTI
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const CLUB_STATUS_OPTIONS = [
|
||||||
|
{ name: '활성', value: 'active' },
|
||||||
|
{ name: '비활성', value: 'inactive' }
|
||||||
|
];
|
||||||
|
export const CLUB_STATUS_LABELS = CLUB_STATUS_OPTIONS.reduce(
|
||||||
|
(acc, cur) => ({ ...acc, [cur.value]: cur.name }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const SUBSCRIPTION_STATUS_OPTIONS = [
|
||||||
|
{ name: '활성', value: 'active' },
|
||||||
|
{ name: '만료', value: 'expired' },
|
||||||
|
{ name: '일시중지', value: 'paused' }
|
||||||
|
];
|
||||||
|
export const SUBSCRIPTION_STATUS_LABELS = SUBSCRIPTION_STATUS_OPTIONS.reduce(
|
||||||
|
(acc, cur) => ({ ...acc, [cur.value]: cur.name }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
export function getGenderLabel(code) {
|
export function getGenderLabel(code) {
|
||||||
return GENDER_LABELS[code] || '-';
|
return GENDER_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
export function getMemberTypeLabel(code) {
|
export function getMemberTypeLabel(code) {
|
||||||
return MEMBER_TYPE_LABELS[code] || '-';
|
return MEMBER_TYPE_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
export function getStatusLabel(code) {
|
export function getStatusLabel(code) {
|
||||||
return STATUS_LABELS[code] || '-';
|
return STATUS_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getParticipantStatusLabel(code) {
|
export function getParticipantStatusLabel(code) {
|
||||||
return PARTICIPANT_STATUS_LABELS[code] || '-';
|
return PARTICIPANT_STATUS_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEventStatusLabel(code) {
|
export function getEventStatusLabel(code) {
|
||||||
return EVENT_STATUS_LABELS[code] || '-';
|
return EVENT_STATUS_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
export function getEventTypeLabel(code) {
|
export function getEventTypeLabel(code) {
|
||||||
return EVENT_TYPE_LABELS[code] || '-';
|
return EVENT_TYPE_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPaymentStatusLabel(code) {
|
export function getPaymentStatusLabel(code) {
|
||||||
return PAYMENT_STATUS_LABELS[code] || '-';
|
return PAYMENT_STATUS_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAverageCalculationPeriodLabel(code) {
|
export function getAverageCalculationPeriodLabel(code) {
|
||||||
return AVERAGE_CALCULATION_PERIOD_LABELS[code] || '-';
|
return AVERAGE_CALCULATION_PERIOD_LABELS[code] || code;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getClubStatusLabel(code) {
|
||||||
|
return CLUB_STATUS_LABELS[code] || code;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSubscriptionStatusLabel(code) {
|
||||||
|
return SUBSCRIPTION_STATUS_LABELS[code] || code;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMemberTypeSeverity(type) {
|
export function getMemberTypeSeverity(type) {
|
||||||
@@ -175,3 +215,30 @@ export function getParticipantStatusSeverity(status) {
|
|||||||
default: return 'secondary';
|
default: return 'secondary';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRoleSeverity(role) {
|
||||||
|
switch (role) {
|
||||||
|
case 'admin': return 'danger';
|
||||||
|
case 'clubadmin': return 'warning';
|
||||||
|
case 'user': return 'info';
|
||||||
|
default: return 'info';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getClubStatusSeverity(status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'active': return 'success';
|
||||||
|
case 'inactive': return 'danger';
|
||||||
|
default: return 'secondary';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSubscriptionStatusSeverity(status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'active': return 'success';
|
||||||
|
case 'expired': return 'danger';
|
||||||
|
case 'paused': return 'warning';
|
||||||
|
default: return 'secondary';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
</Column>
|
</Column>
|
||||||
<Column field="status" header="상태">
|
<Column field="status" header="상태">
|
||||||
<template #body="subProps">
|
<template #body="subProps">
|
||||||
<Badge :value="getStatusName(subProps.data.status)" :severity="getStatusSeverity(subProps.data.status)" />
|
<Badge :value="getSubscriptionStatusLabel(subProps.data.status)" :severity="getSubscriptionStatusSeverity(subProps.data.status)" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column header="작업">
|
<Column header="작업">
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="status">상태</label>
|
<label for="status">상태</label>
|
||||||
<Dropdown id="status" v-model="plan.status" :options="statusOptions" optionLabel="name" optionValue="value" />
|
<Select id="status" v-model="plan.status" :options="SUBSCRIPTION_STATUS_OPTIONS" optionLabel="name" optionValue="value" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -139,28 +139,28 @@
|
|||||||
<Dialog v-model:visible="subscriptionDialog" :header="subscriptionDialogTitle" :style="{ width: '500px' }" :modal="true" class="p-fluid">
|
<Dialog v-model:visible="subscriptionDialog" :header="subscriptionDialogTitle" :style="{ width: '500px' }" :modal="true" class="p-fluid">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="club">클럽</label>
|
<label for="club">클럽</label>
|
||||||
<Dropdown id="club" v-model="subscription.clubId" :options="availableClubs" optionLabel="name" optionValue="id"
|
<Select id="club" v-model="subscription.clubId" :options="availableClubs" optionLabel="name" optionValue="id"
|
||||||
:class="{'p-invalid': subscriptionSubmitted && !subscription.clubId}" placeholder="클럽 선택" />
|
:class="{'p-invalid': subscriptionSubmitted && !subscription.clubId}" placeholder="클럽 선택" />
|
||||||
<small class="p-error" v-if="subscriptionSubmitted && !subscription.clubId">클럽을 선택해주세요.</small>
|
<small class="p-error" v-if="subscriptionSubmitted && !subscription.clubId">클럽을 선택해주세요.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="startDate">시작일</label>
|
<label for="startDate">시작일</label>
|
||||||
<Calendar id="startDate" v-model="subscription.startDate" :showIcon="true" dateFormat="yy-mm-dd"
|
<DatePicker id="startDate" v-model="subscription.startDate" :showIcon="true" dateFormat="yy-mm-dd"
|
||||||
:class="{'p-invalid': subscriptionSubmitted && !subscription.startDate}" />
|
:class="{'p-invalid': subscriptionSubmitted && !subscription.startDate}" />
|
||||||
<small class="p-error" v-if="subscriptionSubmitted && !subscription.startDate">시작일을 선택해주세요.</small>
|
<small class="p-error" v-if="subscriptionSubmitted && !subscription.startDate">시작일을 선택해주세요.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="expiryDate">만료일</label>
|
<label for="expiryDate">만료일</label>
|
||||||
<Calendar id="expiryDate" v-model="subscription.expiryDate" :showIcon="true" dateFormat="yy-mm-dd"
|
<DatePicker id="expiryDate" v-model="subscription.expiryDate" :showIcon="true" dateFormat="yy-mm-dd"
|
||||||
:class="{'p-invalid': subscriptionSubmitted && !subscription.expiryDate}" :minDate="subscription.startDate" />
|
:class="{'p-invalid': subscriptionSubmitted && !subscription.expiryDate}" :minDate="subscription.startDate" />
|
||||||
<small class="p-error" v-if="subscriptionSubmitted && !subscription.expiryDate">만료일을 선택해주세요.</small>
|
<small class="p-error" v-if="subscriptionSubmitted && !subscription.expiryDate">만료일을 선택해주세요.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="status">상태</label>
|
<label for="status">상태</label>
|
||||||
<Dropdown id="status" v-model="subscription.status" :options="subscriptionStatusOptions" optionLabel="name" optionValue="value" />
|
<Select id="status" v-model="subscription.status" :options="SUBSCRIPTION_STATUS_OPTIONS" optionLabel="name" optionValue="value" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -198,26 +198,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getStatusLabel } from '@/utils/enumMappings';
|
import { getStatusLabel, getStatusSeverity, getSubscriptionStatusLabel, getSubscriptionStatusSeverity, SUBSCRIPTION_STATUS_OPTIONS, SUBSCRIPTION_STATUS_LABELS } from '@/utils/enumMappings';
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import { useToast } from 'primevue/usetoast';
|
import { useToast } from 'primevue/usetoast';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import adminService from '@/services/adminService';
|
import adminService from '@/services/adminService';
|
||||||
|
|
||||||
// PrimeVue 컴포넌트
|
|
||||||
import MultiSelect from 'primevue/multiselect';
|
|
||||||
import InputNumber from 'primevue/inputnumber';
|
|
||||||
import Textarea from 'primevue/textarea';
|
|
||||||
import InputText from 'primevue/inputtext';
|
|
||||||
import Button from 'primevue/button';
|
|
||||||
import Dialog from 'primevue/dialog';
|
|
||||||
import DataTable from 'primevue/datatable';
|
|
||||||
import Column from 'primevue/column';
|
|
||||||
import Dropdown from 'primevue/dropdown';
|
|
||||||
import Badge from 'primevue/badge';
|
|
||||||
import Toast from 'primevue/toast';
|
|
||||||
import Calendar from 'primevue/calendar';
|
|
||||||
|
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const API_URL = 'http://localhost:3030/api';
|
const API_URL = 'http://localhost:3030/api';
|
||||||
|
|
||||||
@@ -245,18 +231,6 @@ const subscriptionSubmitted = ref(false);
|
|||||||
const availableClubs = ref([]);
|
const availableClubs = ref([]);
|
||||||
const selectedPlan = ref(null);
|
const selectedPlan = ref(null);
|
||||||
|
|
||||||
// 상태 옵션
|
|
||||||
const statusOptions = [
|
|
||||||
{ name: '활성', value: 'active' },
|
|
||||||
{ name: '비활성', value: 'inactive' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const subscriptionStatusOptions = [
|
|
||||||
{ name: '활성', value: 'active' },
|
|
||||||
{ name: '만료', value: 'expired' },
|
|
||||||
{ name: '일시중지', value: 'paused' }
|
|
||||||
];
|
|
||||||
|
|
||||||
// 다이얼로그 제목
|
// 다이얼로그 제목
|
||||||
const dialogTitle = computed(() => {
|
const dialogTitle = computed(() => {
|
||||||
return isNewPlan.value ? '구독 플랜 추가' : '구독 플랜 수정';
|
return isNewPlan.value ? '구독 플랜 추가' : '구독 플랜 수정';
|
||||||
@@ -498,30 +472,6 @@ const deleteSubscription = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 상태 이름 가져오기
|
|
||||||
// getStatusName 함수 제거(일원화)
|
|
||||||
switch (status) {
|
|
||||||
case 'active':
|
|
||||||
return '활성';
|
|
||||||
case 'inactive':
|
|
||||||
return '비활성';
|
|
||||||
default:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 상태 심각도 가져오기
|
|
||||||
const getStatusSeverity = (status) => {
|
|
||||||
switch (status) {
|
|
||||||
case 'active':
|
|
||||||
return 'success';
|
|
||||||
case 'inactive':
|
|
||||||
return 'danger';
|
|
||||||
default:
|
|
||||||
return 'info';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 금액 포맷팅
|
// 금액 포맷팅
|
||||||
const formatCurrency = (amount) => {
|
const formatCurrency = (amount) => {
|
||||||
return new Intl.NumberFormat('ko-KR', {
|
return new Intl.NumberFormat('ko-KR', {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<Badge :value="getRoleName(slotProps.data.role)" :severity="getRoleSeverity(slotProps.data.role)" />
|
<Badge :value="getRoleName(slotProps.data.role)" :severity="getRoleSeverity(slotProps.data.role)" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
<Select v-model="filterModel.value" @change="filterCallback()" :options="roleOptions" optionLabel="name" optionValue="value" placeholder="역할 선택" class="p-column-filter" />
|
<Select v-model="filterModel.value" @change="filterCallback()" :options="ROLE_OPTIONS" optionLabel="name" optionValue="value" placeholder="역할 선택" class="p-column-filter" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="status" header="상태" sortable style="width: 10%">
|
<Column field="status" header="상태" sortable style="width: 10%">
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<Badge :value="getStatusLabel(slotProps.data.status)" :severity="getStatusSeverity(slotProps.data.status)" />
|
<Badge :value="getStatusLabel(slotProps.data.status)" :severity="getStatusSeverity(slotProps.data.status)" />
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
<Select v-model="filterModel.value" @change="filterCallback()" :options="statusOptions" optionLabel="name" optionValue="value" placeholder="상태 선택" class="p-column-filter" />
|
<Select v-model="filterModel.value" @change="filterCallback()" :options="STATUS_OPTIONS" optionLabel="name" optionValue="value" placeholder="상태 선택" class="p-column-filter" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="createdAt" header="가입일" sortable style="width: 12%">
|
<Column field="createdAt" header="가입일" sortable style="width: 12%">
|
||||||
@@ -90,13 +90,13 @@
|
|||||||
|
|
||||||
<div class="field mb-3">
|
<div class="field mb-3">
|
||||||
<label for="role">역할</label>
|
<label for="role">역할</label>
|
||||||
<Select id="role" v-model="user.role" :options="roleOptions" optionLabel="name" optionValue="value" placeholder="역할 선택" required class="w-full" />
|
<Select id="role" v-model="user.role" :options="ROLE_OPTIONS" optionLabel="name" optionValue="value" placeholder="역할 선택" required class="w-full" />
|
||||||
<small class="p-error" v-if="submitted && !user.role">역할은 필수입니다.</small>
|
<small class="p-error" v-if="submitted && !user.role">역할은 필수입니다.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field mb-3">
|
<div class="field mb-3">
|
||||||
<label for="status">상태</label>
|
<label for="status">상태</label>
|
||||||
<Select id="status" v-model="user.status" :options="statusOptions" optionLabel="name" optionValue="value" placeholder="상태 선택" required class="w-full" />
|
<Select id="status" v-model="user.status" :options="STATUS_OPTIONS" optionLabel="name" optionValue="value" placeholder="상태 선택" required class="w-full" />
|
||||||
<small class="p-error" v-if="submitted && !user.status">상태는 필수입니다.</small>
|
<small class="p-error" v-if="submitted && !user.status">상태는 필수입니다.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getStatusLabel } from '@/utils/enumMappings';
|
import { getStatusLabel, getRoleName, getRoleSeverity, getStatusSeverity, STATUS_OPTIONS, ROLE_OPTIONS } from '@/utils/enumMappings';
|
||||||
import { ref, onMounted, reactive, computed } from 'vue';
|
import { ref, onMounted, reactive, computed } from 'vue';
|
||||||
import { useToast } from 'primevue/usetoast';
|
import { useToast } from 'primevue/usetoast';
|
||||||
import adminService from '@/services/adminService';
|
import adminService from '@/services/adminService';
|
||||||
@@ -147,25 +147,6 @@ const filters = ref({
|
|||||||
status: { value: null, matchMode: 'equals' }
|
status: { value: null, matchMode: 'equals' }
|
||||||
});
|
});
|
||||||
|
|
||||||
// 역할 옵션
|
|
||||||
const roleOptions = [
|
|
||||||
{ name: '관리자', value: 'admin' },
|
|
||||||
{ name: '클럽 관리자', value: 'clubadmin' },
|
|
||||||
{ name: '일반 사용자', value: 'user' }
|
|
||||||
];
|
|
||||||
|
|
||||||
// 상태 옵션
|
|
||||||
const statusOptions = [
|
|
||||||
{ name: getStatusLabel('active'), value: 'active' },
|
|
||||||
{ name: getStatusLabel('inactive'), value: 'inactive' },
|
|
||||||
{ name: getStatusLabel('pending'), value: 'pending' },
|
|
||||||
{ name: getStatusLabel('suspended'), value: 'suspended' }
|
|
||||||
];
|
|
||||||
{ name: '활성', value: 'active' },
|
|
||||||
{ name: '비활성', value: 'inactive' },
|
|
||||||
{ name: '정지', value: 'suspended' }
|
|
||||||
];
|
|
||||||
|
|
||||||
// 다이얼로그 제목
|
// 다이얼로그 제목
|
||||||
const dialogTitle = computed(() => {
|
const dialogTitle = computed(() => {
|
||||||
return isNewUser.value ? '사용자 추가' : '사용자 수정';
|
return isNewUser.value ? '사용자 추가' : '사용자 수정';
|
||||||
@@ -273,62 +254,6 @@ const deleteUser = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 역할 이름 가져오기
|
|
||||||
const getRoleName = (role) => {
|
|
||||||
switch (role) {
|
|
||||||
case 'admin':
|
|
||||||
return '관리자';
|
|
||||||
case 'clubadmin':
|
|
||||||
return '클럽 관리자';
|
|
||||||
case 'user':
|
|
||||||
return '일반 사용자';
|
|
||||||
default:
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 역할 심각도 가져오기
|
|
||||||
const getRoleSeverity = (role) => {
|
|
||||||
switch (role) {
|
|
||||||
case 'admin':
|
|
||||||
return 'danger';
|
|
||||||
case 'clubadmin':
|
|
||||||
return 'warning';
|
|
||||||
case 'user':
|
|
||||||
return 'info';
|
|
||||||
default:
|
|
||||||
return 'info';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 상태 이름 가져오기
|
|
||||||
// getStatusName 함수 제거(일원화)
|
|
||||||
switch (status) {
|
|
||||||
case 'active':
|
|
||||||
return '활성';
|
|
||||||
case 'inactive':
|
|
||||||
return '비활성';
|
|
||||||
case 'suspended':
|
|
||||||
return '정지';
|
|
||||||
default:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 상태 심각도 가져오기
|
|
||||||
const getStatusSeverity = (status) => {
|
|
||||||
switch (status) {
|
|
||||||
case 'active':
|
|
||||||
return 'success';
|
|
||||||
case 'inactive':
|
|
||||||
return 'secondary';
|
|
||||||
case 'suspended':
|
|
||||||
return 'danger';
|
|
||||||
default:
|
|
||||||
return 'info';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 날짜 포맷팅
|
// 날짜 포맷팅
|
||||||
const formatDate = (date) => {
|
const formatDate = (date) => {
|
||||||
return date ? dayjs(date).format('YYYY-MM-DD') : '-';
|
return date ? dayjs(date).format('YYYY-MM-DD') : '-';
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
{{ formatDate(slotProps.data.startDate) }}
|
{{ formatDate(slotProps.data.startDate) }}
|
||||||
</template>
|
</template>
|
||||||
<template #filter="{ filterModel, filterCallback }">
|
<template #filter="{ filterModel, filterCallback }">
|
||||||
<Datepicker v-model="filterModel.value" @date-select="filterCallback()" dateFormat="yy-mm-dd" placeholder="날짜 선택" />
|
<DatePicker v-model="filterModel.value" @date-select="filterCallback()" dateFormat="yy-mm-dd" placeholder="날짜 선택" />
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
<Column field="location" header="장소" sortable style="width: 15%"></Column>
|
<Column field="location" header="장소" sortable style="width: 15%"></Column>
|
||||||
|
|||||||
Reference in New Issue
Block a user