본문 바로가기
과제기록

[페어] statesairline-client

by 뭉지야 2023. 2. 3.
728x90

Search.js

import { useState } from 'react';

function Search({onSearch}) { 
  const [textDestination, setTextDestination] = useState('');

  const handleChange = (e) => {
    setTextDestination(e.target.value.toUpperCase());
  };

  const handleKeyPress = (e) => {
    if (e.type === 'keypress' && e.code === 'Enter') {
      handleSearchClick();
    }
  };

  const handleSearchClick = () => {
    console.log('검색 버튼을 누르거나, 엔터를 치면 search 함수가 실행됩니다');

    // TODO: 지시에 따라 상위 컴포넌트에서 props를 받아서 실행시켜 보세요.
    onSearch( {departure: 'ICN', destination: textDestination}) 
  };                                                           

  return (
    <fieldset>
      <legend>공항 코드를 입력하고, 검색하세요</legend>
      <span>출발지</span>
      <input id="input-departure" type="text" disabled value="ICN"></input>
      <span>도착지</span>
      <input
        id="input-destination"
        type="text"
        value={textDestination}
        onChange={handleChange}
        placeholder="CJU, BKK, PUS 중 하나를 입력하세요"
        onKeyPress={handleKeyPress}
      />
      <button id="search-btn" onClick={handleSearchClick}>
        검색
      </button>
    </fieldset>
  );
}

export default Search;
/* 의사코드 포함*/
import { useState } from 'react';

function Search({onSearch}) { 
//search가 onsearch라는 이름으로 하위 컴포넌트에 전달이 된다.
  const [textDestination, setTextDestination] = useState('');

  const handleChange = (e) => {
    setTextDestination(e.target.value.toUpperCase());
  };

  const handleKeyPress = (e) => {
    if (e.type === 'keypress' && e.code === 'Enter') {
      handleSearchClick();
    }
  };

  const handleSearchClick = () => {
    console.log('검색 버튼을 누르거나, 엔터를 치면 search 함수가 실행됩니다');

    // TODO: 지시에 따라 상위 컴포넌트에서 props를 받아서 실행시켜 보세요.
    onSearch( {departure: 'ICN', destination: textDestination}) 
    //버튼이 클릭되면 onSearch의 값이 Search함수에게 전달되어 실행된다.
  };                                                           

  return (
    <fieldset>
      <legend>공항 코드를 입력하고, 검색하세요</legend>
      <span>출발지</span>
      <input id="input-departure" type="text" disabled value="ICN"></input>
      <span>도착지</span>
      <input
        id="input-destination"
        type="text"
        value={textDestination}
        onChange={handleChange}
        placeholder="CJU, BKK, PUS 중 하나를 입력하세요"
        onKeyPress={handleKeyPress}
      />
      <button id="search-btn" onClick={handleSearchClick}>
        검색
      </button>
    </fieldset>
  );
}

export default Search;

Main.js

import Head from 'next/head';
import { useEffect, useState } from 'react';
import { getFlight } from '../api/FlightDataApi';
import FlightList from './component/FlightList';
import LoadingIndicator from './component/LoadingIndicator';
import Search from './component/Search';
import Debug from './component/Debug';


