Vue PWA mylog

mylog 내것 개선

그랜파 개발자 2024. 12. 4. 04:18

Vue로 PWA 개발 - 그랜파 개발자

Vue 프로젝트 Beta Test : mylog, 일상의 기록

개발이 진행됨에 따라 소스 코드를 계속 추가해 갑니다.

mylog 내것 개선

카테고리가 생겼으니 내 마이로그를 볼 때에도 카테고리별로 볼 수 있습니다.
‘내것’ 페이지에서 카테고리를 선택하면 선택한 카테고리의 마이로그만 볼 수 있도록 수정합니다.

1. 카테고리 보이기

<!-- src/views/MyMyLogsView.vue -->
<template>  
  <v-container> 
    . . . 
    <v-row v-if="userMylogs.length > 0">
        . . .
        <v-card>
          <!--카테고리-->
          <v-card-text class="mb-n5" v-if="mylog.category" style="font-size:1em">
            {{ mylog.category }}
          </v-card-text>
          <v-card-text  class="mb-n5" v-else style="font-size:1em">
            카테고리 없음
          </v-card-text>
          . . .
        </v-card>
      </v-col>
    </v-row>
    . . .
  </v-container>
</template>

<script>
import { mapActions, mapState, mapGetters } from "vuex";
import sanitizeHtml from 'sanitize-html';

export default {
  data() {
    return {      
      myCategories: [],
      selectedCategory: null, // 선택된 카테고리
    };
  }, 
  computed: {
    ...mapGetters('mylogs',['userMylogs', 'loading']),
    ...mapState('mylogs', ['categories']),
    . . .
    }
  },
  methods: {
    ...mapActions('mylogs', ['fetchUserMylogs', 'fetchUserMylogsOrderByDateAsc', 'fetchUserMylogsOrderByViews','fetchCategories']),
    . . .
  },
  mounted() {
    const userId = this.$store.state.auth.user.id;
  
    this.fetchCategories(userId); // Firestore에서 카테고리 데이터 가져오기
    // 카테로그 이름만 가져온다.
    //console.log(this.categories);
    this.myCategories = this.categories.map(category => category.name);
    this.myCategories.unshift('카테고리 없음');
    this.myCategories.unshift('전체 보기');    

    //console.log(userId, this.selectedCategory);
    this.fetchUserMylogs({userId, category:null}); // 본인 작성 글 가져오기 
  },
};
</script>

2. 카테고리 로드

// src/store/modules/mylogs.js

async fetchCategories({ commit }, userId) {
  if (!userId) return;

  try {
    // 사용자 ID로 필터링된 카테고리 가져오기
    const q = query( collection(db, "categories"),  where("userId", "==", userId)  );
    const querySnapshot = await getDocs(q);

    // DB에서 로드한 카테고리를 배열에 넣는다.
    let categories = [];
    categories = querySnapshot.docs.map((doc) => ({ id: doc.id,  ...doc.data()  }));

    // 로드한 카테고리를 상태에 저장한다.
    commit("setCatogories", categories);

  } catch (error) {
    console.error("Error fetching categories:", error);
  }
},

3. MyMyLogsView.vue

<!-- src/views/MyMyLogsView.vue -->
<template>  
  <v-container> 
    <v-row>
      <v-col><v-card-title style="font-size:1em">{{ getMylogName }}</v-card-title></v-col>
    </v-row>
      
    <v-row class="mt-n5">
      <v-col > 
        <v-select class="mt-2" v-model="selectedCategory" :items="myCategories" 
                  label="카테고리를 선택하세요" outlined dense @change="onItemChange">
        </v-select>
        <span style="text-align: right">
          <v-btn text @click="viewByDateDesc">최신순</v-btn> 
          <v-btn text @click="viewByDateAsc">오래된순</v-btn> 
          <v-btn text @click="viewByViews">조회순</v-btn> 
        </span>
      </v-col>
    </v-row>
 
    <v-row v-if="userMylogs.length > 0">
      <v-col v-for="mylog in userMylogs" :key="mylog.id" @click="goToMylogDetail(mylog.id)" cols="12">
        <v-card>
          <!--카테고리-->
          <v-card-text class="mb-n5" v-if="mylog.category" style="font-size:1em">
            {{ mylog.category }}
          </v-card-text>
          <v-card-text  class="mb-n5" v-else style="font-size:1em">
            카테고리 없음
          </v-card-text>
          
          <v-card-title style="font-size:1em">{{ mylog.title }}</v-card-title>
          <!-- eslint-disable -->
          <v-card-text style="font-size:1em" class="mt-n2 mb-n6" v-html="sanitizeContent(mylog.content)"></v-card-text>
          <!-- eslint-enable -->
          <v-card-subtitle>
            <span v-if="mylog.commentCount> 0" style="cursor: pointer">댓글 {{mylog.commentCount }}&nbsp;</span> 
            {{ mylog.userName }} . {{ formatDate(mylog.createdAt) }} 
            <span v-if="mylog.views > 0" > ({{ mylog.views }})</span>
          </v-card-subtitle>
        </v-card>
      </v-col>
    </v-row>
    
    <div class="text-center">
      <v-progress-circular v-if="loading" indeterminate></v-progress-circular>
    </div>

  </v-container>
