728x90
반응형

Front-End 와 Back-End 수업이 끝나고 진행 한 프로젝트

주제: 전기차 충전소 시스템 프로젝트

 

프로젝트 인원 : 6명

프로젝트 기간 : 2023-10-23 ~ 2023-10-30

 

구성

1. Main Page

2. Account Page

3. Categori Page

4. Admin Page

 

1. Main Page

1-1. Intro

프로젝트 페이지 주소로 들어가면 1초간 화면 인트로가 보여진다.

1-2. 멤버십 팝업

 첫 화면에 들어오면 멤버십 가입 관련 팝업이 뜬다. '혜택 자세히 알아보기'를 누르면 멤버십 가입 페이지로 이동하고 '오늘 하루 이 창을 열지 않습니다'에 체크한 뒤 닫기를 누르면 쿠키에 정보가 저장이 되어 오늘 하루 팝업 창이 뜨지 않는다.

1-3. 홈 화면

 상단에 웹 이름, 로고, 카테고리를 두었고 오른쪽에 사이드바(현재 닫힘), 중간에 피카충전소의 슬로건과 관련 이미지를 배치하였다. 뒷 배경에 번개가 치는 애니메이션 효과를 넣어 전기라는 이미지가 떠올리게 하였다.

1-4. 사이드 바

 오른쪽에 번개모양의 이모티콘을 누르면 사이드 바가 열리고 닫힌다. 로그인 전, 후에 생성되는 항목이 다르며 하위 요소가 있는 목록들은 해당 목록에 마우스를 올리면 사이드바가 하나 더 열려 하위 항목들이 나타난다.

1-5. 카테고리 바

 5개의 카테고리로 구성되어 있고, 하위 항목이 있는 카테고리일 경우 해당 카테고리에 마우스를 올리면 하위 항목들이 아래로 내려온다.

 

2. Account Page

2-1. 회원가입

 회원가입 시 이용약관 필수사항 동의, 아이디 중복확인, 이메일 본인인증을 완료해야 회원가입 버튼이 활성화 되도록 구현하였다. 자신의 차를 등록하고자 할 때 차량 회사 선택을 하면 회사에 포함 된 차종이 항목으로 뜬다.

 아래 관리자로 체크를 하고 가입을 하면 관리자 계정으로 구분되어 일반 User보다 다룰 수 있는 사항이 많아진다.

2-2. 로그인

 간단한 로그인 창으로 DB에 저장되어있는 정보로 로그인을 할 수 있다. 로그인을 할 때 정확한 이메일을 입력하지 않으면 형식이 올바르지 않다고 알림창이 뜨고 비밀번호나 아이디를 틀리면 '이메일 또는 비밀번호가 일치하지 않습니다' 라는 알림창이 뜨게 된다. 비밀번호 입력창에 자신의 비밀번호를 입력한 뒤 오른쪽에 눈 모양의 버튼을 누르면 Password처리 되어 보이지 않았던 비밀번호가 현재 자신이 무엇을 입력해 놓았는지 볼 수 있다.

2-3. 비밀번호 찾기

 로그인 창 아래의 '비밀번호가 기억나지 않는다면?'을 클릭하면 본인 인증 후 비밀번호를 새롭게 설정할 수 있. 본인인증에 실패하면 '입력하신 정보와 일치하는 사용자를 찾을 수 없습니다.' 라는 알림창이 뜨기 때문에 DB에 있는 계정만이 본인인증에 성공해서 비밀번호를 변경할 수 있다.

2-4. Mypage

 로그인 후 마이페이지 탭에 들어가면 회원탈퇴가 가능하다. (회원수정을 오류로 수정 중)

3. Categori Page

3-1. 충전소 찾기

 충전소 찾기로 들어오면 왼쪽 사이드바를 이용하여 지정한 반경 이내의 전기차 충전소 위치를 확인 할 수 있고, 카테고리별로 항목을 선택하여 전기차 위치를 볼 수 있다.

