스파르타 코딩클럽 - 리액트 4주차(4)

SeungMai(junior)·2021년 8월 4일
0

1. Quiz_버킷리스트 좀 더 예쁘게!

  • App.js
import React from "react";

import { withRouter } from "react-router";
import { Route, Switch } from "react-router-dom";

import BucketList from "./BucketList";
import styled from "styled-components";
import Detail from "./Detail";
import NotFound from "./NotFound";

import {connect} from 'react-redux';
import {loadBucket, createBucket} from './redux/modules/bucket';
import Progress from "./Progress";

const mapStateTopProps = (state) => ({
  bucket_list: state.bucket.list,
});

const mapDispatchToProps = (dispatch) => ({
  load: () => {
    dispatch(loadBucket());
  },
  create: (new_item) => {
    console.log(new_item);
    dispatch(createBucket(new_item));
  }
});

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
     
    };
    this.text = React.createRef();
  }

  componentDidMount() {
  }

  addBucketList = () => {
    const new_item = { text: this.text.current.value, compeleted: false};
    this.props.create(new_item);
  };

  render() {
    return (
      <div className="App">
        <Container>
          <Title>내 버킷리스트</Title>
          <Progress/>
          <Line />
          <Switch>
            <Route path="/" exact component={BucketList} />
            <Route path="/detail/:index" component={Detail} />
            <Route component={NotFound} />
          </Switch>
        </Container>
        <Input>
          <input type="text" ref={this.text} />
          <button onClick={this.addBucketList}>추가하기</button>
        </Input>

        <button onClick={() => {
          window.scrollTo({ top: 0, left: 0, behavior: "smooth" });
        }}>위로가기</button>
      </div>
    );
  }
}

const Input = styled.div`
  max-width: 350px;
  min-height: 10vh;
  background-color: #fff;
  padding: 16px;
  margin: 20px auto;
  border-radius: 5px;
  border: 1px solid #ddd;
  display: flex;
  align-items: center;
  justify-content: space-between;
  & > * {
    padding: 5px;
  }

  & input {
    border-radius: 5px;
    margin-right: 10px;
    border: 1px solid #888;
    width: 70%;
    &:focus {
      border: 1px solid #a673ff;
    }
  }

  & button {
    width: 25%;
    color: #fff;
    border: 1px solid #a673ff;
    border-radius: 5px;
    background-color: #a673ff;
  }
`;


const Container = styled.div`
  max-width: 350px;
  min-height: 60vh;
  background-color: #fff;
  padding: 16px;
  margin: 20px auto;
  border-radius: 5px;
  border: 1px solid #ddd;
`;

const Title = styled.h1`
  color: #673ab7;
  text-align: center;
`;

const Line = styled.hr`
  margin: 16px 0px;
  border: 1px dotted #ddd;
`;

export default connect(mapStateTopProps, mapDispatchToProps)(withRouter(App));
  • BucketList.js
import React from "react";
import styled from "styled-components";

import {useDispatch, useSelector} from 'react-redux';

const BucketList = (props) => {
  const bucket_list = useSelector(state => state.bucket.list);
  
  return (
    <ListStyle>
      {bucket_list.map((list, index) => {
        return (
          <ItemStyle
            className="list_item"
            key={index}
            completed = {list.completed}
            onClick={() => {
              props.history.push("/detail/" + index);
            }}
          >
            {list.text}
          </ItemStyle>
        );
      })}
    </ListStyle>
  );
};

const ListStyle = styled.div`
  display: flex;
  flex-direction: column;
  height: 50vh;
  overflow-x: hidden;
  overflow-y: auto;
  max-height: 50vh;
`;

const ItemStyle = styled.div`
  padding: 16px;
  margin: 8px;
  font-weight: 600;
  color: ${(props) => (props.completed ? "#fff" : "#212121")};
  background-color: ${props => props.completed ? "#673ab7" : "#eee"};
  box-sizing: border-box;
`;

export default BucketList;
  • Progress.js
import React from "react";
import styled from "styled-components";

import { useDispatch, useSelector } from "react-redux";

import { deleteBucket, updateBucket } from "./redux/modules/bucket";

const Progress = (props) => {
  const bucket_list = useSelector((state) => state.bucket.list);
  
  let count = 0;

  let goal_per = bucket_list.map((l, idx) => {
    if(l.completed){
        count++;
    }
  });

  return (
    <ProgressBar>
      <HighLight width={(count / bucket_list.length) * 100 + "%"}></HighLight>
      <Dot/>
    </ProgressBar>
  );
};

const ProgressBar = styled.div`
  background: #eee;
  width: 100%;
  height: 20px;
  display: flex;
  border-radius: 10px;
  align-items: center;
`;

const HighLight = styled.div`
  background: #673ab7;
  width: ${(props) => props.width};
  height: 20px;
  border-radius: 10px;
  transition: 2s;
`;

const Dot = styled.div`
  background: #fff;
  border: 5px solid #673ab7;
  box-sizing: border-box;
  margin: 0px 0px 0px -10px;
  width: 40px;
  height: 40px;
  border-radius: 20px;
`;
export default Progress;
profile
👍🏻 SeungMai (매 순간 기록을!)🧑🏻‍💻 | WIL만 올리고 있습니다 | 기술블로그는 아래 🏠 의 링크를 이용해주세요.

0개의 댓글