export default function Main() {
  const [condition, setCondition] = useState({
    departure: 'ICN',
  });
  const [flightList, setFlightList] = useState([]);
  const [isLoading, setIsLoading] = useState(false); 

  const search = ({ departure, destination }) => {  
    if (
      condition.departure !== departure ||
      condition.destination !== destination
    ) {
      console.log('condition 상태를 변경시킵니다');

      // TODO: search 함수가 전달 받아온 '항공편 검색 조건' 인자를 condition 상태에 적절하게 담아보세요.
      setCondition({departure, destination})  
    }
  };

  const filterByCondition = (flight) => {
    let pass = true;
  if (condition.departure) {  
      pass = pass && flight.departure === condition.departure;
    }
    if (condition.destination) {
      pass = pass && flight.destination === condition.destination;
    }
    return pass;
  };

  global.search = search; // 실행에는 전혀 지장이 없지만, 테스트를 위해 필요한 코드입니다. 이 코드는 지우지 마세요!

  // TODO: Effeck Hook을 이용해 AJAX 요청을 보내보세요.
  // TODO: 더불어, 네트워크 요청이 진행됨을 보여주는 로딩 컴포넌트(<LoadingIndicator/>)를 제공해보세요.
  

   useEffect(() => {   
    setIsLoading(true);  
    getFlight(condition) 
    .then(data => {         
      setFlightList(data) 
      setIsLoading(false);   
    })
   }, [condition])   

  // TODO: 테스트 케이스의 지시에 따라 search 함수를 Search 컴포넌트로 내려주세요.
  return (
    <div>
      <Head>
        <title>States Airline</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1>여행가고 싶을 땐, States Airline</h1>
        <Search onSearch={search}/>
        <div className="table">
            <div className="row-header">
            <div className="col">출발</div>
            <div className="col">도착</div>
            <div className="col">출발 시각</div>
            <div className="col">도착 시각</div>
            <div className="col"></div>
          </div>
          {isLoading ? <LoadingIndicator /> : <FlightList list ={flightList}/>}
        </div>

        <div className="debug-area">
          <Debug condition={condition} />
        </div>
        <img id="logo" alt="logo" src="codestates-logo.png" />
      </main>
    </div>
  );
}
/* 의사코드포함 */
import Head from 'next/head';
import { useEffect, useState } from 'react';
import { getFlight } from '../api/FlightDataApi';
import FlightList from './component/FlightList';
import LoadingIndicator from './component/LoadingIndicator';
import Search from './component/Search';
import Debug from './component/Debug';


export default function Main() {
  // 항공편 검색 조건을 담고 있는 상태
  const [condition, setCondition] = useState({
    departure: 'ICN',
  });
  const [flightList, setFlightList] = useState([]);
  const [isLoading, setIsLoading] = useState(false); //로딩상태

  // 주어진 검색 키워드에 따라 condition 상태를 변경시켜주는 함수
  const search = ({ departure, destination }) => {  
  //여기의 출발지 목적지는 setCondition으로 적용된다.
    if (
      condition.departure !== departure ||
      condition.destination !== destination
    ) {
      console.log('condition 상태를 변경시킵니다');

      // TODO: search 함수가 전달 받아온 '항공편 검색 조건' 인자를 condition 상태에 적절하게 담아보세요.
      setCondition({departure, destination})  
      //search함수가 전달받은 departure, destination을 setcondition에 적용한다.
    }
  };

  const filterByCondition = (flight) => {
    let pass = true;
  if (condition.departure) {   //flight과 condition의 출발지와 목적지가 같은걸 빼오라는 의미이다.
      pass = pass && flight.departure === condition.departure;
    }
    if (condition.destination) {
      pass = pass && flight.destination === condition.destination;
    }
    return pass;
  };

  global.search = search; // 실행에는 전혀 지장이 없지만, 테스트를 위해 필요한 코드입니다. 이 코드는 지우지 마세요!

  // TODO: Effeck Hook을 이용해 AJAX 요청을 보내보세요.
  // TODO: 더불어, 네트워크 요청이 진행됨을 보여주는 로딩 컴포넌트(<LoadingIndicator/>)를 제공해보세요.
  

   useEffect(() => {   //condition이 변할때만 실행된다.
    setIsLoading(true);  
    getFlight(condition)  //getFlight에서 condition객체로 필터링을 진행하여 데이터를 추출한다.(출발지, 목적지)
    .then(data => {         //그 데이터를 이용해 FlightList와 IsLoading을 변경한다.
      setFlightList(data) 
      setIsLoading(false);   //loadingindicator종료되고 flightlist 뜬다.
    })
   }, [condition])    //condition이 변할때만 앞의 내용들이 실행된다.

  // TODO: 테스트 케이스의 지시에 따라 search 함수를 Search 컴포넌트로 내려주세요.
  return (
    <div>
      <Head>
        <title>States Airline</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1>여행가고 싶을 땐, States Airline</h1>
        <Search onSearch={search}/>
        <div className="table">
            <div className="row-header">
            <div className="col">출발</div>
            <div className="col">도착</div>
            <div className="col">출발 시각</div>
            <div className="col">도착 시각</div>
            <div className="col"></div>
          </div>
          {isLoading ? <LoadingIndicator /> : <FlightList list ={flightList}/>}
         //로딩중이면 loadingindicator이고 로딩중이아니면 flightlist의 list가 뜬다
        </div>

        <div className="debug-area">
          <Debug condition={condition} />
        </div>
        <img id="logo" alt="logo" src="codestates-logo.png" />
      </main>
    </div>
  );
}