3-2. 게시판

 게시판은 공지사항, Q&A로 나뉘어져있으며 글쓰기와, 글의 수정 삭제가 가능하다. Q&A는 일반 글쓰기와, 충전소 추가요청, Car정보 추가요청이 따로 나뉘어져 있어서 각각 추가요청을 하고 글을 쓰면 추가 요청 리스트가 보이게 된다. 

3-3. 정보마당

 정보마당에는 통계정보와 서비스 안내가 있다. 통계정보에는 전기차 현황과 충전기 현황을 볼 수 있도록 나누어 놓았으며, 서비스 안내에는 충전요금, 전기차 충전방식을 볼 수 있도록 나누어 놓았다.

3-4. 미디어

 미디어는 전기차 뉴스, 전기차 영상, 전기차 주행거리, 전기차 게임으로 구성 된 하위 항목을 가지고 있다.

 

3-4-1. 전기차 뉴스

뉴스 API를 이용해 전기차 관련 뉴스를 불러와 보여주고 있으며 네이버 뉴스 링크로 이동이 가능하다.

3-4-2. 전기차 영상

 유튜브API를 이용해 전기차 관련 영상을 보여주고 있다. 카테고리를 전기차와 친환경으로 나누어 항목에 따라 다른 영상을 볼 수 있게 하였다. 

3-4-3. 전기차 주행거리

 유일하게 리액트로 구현한 페이지로 해당 페이지에 들어가면 전기차에 따른 주행거리를 알 수 있으며, 자신이 궁금한 차량을 검색해서 볼 수도 있다.

3-4-5. 전기차 게임

  전기차 게임 페이지 들어가면 왼쪽에 게임 관련 설명이 나와있고 오른쪽 미니 게임에서 키보드로 자동차를 움직여 충전소로 가면 본 게임이 시작된다. 만약 자동차가 지도의 가장자리에 닿으면 다음 지도로 전환되게 구현하였다.

 본 게임은 장애물을 피해 목적지인 주유소에 도착하면 되는 게임으로 성공시 찌리릿 코인을 지급한다. 찌리릿 코인은 하루에 1번만 받을 수 있으며 게임을 해서 한번 더 받으려고 한다면 오늘은 이미 받았다는 알림창이 뜨게 된다.

3-5. 멤버십

 멤버십은 코인교환, 쿠폰함, 구독하기로 구성되어있으며 만약 멤버십에 가입한다면 마이멤버십이라는 하위 항목이 하나 더 보이게 된다.

 

3-5-1. 코인 교환

 게임에서 얻은 코인을 쿠폰으로 교환할 수 있는 페이지이다. 코인 10개당 1개의 무료 충전 쿠폰으로 교환 되며 교환 성공 시 교환 성공 모달이 코인이 없어 교환이 실패 되면 코인이 부족하다는 모달 창이 뜨게 된다.

3-5-2. 쿠폰함

 피카충전소 웹에서 얻게 되는 쿠폰을 한번에 볼 수 있는 페이지이다. 사용기간이 나와 있으며 사용하고자 할 때는 사용하기 버튼을 눌러 사용할 수 있다. 사용하기 버튼을 누르면 쿠폰 사용하기 모달이 뜨는데 해당 모달에서 직원확인 버튼을 누르며 해당 쿠폰은 사라지게 된다.

3-5-3. 가입하기

 피카 PASS라는 멤버십에 가입 할 수 있도록 멤버십 혜택 보기와 가입하기를 구현해 놓았다. 멤버십에 가입을 한다면 로그인 했을 시 멤버십 카테고리에 마이멤버십이라는 항목이 생기는데 이곳에선 멤버십 종료 날짜를 알 수 있다. 또한 멤버십 가입 혜택인 충전소 근처 편의점, 카페, 음식점의 위치 정보와 해당 매장의 쿠폰을 발급 받을 수 있도록 하였다.

가입하기 페이지
가입하기 버튼을 누르면 뜨는 모달 창
마이멤버십 페이지