</template>

<script>
import { mapActions, mapState, mapGetters } from "vuex";
import sanitizeHtml from 'sanitize-html';

export default {
  data() {
    return {      
      myCategories: [],
      selectedCategory: null, // 선택된 카테고리
    };
  }, 
  computed: {
    ...mapGetters('mylogs',['userMylogs', 'loading']),
    ...mapState('mylogs', ['categories']),
    getMylogName() {
      return this.$store.state.auth.user.mylogname;
    }
  },
  methods: {
    ...mapActions('mylogs', ['fetchUserMylogs', 'fetchUserMylogsOrderByDateAsc', 'fetchUserMylogsOrderByViews','fetchCategories']),

    goToMylogDetail(mylogId) {
      this.$router.push({ name: 'mylog', params: { id: mylogId } });
    },
    // 본인 작성 글 가져오기 - 최신순
    viewByDateDesc() { 
      const userId = this.$store.state.auth.user.id; 
      if(this.selectedCategory == "전체 보기")
        this.fetchUserMylogs({userId, category:null});
      else
        this.fetchUserMylogs({userId, category: this.selectedCategory});   
    },
    // 본인 작성 글 가져오기 - 오래된 순
    viewByDateAsc() { 
      const userId = this.$store.state.auth.user.id;
      if(this.selectedCategory == "전체 보기")
        this.fetchUserMylogsOrderByDateAsc({userId, category:null});
      else
        this.fetchUserMylogsOrderByDateAsc({userId, category: this.selectedCategory});    
    },
    // 본인 작성 글 가져오기 - 조회순
    viewByViews() { 
      const userId = this.$store.state.auth.user.id;
      if(this.selectedCategory == "전체 보기")
        this.fetchUserMylogsOrderByViews({userId, category:null});
      else
        this.fetchUserMylogsOrderByViews({userId, category: this.selectedCategory}); 
    },
    // content를 안전한 html로 바꿔준다.
    sanitizeContent(content) {
      return sanitizeHtml(content.replace(/\n/g, '<br>'), {
        allowedTags: ['b', 'i', 'em', 'strong', 'p', 'br'],
        allowedAttributes: {}
      });
    },
    formatDate(date) { 
      if (date && date.toDate) {
        return date.toDate().toISOString().replace('T', ' ').substring(0, 16); 
      }
      return '';
    },
    onItemChange(category) {
      //console.log("선택값이 변경되었습니다:", category);
      const userId = this.$store.state.auth.user.id;
      if(category == "전체 보기")
        this.fetchUserMylogs({userId, category:null});
      else
        this.fetchUserMylogs({userId, category}); 
    },
  },
  mounted() {
    const userId = this.$store.state.auth.user.id;
  
    this.fetchCategories(userId); // Firestore에서 카테고리 데이터 가져오기
    // 카테로그 이름만 가져온다.
    //console.log(this.categories);
    this.myCategories = this.categories.map(category => category.name);
    this.myCategories.unshift('카테고리 없음');
    this.myCategories.unshift('전체 보기');    

    //console.log(userId, this.selectedCategory);
    this.fetchUserMylogs({userId, category:null}); // 본인 작성 글 가져오기 
  },
};
</script>

Vue PWA 프로젝트, mylog 코드

'Vue PWA mylog' 카테고리의 다른 글

mylog 모아보기 개선  (0) 2024.12.05
mylog 쓰기 개선  (1) 2024.12.03
mylog 카테고리  (0) 2024.12.02
mylog FCM 받기  (1) 2024.12.01
mylog FCM 보내기  (0) 2024.11.30