회원가입 이후 우측창에서 '마이페이지'로 이동할 수 있는 링크를 볼 수 있다.
'마이페이지'에서는 회원가입 폼에서 입력한 자신의 정보와 기타 데이터를 볼 수 있다.
1 myPageInterface.js :: 인터페이스 생성
myPageInterface.js는 페이지 이름을 필터링한 뒤에 페이지 html코드를 랜더링하는 인터페이스 역할을 한다.
import myPageScreen from 'https://tistory1.daumcdn.net/tistory/2784544/skin/images/wd-myPageScreen_.js';
import { firebaseConfig } from 'https://tistory2.daumcdn.net/tistory/2784544/skin/images/wd-utils.js';
const firebaseApp = initializeApp(firebaseConfig());
const auth = getAuth();
window.addEventListener('load', async() => {
const content = document.getElementById('content')
auth.onAuthStateChanged(async(user) => {
if(user){
content.innerHTML = await myPageScreen.render(user);
if(myPageScreen.after_render) await myPageScreen.after_render(user);
}else{
}
})
});
|
[ wd-myPageInterface.js ]
auth.onAuthStateChanged( )의 리턴값, user가 존재할 경우에만 myPageScreen모듈의 .render( )메서드를 호출한다.
2 myPageScreen.js :: 페이지 랜더링
마이페이지에는 '세팅', '내 폴더', '제작기능', '찾기', '장바구니', '계좌' 5가지 탭이 있다. 사용자가 각 탭을 클릭할 때마다 FireStore DB는 요청받은 정보를 전달해야한다. 이를 위해서는 FireStore 관련 모듈이 필요하고, 각 버튼에 해당하는 랜더링 파일 6개가 필요하다.
myPageScreen.js 파일은 FireStore( )관련 모듈을 받고, 6개 탭에 관한 랜더링 모듈을 import한다. 또한 myPage 인터페이스에 전달하는 html태그를 반환한다. render( )메서드에는 html파일을 반환하고, after_render( )메서드는 해당 태그에 관한 사용자의 반응 이벤트를 구현해준다. 여기서 아이콘 관련 라이브러리는 "https://svgbox.net/iconset/materialui" svgBox를 이용한다.
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js'; import settingScreen from 'https://tistory2.daumcdn.net/tistory/2784544/skin/images/wd-mp-settingScreen.js';
import myfolderScreen from 'https://tistory3.daumcdn.net/tistory/2784544/skin/images/wd-mp-myfolderScreen.js';
import filmScreen from 'https://tistory3.daumcdn.net/tistory/2784544/skin/images/wd-mp-filmScreen.js';
import searchScreen from 'https://tistory3.daumcdn.net/tistory/2784544/skin/images/wd-mp-searchScreen.js';
import cartScreen from 'https://tistory3.daumcdn.net/tistory/2784544/skin/images/wd-mp-cartScreen.js';
import accountScreen from 'https://tistory1.daumcdn.net/tistory/2784544/skin/images/wd-mp-accountScreen.js';
const db = getFirestore();
const mypageRouter = {
'setting': settingScreen,
'myfolder': myfolderScreen,
'film': filmScreen,
'search': searchScreen,
'cart': cartScreen,
'account': accountScreen
}
let currentSlcBtn = mypageRouter['setting'];
const myPageScreen = {
after_render: async(user) =>{
let mypageIcons = document.getElementsByClassName("mypage-icons");
let mypageIconDivs = document.querySelectorAll('.mypage-aside>div');
const mypageBoard = document.getElementById('mypageBoard');
[...mypageIcons].forEach(icon => {
icon.addEventListener('click', async(e) => {
e.preventDefault();
resetTag(mypageIconDivs);
icon.parentElement.setAttribute('class','slc');
let iconName = icon.getAttribute('data-name');
currentSlcBtn = await mypageRouter[iconName];
mypageBoard.innerHTML = await currentSlcBtn.render(user);
if(mypageRouter[iconName].after_render()) await mypageRouter[iconName].after_render(user);
});
});
mypageBoard.innerHTML = await currentSlcBtn.render(user);
if(currentSlcBtn.after_render()) await currentSlcBtn.after_render(user);
},
render: async(user) => {
const userInfoDoc = doc(db, "webdoliUsers", user.uid);
const docSnap = await getDoc(userInfoDoc);
if(docSnap.exists()){
console.log('유저 정보: ', docSnap.data());
}
return `
<div id="myPageContainer">
<div class="mypage-aside"> <div id="mypage-setting" class="slc"> <svg class="mypage-icons" data-name="setting" data-src="https://s2.svgbox.net/materialui.svg?ic=settings" width="32" height="32" color="#fff"></svg> </div> <div id="mypage-myfolder"> <svg class="mypage-icons" data-name="myfolder" data-src="https://s2.svgbox.net/materialui.svg?ic=folder_open" width="32" height="32" color="#fff"></svg> </div> <div id="mypage-cgfilm"> <svg class="mypage-icons" data-name="film" data-src="https://s2.svgbox.net/materialui.svg?ic=view_in_ar" width="32" height="32" color="#fff"></svg> </div> <div id="mypage-search"> <svg class="mypage-icons" data-name="search" data-src="https://s2.svgbox.net/materialui.svg?ic=search" width="32" height="32" color="#fff"></svg> </div> <div id="mypage-cart"> <svg class="mypage-icons" data-name="cart" data-src="https://s2.svgbox.net/materialui.svg?ic=shopping_cart" width="32" height="32" color="#fff"></svg> </div> <div id="mypage-account"> <svg class="mypage-icons" data-name="account" data-src="https://s2.svgbox.net/materialui.svg?ic=credit_card" width="32" height="32" color="#fff"></svg> </div> </div> <div class="mypage-main"> <div class="mypage-main-title"> <h3>${docSnap.data().userID}님 페이지</h3> </div> <div class="mypage-main-content" id="mypageBoard"> </div> </div> </div> `
}
}
const resetTag = (ele) => {
ele.forEach(item => {
item.setAttribute('class', '');
});
return;
}
export default myPageScreen;
|
[ myPageScreen.js ]
파이어베이스 쿼리관련 메서드는 여러가지가 있으며, 각 상황에 맞는 쿼리를 사용하면 된다. 위의 경우에는 getDoc모듈과 .exists( )메서드를 조합했다. 단, 단일 데이터를 검색할 때는 .exists( )메서드보다 .empty( )가 유용할 수 있다. 쿼리 관련 정보는 아래 링크에서 확인해보자.
https://firebase.google.com/docs/firestore/query-data/get-data
https://firebase.google.com/docs/firestore/query-data/queries
3 하위 모듈
mypageScreen.js에서 요청한 하위 6개의 모듈이 필요하다. 테스트용이므로 내용보다는 연결에 중점을 뒀지만, 실제로 서비스를 공개한다면 fetch나 ajax를 통한 외부데이터를 각 모듈에 담을 수 있다.
3-1 settingScreen.js
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js';
const db = getFirestore();
const settingScreen = {
after_render: () =>{
},
render: (user) => {
return `
<div class="mypage-main-control">
<span>유저</span>
<span>uid:${user.uid} </span>
</div>
<div class="mypage-main-control">
<span>이메일</span>
<span> email: ${user.email} </span>
</div>
`
}
}
export default settingScreen;
|
[ settingScreen.js ]
이어지는 myfolderScreen.js ~ accountScreen.js까지 모두 같은 형식으로 채워준다.
3-2 myfolderScreen.js
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js'; const db = getFirestore();
const myfolderScreen = {
after_render: () =>{
},
render: async(user) => {
return `
<h3>내 폴더 Board </h3>
`
}
}
export default myfolderScreen;
|
[ myfolderScreen.js ]
3-3 filmScreen.js
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js'; const db = getFirestore();
const filmScreen = {
after_render: () =>{
},
render: async(user) => {
return `
<h3> CG제작 Board </h3>
`
}
}
export default filmScreen;
|
[ filmScreen.js ]
3-4 searchScreen.js
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js'; const db = getFirestore();
const searchScreen = {
after_render: () =>{
},
render: async(user) => {
return `
<h3> 소스찾기 Board </h3>
`
}
}
export default searchScreen;
|
[ searchScreen.js ]
3-5 cartScreen.js
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js';
const db = getFirestore();
const cartScreen = {
after_render: () =>{
},
render: async(user) => {
return `
<h3>쇼핑카트 Board </h3>
`
}
}
export default cartScreen;
|
[ cartScreen.js ]
3-6 accountScreen.js
import { collection, getDocs, getDoc, doc, getFirestore, query } from 'https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js'; const db = getFirestore();
const accountScreen = {
after_render: () =>{
},
render: async(user) => {
return `
<h3>내 계좌 Board </h3>
`
}
}
export default accountScreen;
|
[ accountScreen.js ]
4 myPage.css
메뉴에 토글 효과를 구현하기 위한 CSS를 구현한다. 티스토리 블로그에서 구현하는 상황에서는 부트스트랩, 파운데이션 같은 css라이브러리들을 배제하는 편이 좋다. 태그, 클래스명이 티스토리 css와 충돌할 수도 있기 때문이다.
#container .content-wrap{
margin-top: -350px;
}
#myPageContainer{
display: flex;
width: 680px;
}
.mypage-aside{
width: 20%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.mypage-aside > div:first-child{
margin-top: 70px;
}
.mypage-aside > div.slc{
background-color: #eda36b;
}
.mypage-aside > div{
padding: 10px 15px;
margin: 10px 0;
background-color: #48CFAD;
color: white;
cursor: pointer;
}
.mypage-aside > div:hover{
background-color: #979c9b;
}
.mypage-main{
width: 80%;
display: flex;
flex-direction: column;
}
.mypage-main-title{
border-bottom: 1px solid #979c9b;
padding: 15px 5px;
}
.mypage-main-content{
padding: 20px 5px;
background: #f3f5f7;
margin-top: 10px;
height: 100%;
}
.mypage-main-content > h3{
padding: 0 10px;
}
.mypage-main-control{
margin-bottom: 15px;
padding: 5px 10px;
}
|
[ myPage.css ]
css를 적용한 후에는 아래와 같은 '마이페이지'를 제작할 수 있다. 위의 코드를 응용한다면, 관리자 페이지도 제작할 수 있으며, 더 나아가 커뮤니티 게시판 서비스도 자체적으로 제공할 수 있다.
'웹개발 자료실 > Firebase 개발 Code' 카테고리의 다른 글
블로그 회원가입 제작 [4편. 아이디 비밀번호 찾기] (0) | 2022.01.11 |
---|---|
블로그 회원가입 제작 [2편. 회원가입 페이지] (0) | 2022.01.07 |
블로그 회원가입 제작(feat. firebase) [1편. 파이어베이스 설정 & 로그인폼 제작] (0) | 2022.01.06 |
Firebase『Auth 로그인, 비밀번호 찾기』 (1) | 2019.12.28 |
Firebase『Auth 회원가입, 이메일 인증,』 (10) | 2019.12.27 |
댓글