용어집 작업

This commit is contained in:
Dang 2025-01-24 15:03:55 +09:00
parent eef87a18d1
commit f32a45c69c
5 changed files with 203 additions and 94 deletions

View File

@ -0,0 +1,49 @@
<template>
<ul class="cate-list list-unstyled d-flex flex-wrap mb-0">
<li
v-for="category in lists"
:key="category.CMNCODVAL"
class="mt-2 mx-1"
>
<button
type="button"
class="btn"
:class="{
'btn-outline-primary': category !== selectedCategory,
'btn-primary': category === selectedCategory
}"
@click="selectCategory(category)"
>{{ category.CMNCODNAM }}</button>
</li>
</ul>
</template>
<script setup>
import { defineProps, ref } from 'vue';
// lists prop
const props = defineProps({
lists: {
type: Array,
required: true,
},
});
//
const selectedCategory = ref(null);
const selectCategory = (category) => {
selectedCategory.value = category;
};
</script>
<style scoped>
.cate-list {
margin-left: -0.25rem;
}
@media screen and (max-width:450px) {
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<div>
<!-- 한글 버튼들 -->
<ul>
<li v-for="char in koreanChars" :key="char" >
<button type="button" class="nav-link" @click="filterByKoreanChar(char)">
{{ char }}
</button>
</li>
</ul>
<!-- 영어 버튼들 -->
<ul>
<li v-for="char in englishChars" :key="char">
<button type="button" class="nav-link" @click="filterByEnglishChar(char)">
{{ char }}
</button>
</li>
</ul>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const emit = defineEmits();
const koreanChars = ['ㄱ', 'ㄴ', 'ㄷ', 'ㄹ'];
const englishChars = ['a', 'b', 'c', 'd', 'e'];
//
const filterByKoreanChar = (char) => {
emit('filter', char, 'korean');
};
//
const filterByEnglishChar = (char) => {
emit('filter', char, 'english');
};
</script>
<style scoped>
.nav-pills {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<li class="mt-5">
<div class="d-flex align-items-center">
<div class="w-100 d-flex align-items-center">
<span class="btn btn-primary">{{ item.category }}</span>
<strong class="mx-2 w-75">{{ item.WRDDICTTL }}</strong>
</div>
<EditBtn />
</div>
<p class="mt-5">{{ item.WRDDICCON }}</p>
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
<div class="d-flex flex-wrap align-items-center mb-50">
<div class="avatar avatar-sm me-2">
<img :src="getProfileImage(item.author.profileImage)" alt="최초 작성자" class="rounded-circle">
</div>
<div>
<p class="mb-0 small fw-medium">{{ formatDate(item.author.createdAt) }}</p>
</div>
</div>
</div>
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
<div class="d-flex flex-wrap align-items-center mb-50">
<div class="avatar avatar-sm me-2">
<img :src="getProfileImage(item.lastEditor.profileImage)" alt="최근 작성자" class="rounded-circle">
</div>
<div>
<p class="mb-0 small fw-medium">{{ formatDate(item.lastEditor.updatedAt) }}</p>
</div>
</div>
</div>
</li>
</template>
<script setup>
import EditBtn from '@/components/button/EditBtn.vue';
// Props
defineProps({
item: {
type: Object,
required: true,
},
});
//
const formatDate = (dateString) => new Date(dateString).toLocaleString();
//
const getProfileImage = (imagePath) =>
imagePath ? `/img/avatars/${imagePath}` : '/img/avatars/default-Profile.jpg';
</script>

View File

@ -0,0 +1,21 @@
<template>
<div>
<FormSelect/>
<button>쇼핑몰</button>
<button>저장</button>
</div>
<div>
<FormInput/>
</div>
<div>
<QEditor/>
<button>저장</button>
<button @click="$emit('close')">취소</button>
</div>
</template>
<script setup>
import QEditor from '@/components/editor/QEditor.vue';
import FormInput from '@/components/input/FormInput.vue';
import FormSelect from '@/components/input/FormSelect.vue';
</script>

View File

@ -15,47 +15,26 @@
<!-- 단어 갯수, 작성하기 --> <!-- 단어 갯수, 작성하기 -->
<div class="mt-4"> <div class="mt-4">
단어 : {{ filteredList.length }} 단어 : {{ filteredList.length }}
<WriteButton /> <WriteButton @click="toggleWriteForm" />
</div> </div>
<!-- -->
<div> <div>
<div class="nav-align-top"> <DictAlphabetFilter/>
<ul class="nav nav-pills" role="tablist">
<li class="nav-item" role="presentation">
<button type="button" class="nav-link"></button>
</li>
<li class="nav-item" role="presentation">
<button type="button" class="nav-link"></button>
</li>
<li class="nav-item" role="presentation">
<button type="button" class="nav-link"></button>
</li>
</ul>
<ul class="nav nav-pills" role="tablist">
<li class="nav-item" role="presentation">
<button type="button" class="nav-link">a</button>
</li>
<li class="nav-item" role="presentation">
<button type="button" class="nav-link">b</button>
</li>
<li class="nav-item" role="presentation">
<button type="button" class="nav-link">c</button>
</li>
</ul>
</div>
</div> </div>
<!-- 카테고리 --> <!-- 카테고리 -->
<div> <div v-if="cateList.length" class="mt-5">
<ul v-if="cateList.length"> <CategoryBtn :lists="cateList" />
<li v-for="item in cateList" :key="item.CMNCODVAL"> </div>
<button>{{ item.CMNCODNAM }}</button>
</li> <!-- 작성 -->
</ul> <div v-if="isWriteVisible" class="mt-5">
<DictWrite @close="isWriteVisible = false" />
</div> </div>
<!-- 용어 리스트 --> <!-- 용어 리스트 -->
<div> <div class="mt-10">
<!-- 로딩 중일 --> <!-- 로딩 중일 -->
<div v-if="loading">로딩 중...</div> <div v-if="loading">로딩 중...</div>
@ -63,48 +42,18 @@
<div v-if="error" class="error">{{ error }}</div> <div v-if="error" class="error">{{ error }}</div>
<!-- 단어 목록 --> <!-- 단어 목록 -->
<ul v-if="filteredList.length" class="word-list"> <ul v-if="filteredList.length" class="px-0 list-unstyled">
<li v-for="item in filteredList" :key="item.WRDDICSEQ"> <DictCard
<div class="d-flex"> v-for="item in filteredList"
<div> :key="item.WRDDICSEQ"
({{ item.category }}) <strong>{{ item.WRDDICTTL }}</strong> :item="item"
</div> />
<WriteButton />
</div>
<p>{{ item.WRDDICCON }}</p>
<div>
<img :src="'/img/avatars/' + item.author.profileImage" alt="최초 작성자" />
최초 작성자 {{ item.author.name }}
작성일 {{ new Date(item.author.createdAt).toLocaleString() }}
</div>
<div>
<img :src="'/img/avatars/' + item.lastEditor.profileImage" alt="최근 수정자" />
최근 수정자 {{ item.lastEditor.name }}
수정일 {{ new Date(item.lastEditor.updatedAt).toLocaleString() }}
</div>
</li>
</ul> </ul>
<!-- 데이터가 없을 --> <!-- 데이터가 없을 -->
<div v-else-if="!loading && !error">용어집의 용어가 없습니다.</div> <div v-else-if="!loading && !error">용어집의 용어가 없습니다.</div>
</div> </div>
<!-- 작성 수정 -->
<div>
<div>
<FormSelect/>
<button>쇼핑몰</button>
<button>저장</button>
</div>
<div>
<FormInput/>
</div>
<div>
<QEditor/>
<button>저장</button>
</div>
</div>
</div> </div>
</div> </div>
@ -116,35 +65,36 @@
import axios from '@api'; import axios from '@api';
import SearchBar from '@c/search/SearchBar.vue'; import SearchBar from '@c/search/SearchBar.vue';
import WriteButton from '@c/button/WriteBtn.vue'; import WriteButton from '@c/button/WriteBtn.vue';
import QEditor from '@/components/editor/QEditor.vue'; import CategoryBtn from '@/components/category/CategoryBtn.vue';
import FormInput from '@/components/input/FormInput.vue'; import DictCard from '@/components/wordDict/DictCard.vue';
import FormSelect from '@/components/input/FormSelect.vue'; import DictWrite from '@/components/wordDict/DictWrite.vue';
import DictAlphabetFilter from '@/components/wordDict/DictAlphabetFilter.vue';
// /** */ //
// const goDetail = idx => { const loading = ref(false);
// router.push(`/board/get/${idx}`); const error = ref('');
// };
// //
const wordList = ref([]); const wordList = ref([]);
// //
const cateList = ref([]); const cateList = ref([]);
const loading = ref(false);
const error = ref('');
// //
const searchText = ref(''); const searchText = ref('');
// API //
const isWriteVisible = ref(false);
// API
const fetchAllData = async () => { const fetchAllData = async () => {
loading.value = true; loading.value = true;
error.value = ''; error.value = '';
try { try {
// //
const wordResponse = await axios.get('worddict/getWordList'); const wordResponse = await axios.get('worddict/getWordList');
wordList.value = wordResponse.data.data.data; wordList.value = wordResponse.data.data.data;
console.log('단어 데이터:', wordList.value); console.log('용어집 데이터:', wordList.value);
// //
const categoryResponse = await axios.get('worddict/getWordCategory'); const categoryResponse = await axios.get('worddict/getWordCategory');
cateList.value = categoryResponse.data.data; cateList.value = categoryResponse.data.data;
@ -173,8 +123,10 @@
) )
); );
// toggle
const toggleWriteForm = () => {
isWriteVisible.value = !isWriteVisible.value;
};
// `watchEffect` API // `watchEffect` API
watchEffect(() => { watchEffect(() => {
@ -189,17 +141,6 @@
padding: 0 30px padding: 0 30px
} }
.word-list {
padding-left: 0;
}
.word-list li {
list-style: none;
}
.word-list li ~ li {
margin-top: 20px;
}
.error { .error {
color: red; color: red;
font-weight: bold; font-weight: bold;