til

최종 프로젝트 11일 차 @zustand, tailwind 설정

fpzmfks 2024. 11. 1. 23:50

오늘은 어제 완성한 기능들을 zustand를 이용하여  헤더에 올리고 css작업을 시작했다. 또한 font와 테마컬러를 설정하기 위해 tailwind.config.ts 파일을 설정했다. 

 

zustand

오늘 zustand를 하면서 next.js 과정에 들어오고 나서 처음으로 간단한 zustand 설정을 해보았다. 전에 zustand를 간단하게도 사용할 수 있다는 얘기를 듣기는 했는데, 정말 엄청 간단해서 놀랐다. 아래의 첫번째가 간단한 zustand가 두번째가 어제 만진 복잡한 zustand이다. 이 둘의 차이가 무엇인지, 또 복잡한 설정에서의 이점이 구체적으로 무엇인지(이점이 명확하지 않으면 굳이 복잡한 설정을 디폴트로 두지 않았을 테니까) 알아보아야겠다. 

 

// 간단한 zustand 설정

import { create } from 'zustand';

type RecruitState = {
  partySituation: string;

  setPartySituation: (info: string) => void;
};

export const useWatchFilter = create<RecruitState>((set) => ({
  partySituation: '',

  setPartySituation: (info) => set(() => ({ partySituation: info }))
}));

 

// 복잡한 zustand 설정

// zustand 설정
export type textProp = { searchText: string };
export type searchStore = textProp & { changeSearchWord: (text: string) => void };

const DEFAULT_PROPS: textProp = { searchText: '' };
export const createSearchStateStore = (initState: textProp = DEFAULT_PROPS) => {
  return createStore<searchStore>()((set) => ({
    ...initState,
    changeSearchWord: (text: string) => set(() => ({ searchText: text }))
  }));
};

// zustand Provider
export type searchStoreAPI = ReturnType<typeof createSearchStateStore>;
export const SearchContext = createContext<searchStoreAPI | undefined>(undefined);

export type searchProviderProps = { children: ReactNode };
export const SearchProvider = ({ children }: searchProviderProps) => {
  const storeRef = useRef<searchStoreAPI>();
  if (!storeRef.current) {
    storeRef.current = createSearchStateStore();
  }
  return <SearchContext.Provider value={storeRef.current}> {children} </SearchContext.Provider>;
};

export const useSearchStore = <T,>(selector: (store: searchStore) => T): T => {
  const storeContext = useContext(SearchContext);
  if (!storeContext) throw new Error('Missing CartContext.Provider in the tree');
  return useStore(storeContext, selector);
};

 

tailwind

오늘은 주말 동안의 css 작업에 앞서서 tailwind 설정을 하기도 했다. 디자이너님의 조언에 따라 먼저 font와 테마 컬러를 먼저 설정했는데, 테마 컬러 설정은 문제가 없었지만 font 설정에서 약간 이슈가 있었다. 아무래도 글꼴 같은 것들은 크게 다른 부분이 있지 않는다면 알아보기가 쉽지 않기 때문에 설정이 완료된 건지 안 된건지 알아보기가 쉽지 않았던 것이다. 하지만 논리적 오류를 발견해서 font 설정이 제대로 되지 않았다는 것을 발견할 수 있었다. 

 

아래가 최종 수정한 global.css의 폰트 설정부분이다. 폰트 설정과 폰트 사용으로 이루어져 있다. 

// 폰트 설정
@font-face {
  font-family: 'Pretendard';
  src: url('fonts/PretendardVariable.woff2');
}

// 폰트 사용
* {
  font-family: 'Pretendard';
}

 

위와 같이 설정하기 이전에는 아래와 같이 설정되어 있었는데, 폰트를 어디선가 import 해온 것도 아닌데 그냥 폰트를 사용하기만 하고 있는 모습이다. 이렇게 설정을 해서는 다른 곳에서 font를 설정했다고 해도 폰트가 사용될 리가 없다. 하지만 개발자 도구 창에서는 Pretendard라는 폰트가 적용되지 않았는데도 적용되고 있다고 표기되기 때문에 알아보기가 힘들었다. 

// 폰트 사용
* {
  font-family: 'Pretendard';
}

 

해야할 것

앞으로 주말 동안에는 내가 맡은 부분 css를 작업하고, 월요일에 최종 머지를 해야한다. 내가 맡은 부분은 파티페이지와 참가하기 모달, 메인페이지(배너 제외)와 헤더이다. 

 

또한 오늘로써 필수기능 구현을 전부 마치기는 했지만 미처 고려하지 못한 세세한 부분들이 있을 수 있으니 그 부분들을 수정해야 한다. 일단 내가 파악한 바로는 메인페이지에서 로그아웃 했을 경우 MyParty 리스트가 그대로 노출되어 있는 것(로그아웃에 invalidation을 줘야하나?)이나 마이프로필과 구분되는 파티멤버프로필의 스토리지 이미지를 삭제할 수 있도록 해야겠다. 

 

그리고 디자인을 다시금 확인하니, 디자이너님이 생각한 초대하기 기능과 내가 구현한 초대하기 기능이 약간 다르게 작동하는 것을 확인했다. 나는 각 팔로우한 사람 정보마다 버튼을 누르면 초대할 수 있도록 했는데, 디자이너님은 팔로우한 사람을 선택해서 초대장을 보낼 수 있도록 구안한 것이었다. 이 또한 반영해서 중간 최종본이 나오도록 해야겠다.