4. Admin

 회원가입 시 관리자는 관리자 계정으로 회원가입을 할 수 있다. 관리자로 로그인하게 되면 사이드바에 Admin이라는 항목이 나타나게 되는데 해당 페이지에서 user 수, 구독자 수, 고객문의 수 등을 알 수 있다. 또한 user들의  Charging Q&A, Car Q&A, 발급 된 Coupon 을 한 페이지에서 볼 수 있어 관리하기 쉽게 구현해 놓았다.

 

728x90
반응형
728x90
반응형

조건

1. "가위", "바위", "보" 중 하나를 선택하면 게임 진행

2. "Com:" 옆에 랜덤으로 선택된 결과를 출력하고 "Player:" 옆에 사용자가 선택한 결과를 출력

3.선택한 결과 밑에 게임 진행 결과를 출력

import logo from './logo.svg';
import './App.css';
import { useState } from 'react';

function Title() {
  return (
    <div className='title'>
      <h1>가위 바위 보 게임</h1>
    </div>
  );
}

function Scissors(props) {
  const { onUserChoice } = props;

  function run() {
    const choice = 'scissors';
    console.log(choice);
    onUserChoice(choice);
  }

  return (
    <div className='control'>
      <img src='http://ggoreb.com/images/react/scissors.png' onClick={run} />
    </div>
  );
}

function Rock(props) {
  const { onUserChoice } = props;

  function run() {
    const choice = 'rock';
    console.log(choice);
    onUserChoice(choice);
  }

  return (
    <div className='control'>
      <img src='http://ggoreb.com/images/react/rock.png' onClick={run}></img>
    </div>
  );
}

function Paper(props) {
  const { onUserChoice } = props;

  function run() {
    const choice = 'paper';
    console.log(choice);
    onUserChoice(choice);
  }

  return (
    <div className='control'>
      <img src='http://ggoreb.com/images/react/paper.png' onClick={run}></img>
    </div>
  );
}

function getRandomChoice() {
  const choices = ['scissors', 'rock', 'paper'];
  const randomIndex = Math.floor(Math.random() * choices.length);
  return choices[randomIndex];
}

function getResultMessage(userChoice, comChoice) {
  if (userChoice === comChoice) {
    return '비겼습니다!';
  } else if (
    (userChoice === 'scissors' && comChoice === 'paper') ||
    (userChoice === 'rock' && comChoice === 'scissors') ||
    (userChoice === 'paper' && comChoice === 'rock')
  ) {
    return '당신이 이겼습니다.';
  } else {
    return '당신이 졌습니다.';
  }
}

function Result(props) {
  const [userChoice, setUserChoice] = useState(null);
  const comChoice = getRandomChoice();
  const resultMessage = getResultMessage(props.userChoice, comChoice);

  function handleUserChoice(choice) {
    setUserChoice(choice);
  }

  return (
    <div className='result'>
      <h1>Com: {comChoice} </h1>
      <h1>Player: {props.userChoice || ''} </h1>
      <h1>{resultMessage}</h1>
    </div>
  );
}

function App() {
  const [userChoice, setUserChoice] = useState(null);

  const handleUserChoice = (choice) => {
    console.log(`User chose: ${choice}`);
    setUserChoice(choice);
  };

  return (
    <div className="App">
      <Title />
      <Scissors onUserChoice={handleUserChoice} />
      <Rock onUserChoice={handleUserChoice} />
      <Paper onUserChoice={handleUserChoice} />
      <Result userChoice={userChoice} />
    </div>
  );
}

export default App;

 

실행 결과

728x90
반응형
728x90
반응형

최대 공약수 구하기

GCD : Greatest Common Divisor

A, B 두 수 중 적은 수를 기준으로 1씩 감소시키면서

A와 B가 나누어 떨어지는 숫자

<!-- 생략 -->

<body>
    <script>
        let a = 21, b = 14;
        let c = Math.min(a, b);
        console.log(c);
        for (let i = c; i >= 1; i--) {
            if (a % i == 0 && b % i == 0) {
                console.log(`최대공약수: ${i}`);
                break;
            }
        }
    </script>
