프로젝트 목록

This commit is contained in:
yoon 2025-02-13 14:48:51 +09:00
parent 380fd9cb1d
commit 6edb911d43
3 changed files with 200 additions and 67 deletions

View File

@ -1,22 +1,35 @@
<template>
<div class="card mb-3 shadow-sm border">
<div class="row g-0">
<!-- 게시물 내용 섹션 -->
<div>
<div class="card-body">
<!-- 제목 -->
<h5 class="card-title">
{{ title }}
<span class="text-muted me-3" v-if="attachment">
<i class="fa-solid fa-paperclip"></i>
</span>
</h5>
<!-- 본문 -->
<div class="card-text line-clamp-2 my-5">{{ content }}</div>
<!-- 날짜 -->
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-start">
<small class="text-muted">{{ formattedDate }}</small>
</div>
<div class="card-body">
<!-- 제목 -->
<h5 class="card-title">
{{ title }}
</h5>
<!-- 날짜 -->
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
<i class="bx bx-calendar"></i>
<div class="ms-2">날짜</div>
<div class="ms-12">{{ date }}</div>
</div>
<!-- 참여자 -->
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
<i class="bx bxs-user"></i>
<div class="ms-2">참여자</div>
<UserList class="ms-8 mb-0" />
</div>
<!-- 설명 -->
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
<i class="bx bx-detail"></i>
<div class="ms-2">설명</div>
<div class="ms-12">{{ description }}</div>
</div>
<!-- 주소 -->
<div class="d-flex flex-column flex-sm-row align-items-center pb-2">
<i class="bx bxs-map"></i>
<div class="ms-2">주소</div>
<div class="ms-12">{{ address }}</div>
<button type="button" class="btn btn-info ms-auto">log</button>
</div>
</div>
</div>
@ -24,40 +37,26 @@
</template>
<script setup>
import { computed } from 'vue';
import { defineProps } from 'vue';
import { defineProps } from 'vue';
import UserList from '../user/UserList.vue';
// Props
const props = defineProps({
category: {
type: String,
required: false,
},
title: {
type: String,
required: true,
},
content: {
type: String,
required: true,
},
date: {
type: String,
required: true,
},
attachment: {
type: Boolean,
default: false,
}
});
// formattedDate computed
const formattedDate = computed(() => {
const date = new Date(props.date);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(
date.getDate()
).padStart(2, "0")} ${String(date.getHours()).padStart(2, "0")}:${String(
date.getMinutes()
).padStart(2, "0")}`;
});
// Props
const props = defineProps({
title: {
type: String,
required: true,
},
date: {
type: String,
required: true,
},
description: {
type: String,
required: false,
},
address: {
type: String,
required: true,
},
});
</script>

View File

@ -7,9 +7,9 @@
<div v-for="post in posts" :key="post.id" @click="goDetail(post.id)">
<ProjectCard
:title="post.title"
:content="post.content"
:description="post.description"
:date="post.date"
:attachment="post.attachment || false"
:address="post.address"
/>
</div>
</div>
@ -24,18 +24,16 @@ const posts = ref([
{
id: 1,
title: 'Vue 3 Composition API 소개',
content: 'Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다. Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다. Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다. Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다. Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다. Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다.',
description: 'Composition API를 사용하여 Vue 3에서 효율적으로 개발하는 방법을 알아봅니다.',
date: '2025-02-10',
comments: 4,
attachment: true
address: '서울특별시 구로구'
},
{
id: 2,
title: 'Spring Boot로 REST API 만들기',
content: 'Spring Boot를 사용하여 간단한 RESTful API를 구현하는 방법을 다룹니다.',
description: 'Spring Boot를 사용하여 간단한 RESTful API를 구현하는 방법을 다룹니다.',
date: '2025-02-09',
comments: 2,
attachment: false
address: '서울특별시 강남구'
}
]);

View File

@ -1,19 +1,155 @@
<template>
<SearchBar />
<CategoryBtn :lists="yearCategory" />
<div class="d-flex align-items-center">
<CategoryBtn :lists="yearCategory" />
<WriteBtn class="mt-2 ms-auto" @click="openModal" />
<CenterModal :display="isModalOpen" @close="closeModal">
<template #title> 프로젝트 등록 </template>
<template #body>
<FormInput
title="이름"
name="name"
:is-essential="true"
:is-alert="nameAlert"
@update:alert="nameAlert = $event"
:value="name"
/>
<FormSelect
title="컬러"
name="color"
:is-essential="true"
:is-label="true"
:is-common="true"
:data="colorList"
@update:data="color = $event"
/>
<FormInput
title="시작 일"
:type="'date'"
name="startDay"
v-model="today"
:is-essential="true"
:is-alert="startDayAlert"
@update:data="startDay = $event"
@update:alert="startDayAlert = $event"
:value="startDay"
/>
<FormInput
title="종료 일"
name="endDay"
:type="'date'"
@update:data="endDay = $event"
:value="endDay"
/>
<FormInput
title="설명"
name="description"
@update:data="description = $event"
:value="description"
/>
<ArrInput
title="주소"
name="address"
:isEssential="true"
:is-row="true"
:is-alert="addressAlert"
@update:data="handleAddressUpdate"
@update:alert="addressAlert = $event"
:value="address"
/>
</template>
<template #footer>
<button class="btn btn-secondary" @click="closeModal">Close</button>
<button class="btn btn-primary" @click="handleSubmit">Save</button>
</template>
</CenterModal>
</div>
<ProjectCardList :category="selectedCategory" />
</template>
<script setup>
import SearchBar from '@c/search/SearchBar.vue';
import ProjectCardList from '@c/list/ProjectCardList.vue';
import CategoryBtn from '@c/category/CategoryBtn.vue';
import commonApi from '@/common/commonApi'
import { ref } from 'vue';
import SearchBar from '@c/search/SearchBar.vue';
import ProjectCardList from '@c/list/ProjectCardList.vue';
import CategoryBtn from '@c/category/CategoryBtn.vue';
import commonApi from '@/common/commonApi';
import { inject, ref } from 'vue';
import WriteBtn from '../button/WriteBtn.vue';
import CenterModal from '../modal/CenterModal.vue';
import FormSelect from '../input/FormSelect.vue';
import FormInput from '../input/FormInput.vue';
import ArrInput from '../input/ArrInput.vue';
import { useToastStore } from '@s/toastStore';
const selectedCategory = ref(null);
const dayjs = inject('dayjs');
const { yearCategory } = commonApi();
const today = dayjs().format('YYYY-MM-DD');
const toastStore = useToastStore();
const name = ref('');
const color = ref('');
const address = ref('');
const detailAddress = ref('');
const postcode = ref('');
const startDay = ref('');
const endDay = ref('');
const description = ref('');
const isModalOpen = ref(false);
const nameAlert = ref(false);
const addressAlert = ref(false);
const startDayAlert = ref(false);
const openModal = () => {
isModalOpen.value = true;
};
const closeModal = () => {
isModalOpen.value = false;
};
const selectedCategory = ref(null);
const { yearCategory, colorList } = commonApi({
loadColor: true,
colorType: 'YNP',
loadYearCategory: true,
});
//
const handleAddressUpdate = addressData => {
address.value = addressData.address;
detailAddress.value = addressData.detailAddress;
postcode.value = addressData.postcode;
};
const handleSubmit = () => {
addressAlert.value = address.value.trim() === '';
nameAlert.value = name.value.trim() === '';
startDayAlert.value = startDay.value.trim() === '';
$api.post('project/insert', {
projctNam: name.value,
projctCol: color.value,
projctCdt: startDay.value,
projctEdt: endDay.value,
projctDes: description.value,
projctAdd: address.value,
projctDtl: detailAddress.value,
projctZip: postcode.value,
})
.then(res => {
if (res.status === 200) {
toastStore.onToast('프로젝트가 등록되었습니다.', 's');
closeModal();
}
})
};
</script>