Files
core/hwe/ts/PageBoard.vue
T
Hide_D 4f4533e533 refac: linter 관련 설정 변경 및 적용, map_theme 변수 제거
- eslint에 prettier 조합
- prettierrc에 width 120, tabWidth 2
- gameStor->map_theme 제거
- map_theme, mapTheme를 GameConst::$mapName으로 대체
- eslint에서 vue/vue3-essential 대신 vue3-recommended 적용
  - vue/max-attributes-per-line 완화
  - vue/v-on-event-hyphenation 해제
  - vue/attribute-hyphenation 해제
- 일부 tsc import type warning 해결
- 일부 vue template type warning 해결
- 일부 vue SFC를 script setup으로 변경
  - TipTap
  - TopBackBar
  - BottomBackBar
  - BoardArticle
  - ProcessCity
2022-03-29 02:06:47 +09:00

192 lines
4.7 KiB
Vue

<template>
<div id="container">
<TopBackBar :title="title" />
<div id="newArticle" class="bg0">
<div class="newArticleHeader bg2 center"> 게시물 작성</div>
<div class="row gx-0">
<div class="col-2 col-md-1 articleTitle bg1 center">제목</div>
<div class="col-10 col-md-11">
<input v-model="newArticle.title" class="titleInput" type="text" maxlength="250" placeholder="제목" />
</div>
</div>
<div class="row gx-0">
<div class="col-2 col-md-1 bg1 center">내용</div>
<div class="col-10 col-md-11">
<textarea
ref="newArticleTextForm"
v-model="newArticle.text"
class="contentInput autosize"
placeholder="내용"
@input="autoResizeTextarea"
/>
</div>
</div>
<div class="row">
<div class="col-8 col-md-10" />
<div class="col-4 col-md-2 d-grid">
<b-button id="submitArticle" @click="submitArticle"> 등록 </b-button>
</div>
</div>
</div>
<div id="board">
<template v-if="articles && articles.length">
<board-article
v-for="article in articles"
:key="article.no"
:article="article"
@submitComment="reloadArticles"
/>
</template>
<template v-else> 게시물이 없습니다. </template>
</div>
<BottomBar />
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, ref } from "vue";
import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue";
import BoardArticle from "@/components/BoardArticle.vue";
import { convertFormData } from "@util/convertFormData";
import axios from "axios";
import type { InvalidResponse } from "@/defs";
import { autoResizeTextarea } from "@util/autoResizeTextarea";
import { unwrap } from "@util/unwrap";
export type BoardResponse = {
result: true;
articles: Record<number, BoardArticleItem>;
};
export type BoardArticleItem = {
no: number;
nation_no: number;
is_secret?: boolean;
date: string;
general_no: number;
author: string;
author_icon: string;
title: string;
text: string;
comment: BoardCommentItem[];
};
export type BoardCommentItem = {
no: number;
nation_no: number;
is_secret?: boolean;
date: string;
document_no: number;
general_no: number;
author: string;
text: string;
};
export default defineComponent({
name: "PageBoard",
components: {
TopBackBar,
BottomBar,
BoardArticle,
},
props: {
isSecretBoard: {
type: Boolean,
required: true,
},
},
setup(props) {
const newArticleTextForm = ref<HTMLInputElement>();
const articles = reactive<BoardArticleItem[]>([]);
const reloadArticles = async () => {
let boardResponse: BoardResponse;
try {
const response = await axios({
url: "j_board_get_articles.php",
responseType: "json",
method: "post",
data: convertFormData({
isSecret: props.isSecretBoard,
}),
});
const result: InvalidResponse | BoardResponse = response.data;
if (!result.result) {
throw result.reason;
}
boardResponse = result;
} catch (e) {
console.error(e);
alert(`에러: ${e}`);
return;
}
articles.length = 0;
articles.push(...Object.values(boardResponse.articles));
articles.reverse();
};
onMounted(async () => {
await reloadArticles();
});
return {
newArticleTextForm,
articles,
reloadArticles,
};
},
data() {
return {
title: this.isSecretBoard ? "기밀실" : "회의실",
newArticle: {
title: "",
text: "",
},
};
},
methods: {
autoResizeTextarea,
async submitArticle() {
const { title, text } = this.newArticle;
if (!title && !text) {
return;
}
let result: InvalidResponse;
try {
const response = await axios({
url: "j_board_article_add.php",
method: "post",
responseType: "json",
data: convertFormData({
isSecret: this.isSecretBoard,
title,
text,
}),
});
result = response.data;
if (!result.result) {
throw result.reason;
}
} catch (e) {
console.error(e);
alert(`실패했습니다. :${e}`);
return;
}
this.newArticle = { title: "", text: "" };
const newArticleTextForm = unwrap(this.newArticleTextForm);
newArticleTextForm.style.height = "auto";
await this.reloadArticles();
},
},
});
</script>