</body>

 

최소 공배수 구하기

LCD : Least Common Divisor

A, B 두 수 중 큰 수를 기준으로 1씩 증가시키면서

A와 B가 나누어 떨어지는 숫자

<!-- 생략 -->

<body>
    <script>
        let a = 21, b = 14;
        let d = Math.max(a, b);
        console.log(d);
        for (let j = d; j <= a * b; j++) {
            if (j % a == 0 && j % b == 0) {
                console.log(`최소공배수: ${j}`);
                break;
            }
        }
    </script>
</body>

 

유클리드 호제법을 재귀호출로 나타내기

유클리드 호제법은 최대 공약수, 최소 공배수를 나타내는 알고리즘

<!-- 생략 -->

<body>
    <script>
            let a = 21, b = 14;
            function gcd(a, b) {
                if (a % b == 0) {
                    return b;
                }
                return gcd(b, a % b);
            }
            console.log(gcd(a, b));
            let 최소공배수 = a * b / gcd(a, b);
            console.log(최소공배수);
    </script>
</body>
728x90
반응형
728x90
반응형

문제

 

내기 생각해 본 script

-if 조건문 사용

-각 동전의 최소 개수가 나올 뿐 동전 개수의 합이 나오진 않는다.

<!-- 생략 -->
<body>
    <script>
        let 돈 = 0;
        돈 = prompt('받은 돈을 입력하시오');
        console.log(`받은 돈 ${돈}원`)
        let 동전수 = 0;

        if (parseInt(돈 / 500) >= 1) {
            console.log(`500원 ${parseInt(돈 / 500)} 개`)
        }
        if (돈 % 500 >= 1) {
            console.log(`100원 ${parseInt((돈 % 500) / 100)} 개`)
        }
        if (돈 % 100 >= 5) {
            console.log(`50원 ${parseInt((돈 % 100) / 50)} 개`)
        }

        if (돈 % 50 >= 1) {
            console.log(`10원 ${parseInt(돈 % 50) / 10} 개`)
        }

    </script>
</body>

 

예시 script 1

-greedy 알고리즘

-거스름 돈을 미리 설정해둠(하드코딩)

-조건문 if 사용

-반복문 while 사용

-if문만 사용한다면 조건에 만족할 경우 1번으로 끝나고 반복하지 않는다. 그래서 while문을 써서 돈이 0원보다 크다면 계속 반복하고 0원이 된다면 멈추도록 한다.

<!-- 생략 -->
<body>
  <script>
        let money = 1260;
        let 동전수 = 0;

        while (money > 0) {
            if (money >= 500) {
                동전수 = 동전수 + 1;
                money -= 500;
            } else if (money >= 100) {
                동전수 = 동전수 + 1;
                money -= 100;
            } else if (money >= 50) {
                동전수 = 동전수 + 1;
                money -= 50;
            } else if (money >= 10) {
                동전수 = 동전수 + 1;
                money -= 10;
            }
        }
        console.log(동전수);
  </script>
</body>

예시 script2

<!-- 생략 -->
<body>
    <script>

        let money = 1260;
        let 동전수 = 0;

        while (money > 0) {
            if (money >= 500) {
                동전수 += parseInt(money / 500);
                money = money % 500;
            } else if (money >= 100) {
                동전수 += parseInt(money / 100);
                money = money % 100;
            } else if (money >= 50) {
                동전수 += parseInt(money / 50);
                money = money % 50;
            }
            else if (money >= 10) {
                동전수 += parseInt(money / 10);
                money = money % 10;
            }
        }

        console.log(동전수);
    </script>
</body>

예시 script3

<!-- 생략 -->
<body>
    <script>
        let money = 1260;
        let 동전수 = 0;

        let 동전종류 = [500, 100, 50, 10];
        let count = 0;
        while (count < 4) {
            let 동전 = 동전종류[count];
            count++;
            동전수 += parseInt(money / 동전);
            money %= 동전;
        }
        console.log(동전수);
    </script>
</body>
728x90
반응형

+ Recent posts