FlightDataApi.js

import flightList from '../resource/flightList';
import fetch from 'node-fetch';

if (typeof window !== 'undefined') { 
  localStorage.setItem('flight', JSON.stringify(flightList));
}

export function getFlight(filterBy = {}) {
  // HINT: 가장 마지막 테스트를 통과하기 위해, fetch를 이용합니다. 아래 구현은 완전히 삭제되어도 상관없습니다.
  // TODO: 아래 구현을 REST API 호출로 대체하세요.

 /* let json = [];
  if (typeof window !== 'undefined') {
    json = localStorage.getItem('flight');
  }
  const flight = JSON.parse(json) || [];

  return new Promise((resolve) => {
    const filtered = flight.filter((flight) => {
      let condition = true;
      if (filterBy.departure) {
        condition = condition && flight.departure === filterBy.departure;
      }
      if (filterBy.destination) {
        condition = condition && flight.destination === filterBy.destination;
      }
      return condition;
    });

    setTimeout(() => {
      resolve(filtered);
    }, 500);
  });
  */
 let result = ''
  if(filterBy.departure){
    result =  `departure=${filterBy.departure}&`; 
  }
  if(filterBy.destination){
    result =  result + `destination=${filterBy.destination}`;  
  }

  let URL = `http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?${result}`  //필터링된 값이 담긴 result를 명시한 url

  return fetch(URL)  
  .then((res) => res.json());   
}
/* 의사코드포함 */
import flightList from '../resource/flightList';
import fetch from 'node-fetch';

if (typeof window !== 'undefined') { //브라우저가 정상적으로 렌더링이 되었을때, (그래야 localstorage를 쓸수있다)
  localStorage.setItem('flight', JSON.stringify(flightList));
}// 로컬스토리지에 flight이라는 프로퍼티명으로 JSON.stringify(flightList)저장해줘

export function getFlight(filterBy = {}) {
  // HINT: 가장 마지막 테스트를 통과하기 위해, fetch를 이용합니다. 아래 구현은 완전히 삭제되어도 상관없습니다.
  // TODO: 아래 구현을 REST API 호출로 대체하세요.

 /* let json = [];
  if (typeof window !== 'undefined') {
    //로컬스토리지에 있는 'flight'프로퍼티안에 있는 값을 가져오겠다.
    json = localStorage.getItem('flight');
  }
  const flight = JSON.parse(json) || [];

  return new Promise((resolve) => {
    const filtered = flight.filter((flight) => {
      let condition = true;
      if (filterBy.departure) {
        condition = condition && flight.departure === filterBy.departure;
      }
      if (filterBy.destination) {
        condition = condition && flight.destination === filterBy.destination;
      }
      return condition;
    });

    setTimeout(() => {
      resolve(filtered);
    }, 500);
  });
  */
 let result = ''
  if(filterBy.departure){
    result =  `departure=${filterBy.departure}&`; //result에 필터링된 departure를 저장.
  }
  if(filterBy.destination){
    result =  result + `destination=${filterBy.destination}`;  //result에 필터링된 destination을 저장.
  }

  let URL = `http://ec2-13-124-90-231.ap-northeast-2.compute.amazonaws.com:81/flight?${result}`  //필터링된 값이 담긴 result를 명시한 url

  return fetch(URL)   //그 url을 서버에 요청한다.
  .then((res) => res.json());   // 데이터를 json화시킨다.
 }
728x90

'과제기록' 카테고리의 다른 글

[페어]statesairline-server  (0) 2023.02.08
[페어] beesbeesbees  (0) 2023.01.28
[project] 나만의 아고라스테이츠만들기  (0) 2023.01.10