init
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<Dialog
|
||||
:visible="visible"
|
||||
@update:visible="$emit('update:visible', $event)"
|
||||
:header="isNew ? '이벤트 추가' : '이벤트 수정'"
|
||||
:style="{ width: '650px' }"
|
||||
:modal="true"
|
||||
class="p-fluid"
|
||||
>
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label for="title">제목 *</label>
|
||||
<InputText id="title" v-model="eventModel.title" :class="{'p-invalid': submitted && !eventModel.title}" required autofocus />
|
||||
<small class="p-error" v-if="submitted && !eventModel.title">제목은 필수입니다.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label for="description">설명</label>
|
||||
<Textarea id="description" v-model="eventModel.description" rows="3" autoResize />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="eventType">이벤트 유형 *</label>
|
||||
<Dropdown id="eventType" v-model="eventModel.eventType" :options="eventTypeOptions" optionLabel="name" optionValue="value" placeholder="유형 선택" :class="{'p-invalid': submitted && !eventModel.eventType}" />
|
||||
<small class="p-error" v-if="submitted && !eventModel.eventType">이벤트 유형은 필수입니다.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="status">상태 *</label>
|
||||
<Dropdown id="status" v-model="eventModel.status" :options="statusOptions" optionLabel="name" optionValue="value" placeholder="상태 선택" :class="{'p-invalid': submitted && !eventModel.status}" />
|
||||
<small class="p-error" v-if="submitted && !eventModel.status">상태는 필수입니다.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="startDate">시작일 *</label>
|
||||
<Calendar id="startDate" v-model="eventModel.startDate" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :class="{'p-invalid': submitted && !eventModel.startDate}" />
|
||||
<small class="p-error" v-if="submitted && !eventModel.startDate">시작일은 필수입니다.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="endDate">종료일</label>
|
||||
<Calendar id="endDate" v-model="eventModel.endDate" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" :class="{'p-invalid': submitted && !eventModel.endDate}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="field">
|
||||
<label for="location">장소</label>
|
||||
<InputText id="location" v-model="eventModel.location" :class="{'p-invalid': submitted && !eventModel.location}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="maxParticipants">최대 참가자 수</label>
|
||||
<InputNumber id="maxParticipants" v-model="eventModel.maxParticipants" :min="0" showButtons />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="gameCount">게임 수</label>
|
||||
<InputNumber id="gameCount" v-model="eventModel.gameCount" :min="1" showButtons />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="participantFee">참가비</label>
|
||||
<InputNumber id="participantFee" v-model="eventModel.entryFee" :min="0" mode="currency" currency="KRW" locale="ko-KR" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<label for="registrationDeadline">등록 마감일</label>
|
||||
<Calendar id="registrationDeadline" v-model="eventModel.registrationDeadline" :showTime="true" dateFormat="yy-mm-dd" timeFormat="24" hourFormat="24" :showIcon="true" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<Button label="취소" icon="pi pi-times" class="p-button-text" @click="hideDialog" />
|
||||
<Button label="저장" icon="pi pi-check" class="p-button-text" @click="saveEvent" />
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, toRefs, computed } from 'vue';
|
||||
|
||||
const statusOptions = [
|
||||
{ name: '준비', value: '준비' },
|
||||
{ name: '활성', value: '활성' },
|
||||
{ name: '완료', value: '완료' },
|
||||
{ name: '취소', value: '취소' },
|
||||
{ name: '삭제', value: '삭제' }
|
||||
];
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
event: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
isNew: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
submitted: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:visible', 'save', 'hide']);
|
||||
|
||||
// 이벤트 타입 옵션
|
||||
const eventTypeOptions = [
|
||||
{ name: '정기전', value: '정기전' },
|
||||
{ name: '번개', value: '번개' },
|
||||
{ name: '연습', value: '연습' },
|
||||
{ name: '교류전', value: '교류전' },
|
||||
{ name: '이벤트', value: '이벤트' },
|
||||
{ name: '기타', value: '기타' }
|
||||
];
|
||||
|
||||
// 이벤트 모델
|
||||
const eventModel = ref({ ...props.event });
|
||||
|
||||
// 날짜 형식 변환
|
||||
const formatDate = (date) => {
|
||||
if (!date) return null;
|
||||
const d = new Date(date);
|
||||
d.setHours(d.getHours() + 9); // UTC to KST
|
||||
return d;
|
||||
};
|
||||
|
||||
// props 변경 시 이벤트 모델 업데이트
|
||||
watch(() => props.event, (newValue) => {
|
||||
const formattedEvent = {
|
||||
...newValue,
|
||||
startDate: formatDate(newValue.startDate),
|
||||
endDate: formatDate(newValue.endDate),
|
||||
registrationDeadline: formatDate(newValue.registrationDeadline)
|
||||
};
|
||||
eventModel.value = formattedEvent;
|
||||
}, { deep: true });
|
||||
|
||||
// 이벤트 저장 시 UTC로 변환
|
||||
const saveEvent = () => {
|
||||
const eventData = { ...eventModel.value };
|
||||
if (eventData.startDate) {
|
||||
const d = new Date(eventData.startDate);
|
||||
d.setHours(d.getHours() - 9); // KST to UTC
|
||||
eventData.startDate = d;
|
||||
}
|
||||
if (eventData.endDate) {
|
||||
const d = new Date(eventData.endDate);
|
||||
d.setHours(d.getHours() - 9); // KST to UTC
|
||||
eventData.endDate = d;
|
||||
}
|
||||
if (eventData.registrationDeadline) {
|
||||
const d = new Date(eventData.registrationDeadline);
|
||||
d.setHours(d.getHours() - 9); // KST to UTC
|
||||
eventData.registrationDeadline = d;
|
||||
}
|
||||
emit('save', eventData);
|
||||
};
|
||||
|
||||
// 다이얼로그 닫기
|
||||
const hideDialog = () => {
|
||||
emit('hide');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.field {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -0.25rem;
|
||||
}
|
||||
|
||||
.col-12 {
|
||||
width: 100%;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.md\:col-6 {
|
||||
width: 50%;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.p-dialog-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.p-dialog-footer {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
:deep(.p-dropdown),
|
||||
:deep(.p-calendar),
|
||||
:deep(.p-inputnumber) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.p-inputtext) {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user