본문 바로가기
개발/Node JS

Node js, React 파일 관리 시스템 만들기 (8)

by 피로물든딸기 2021. 7. 15.
반응형

프로젝트 전체 링크

 

이전 - (7) Local Storage로 현재 version 기억하기

현재 - (8) 각 version별 country 폴더 불러오기

다음 - (9) csv 파일 목록 불러오기

 

깃허브에서 코드 확인하기


node로 불러온 폴더는 각 ver 폴더이다.

각 ver 폴더에는 국가 폴더가 있고, 국가 폴더 아래에는 관리해야 할 (불러와야 할 csv) 파일이 있다.

2020 폴더 아래의 국가와 파일

이제 MyToggles에 국가까지 보이도록 toggle을 추가하자.


App.js에 country 정보를 기억할 수 있도록 useState로 선언한 후, MyToggles에 넘겨준다.

//App.js

const App = () => {
  const [csvObject, setCsvObject] = useState(csvObjectDefault);
  const [version, setVersion] = useState("");
  const [country, setCountry] = useState("");

  return (
    <div>
      <MyToggles
        version={version}
        setVersion={setVersion}
        country={country}
        setCountry={setCountry}
      />
      
      ...

 

MyToggles에는 country : props, local storage, countList를 추가한다.

//MyToggles.js

const MyToggles = ({ version, setVersion, country, setCountry }) => {
  const LOCAL_STORAGE = {
    LS_VERSION: setVersion,
    LS_COUNTRY: setCountry,
  };

  const [versionList, setVersionList] = useState([]);
  const [countryList, setCountryList] = useState([]);
  
  ...

 

makeVersion을 참고해서 makeCountry를 만든다.

//MyToggles.js

const makeCountry = () => {
  if (countryList.length === 0) return;

  return countryList.map((con, idx) => (
    <div
      key={idx}
      className={con === country ? "btn-child selected-country" : "btn-child"}
      onClick={(e) => onClickToggles(e.target.innerText, setCountry, 'LS_COUNTRY')}
    >
      {con}
    </div>
  ));
};

 

사실 이 코드는 makeVersion과 많은 중복을 일으킨다. 따라서 하나로 통합한다.

//MyToggles.js

const makeToggles = (toggleList, value, selected, setState, lsKey) => {
  if (toggleList.length === 0) return;

  return toggleList.map((tog, idx) => (
    <div
      key={idx}
      className={tog === value ? `btn-child ${selected}` : "btn-child"}
      onClick={(e) => onClickToggles(e.target.innerText, setState, lsKey)}
    >
      {tog}
    </div>
  ));
}

 

MyToggles의 return 부분은 아래처럼 바뀐다.

//MyToggles.js

return (
  <div>
    <div className="btn-set">
      {makeToggles(
        versionList,
        version,
        "selected",
        setVersion,
        "LS_VERSION"
      )}
    </div>
    <div className="btn-set">
      {makeToggles(
        countryList,
        country,
        "selected-country",
        setCountry,
        "LS_COUNTRY"
      )}
    </div>
  </div>
);

country toggle button의 색은 selected-country로 설정하였다. scss는 최종 코드를 참고하자.

 

version 정보는 init에서 실행하였으나, country 정보는 version이 변경될 때 마다 변경되어야 한다.

따라서 useEffect에 version이 변경되면 country list를 가져온다.

//MyToggles.js

const getCountryList = () => {
  if (version === "" || version === undefined) return;

  let path = `${mnode.PATH}/${version}`;
  mnode.getFolderList(setCountryList, path);
};
  
useEffect(getCountryList, [version]);

 

init의 getVersionList(library.js)는 폴더를 가져온다. getCountryList도 결국 폴더를 가져온다.

따라서 path를 넘겨주는 식으로 변경한다.

//nodelibrary.js

export const getFolderList = (setState, path) => {
    fetch(`${MY_SERVER}/getFileFolderList?path=${path}`)
    .then((response) => response.json())
    .then((data) => setState(data.folderList.map(list => list.name)));
}

 

makeToggles에서 사용한 것 처럼, init도 아래와 같이 변경하면 된다.

//MyToggles.js

const init = () => {
  let path = `${mnode.PATH}`;
  mnode.getFolderList(setVersionList, path);
  
  ...

 

이름을 변경하였기 때문에 혹시나 MyOptions를 사용하고 싶다면, MyOptions의 init도 수정해야 한다.

const init = () => {
  let path = `${mnode.PATH}`;
  mnode.getFolderList(setVersionList, path);
};

 

이제 country 목록도 불러오게 되었다.

2023년은 빈 폴더이므로 어떤 list도 가져오지 않는다.

 

최종 코드는 아래와 같다.

 

React 

//App.js
import React, { useState } from "react";

import FileUpload from "./components/FileUpload";
import MyTable from "./components/MyTable";
import MyToggles from "./components/MyToggles";
import * as mnode from "./components/nodelibrary";

const csvObjectDefault = {
  HEIGHT: 0,
  WIDTH: 0,
  csv: [],
};

const nodeTest = () => {
  mnode.getFileFolderList(mnode.PATH, "csv");
  return;
}

const App = () => {
  const [csvObject, setCsvObject] = useState(csvObjectDefault);
  const [version, setVersion] = useState("");
  const [country, setCountry] = useState("");

  return (
    <div>
      <MyToggles
        version={version}
        setVersion={setVersion}
        country={country}
        setCountry={setCountry}
      />
      
      <button onClick={nodeTest}>서버 연결</button>
      <button onClick={() => console.log(csvObject)}>print csv</button>
      <div className="App">
        <FileUpload setCsvObject={setCsvObject} />
        <MyTable csvFile={csvObject}/>
      </div>
    </div>
  );
};

export default App;

 

//MyToggles.js
import React, { useState, useEffect } from "react";
import * as mnode from "./nodelibrary";
import "../css/MyToggles.scss";

const MyToggles = ({ version, setVersion, country, setCountry }) => {
  const LOCAL_STORAGE = {
    LS_VERSION: setVersion,
    LS_COUNTRY: setCountry,
  };

  const [versionList, setVersionList] = useState([]);
  const [countryList, setCountryList] = useState([]);

  const onClickToggles = (value, setState, lsKey) => {
    setState(value);
    if (lsKey) localStorage.setItem(lsKey, value);
  };

  const makeToggles = (toggleList, value, selected, setState, lsKey) => {
    if (toggleList.length === 0) return;

    return toggleList.map((tog, idx) => (
      <div
        key={idx}
        className={tog === value ? `btn-child ${selected}` : "btn-child"}
        onClick={(e) => onClickToggles(e.target.innerText, setState, lsKey)}
      >
        {tog}
      </div>
    ));
  };

  const getCountryList = () => {
    if (version === "" || version === undefined) return;

    let path = `${mnode.PATH}/${version}`;
    mnode.getFolderList(setCountryList, path);
  };

  const init = () => {
    let path = `${mnode.PATH}`;
    mnode.getFolderList(setVersionList, path);

    for (let key in LOCAL_STORAGE) {
      let data = localStorage.getItem(key);
      if (data !== null) onClickToggles(data, LOCAL_STORAGE[key], key);
    }
  };

  useEffect(init, []);
  useEffect(getCountryList, [version]);

  return (
    <div>
      <div className="btn-set">
        {makeToggles(
          versionList,
          version,
          "selected",
          setVersion,
          "LS_VERSION"
        )}
      </div>
      <div className="btn-set">
        {makeToggles(
          countryList,
          country,
          "selected-country",
          setCountry,
          "LS_COUNTRY"
        )}
      </div>
    </div>
  );
};

export default MyToggles;

 

//nodelibrary.js

const MY_SERVER = `http://192.168.55.120:3002`;
export const PATH = `C:\\Users\\username\\Downloads\\TESTFILES`;

export const getFileFolderList = (path, fileExtension) => {
    fetch(`${MY_SERVER}/getFileFolderList?path=${path}&fileExtension=${fileExtension}`)
    .then((response) => response.json())
    .then((data) => console.log(data));
}

export const getFolderList = (setState, path) => {
    fetch(`${MY_SERVER}/getFileFolderList?path=${path}`)
    .then((response) => response.json())
    .then((data) => setState(data.folderList.map(list => list.name)));
}

 

MyToggles.scss에는 seleted-country를 초록색이 되도록 추가하였다.

//MyToggles.scss

@mixin btn-style($color) {
    border-color: $color;;
    background-color: $color;
}

.btn-set {
    margin-top: 3px;
    .btn-child {
      margin-left: 1px;
      cursor: pointer;
      display: inline-block;
      font-weight: 400;
      color: #6c757d;
      text-align: center;
      vertical-align: middle;
      -webkit-user-select: none;
      -ms-user-select: none;
      user-select: none;
      background-color: transparent;
      border: 1px solid transparent;
      padding: .375rem .75rem;
      font-size: 1rem;
      line-height: 1.5;
      border-radius: .25rem;
      transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
      border-color: #6c757d;
      
      &:hover {
        font-weight: bolder;
        border-color: black;
      }
    }
  
    .selected {
      color: #fff;
      @include btn-style(rgb(255, 65, 97));
    }

    .selected-country {
        color: #fff;
        @include btn-style(#28a745); 
    }
  }

이전 - (7) Local Storage로 현재 version 기억하기

다음 - (9) csv 파일 목록 불러오기

반응형

댓글