[React] 여러 조건별로 검색하는 검색창 구현하기

Hyoyoung Kim·2023년 4월 4일
1


😎 여러조건별로 검색하는 검색창 구현 코드

/* eslint-disable */
import * as S from './style';
import { useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { Pagination } from '../../often/pagination';
import { useDateFormat } from '../../common/hooks/useDateFormat';
import { useMoney } from '../../common/hooks/useMoney';
import axios from 'axios';
import { Cookies } from 'react-cookie';
import Swal from 'sweetalert2';
import withReactContent from 'sweetalert2-react-content';
import '../../../css/alert.css';

const swal = withReactContent(Swal);

export const AdminOrderList = (props: any) => {
  const { registDate, registDate2 } = useDateFormat();
  const { MoneyNumber } = useMoney();

  const navigate = useNavigate();
  const moveQnApw = (item: any) => {
    if (cookies.get('refreshToken')) {
      navigate('/admin-order-de', {
        state: {
          data: item,
        },
      });
    } else {
      navigate('/sign-in');
      cookies.remove('accessToken');
      cookies.remove('refreshToken');
      cookies.remove('loginUser');

    }

  };

  const [itemList, setItemList] = useState([]);
  const [sort] = useState(`sort=date,desc`);
  // 페이지 숫자
  const [page, setPage] = useState(0);
  // 전체 페이지 확인(전체 페이지 수만큼 페이지네이션 숫자 늘리기)
  const [totalPages, setTotalPages] = useState(0);
  const [size] = useState(7);
  const cookies = new Cookies();
  const jwt = cookies.get('accessToken');

  //페이지 네이션
  const [currentPage, setCurrentPage] = useState(page + 1);
  const [itemsPerPage] = useState(size);

  const [pageNumberLimit] = useState(5);
  const [maxPageNumberLimit, setMaxPageNumberLimit] = useState(5);
  const [minPageNumberLimit, setMinPageNumberLimit] = useState(0);

  // 검색시작날짜
  const [startDay, setStartDay] = useState('' as any);
  // 검색종료날짜
  const [finishDay, setFinishDay] = useState('' as any);

  //결제상태
  const [payStatus, setPayStatus] = useState('');

  // 배송상태
  const [deliStatus, setDeliStatus] = useState('');

  //상품명 입력
  const [keyWord, setKeyWord] = useState('');

  const [searchText, setSearchText] = useState('');
  //검색리스트 길이
  const [listLength, setListLength] = useState(0);

  useEffect(() => {
    const getData = async () => {
      try {
        await axios({
          method: 'get',
// 서버에 보내줘야 하는 Query String
          url: `${process.env.REACT_APP_API_URL}/admin/order/list?
sort=${sort}&page=${page}&size=${size}&fromDate=${finishDay}
&toDate=${startDay}&keyword=${keyWord}&deliveryStatus=${deliStatus}
&paymentStats=${payStatus}`,
          headers: {
            Authorization: jwt,
          },
        }).then((res) => {
          setItemList(res.data.orders);
          setTotalPages(res.data.total_elements);
          setListLength(res.data.total_elements);
        });
      } catch (err: any) {
        navigate('/sign-in');
        cookies.remove('accessToken');
        cookies.remove('refreshToken');
        cookies.remove('loginUser');

      }

    };
    getData();
  }, [jwt, size, sort, page, startDay, finishDay, keyWord, deliStatus, payStatus, navigate]);

  const dataList2 = (data: any) => {
    return (
      <S.DataList>
        {listLength !== 0 ? (
          data.map((el: any, index: any) => {
            return (
              <S.Container key={index} onClick={() => moveQnApw(el.id)}>
                <div>{el.id}</div>
                {el.order_item_count === 1 ? (
                  <div>{el.order_item.name}</div>
                ) : (
                  <div>
                    {el.order_item.name}{el.order_item_count - 1}</div>
                )}
                <div>{MoneyNumber(el.price)}</div>
                <div>
                  {el.payment.status === 'PAID'
                    ? '결제완료'
                    : el.payment.status === 'READY'
                      ? '결제대기'
                      : el.payment.status === 'CANCEL'
                        ? '결제취소'
                        : '결제실패'}
                </div>

                <div>
                  {el.delivery.status === 'COMPLETE'
                    ? '배송완료'
                    : el.delivery.status === 'IN_DELIVERY'
                      ? '배송 중'
                      : el.delivery.status === 'PREPARATION'
                        ? '배송 준비'
                        : '배송취소'}
                </div>
                <div>{registDate(el.date)}</div>
                <div>
                  {el.member.name}/{el.delivery.receiver}
                </div>
              </S.Container>
            );
          })
        ) : (
          <S.NoSearchItem>검색 결과가 없습니다.</S.NoSearchItem>
        )}
      </S.DataList>
    );
  };
  //오늘
  const Now = () => {
    const date = new Date();
    setStartDay(registDate2(date));
    setFinishDay(registDate2(date));
  };

  //1주일 전
  const OneWeek = () => {
    const now = new Date();
    setStartDay(registDate2(now));
    const date = new Date(now.setDate(now.getDate() - 7));
    setFinishDay(registDate2(date));
  };

  // 3개월 전
  const ThreeMonth = () => {
    const now = new Date();
    setStartDay(registDate2(now));
    const date = new Date(now.setMonth(now.getMonth() - 3));
    setFinishDay(registDate2(date));
  };

  //6개월전
  const SixMonth = () => {
    const now = new Date();
    setStartDay(registDate2(now));
    const date = new Date(now.setMonth(now.getMonth() - 6));
    setFinishDay(registDate2(date));
  };

// 검색창
  const onChangeText = (e: any) => {
    setSearchText(e.target.value);
  };

// 검색창에 엔터 쳤을때 검색되게 하는 함수
  const onKeyDownEnter = (e: any) => {
    if (e.key === 'Enter') {
      search();
      e.target.blur();
    }
  };


  const search = () => {
    setKeyWord(searchText);
  };

  return (
    <S.Wrapper>
      <S.SearchBox>
        <S.SearchSecon>
          <S.DayButton onClick={Now}>오늘</S.DayButton>
          <S.DayButton onClick={OneWeek}>1주일</S.DayButton>
          <S.DayButton onClick={ThreeMonth}>3개월</S.DayButton>
          <S.DayButton onClick={SixMonth}>6개월</S.DayButton>
          <S.SearchThird>
            <S.DayInput
              type='date'
              value={finishDay}
              onChange={(e: any) => {
                setFinishDay(e.target.value);
              }}
            />
            <S.Tilde>~</S.Tilde>
            <S.DayInput
              type='date'
              value={startDay}
              onChange={(e: any) => {
                setStartDay(e.target.value);
              }}
            />
          </S.SearchThird>
        </S.SearchSecon>
        <S.SearchFive>
          <S.SearchH2>상품명</S.SearchH2>
          <S.SearchInput
            type='text'
            name='search-form'
            id='search-form'
            placeholder='Search for...'
            onClick={searchClick}
            onChange={(e: any) => onChangeText(e)}
            onKeyDown={(e: any) => onKeyDownEnter(e)}
            autoComplete='off'
          />
          <S.DeliSelect value={payStatus} onChange={(e: any) => setPayStatus(e.target.value)}>
            <option value=''>결제상태</option>
            <option value='PAID'>결제완료</option>
            <option value='READY'>결제대기</option>
            <option value='CANCEL'>결제취소</option>
            <option value='FAILED'>결제실패</option>
          </S.DeliSelect>
          <S.DeliSelect value={deliStatus} onChange={(e: any) => setDeliStatus(e.target.value)}>
            <option value=''>배송상태</option>
            <option value='PREPARATION'>배송준비</option>
            <option value='IN_DELIVERY'>배송중</option>
            <option value='COMPLETE'>배송완료</option>
            <option value='CANCEL'>배송취소</option>
          </S.DeliSelect>
          <S.SearchButton onClick={() => search()}>검색</S.SearchButton>
        </S.SearchFive>
      </S.SearchBox>
      <div>
        <S.BigTitle>상품 리스트</S.BigTitle>
      </div>
      <S.AdminOrdertitle>
        <div>상품번호</div>
        <div>상품명</div>
        <div>결제금액</div>
        <div>결제상태</div>
        <div>배송상태</div>
        <div>
          <div>처리일자</div>
          <div>(결제일자기준)</div>
        </div>
        <div>주문자/수령인</div>
      </S.AdminOrdertitle>
      {dataList2(itemList)}
      <Pagination
        data={itemList}
        totalPages={totalPages}
        page={page}
        setPage={setPage}
        currentPage={currentPage}
        setCurrentPage={setCurrentPage}
        itemsPerPage={itemsPerPage}
        pageNumberLimit={pageNumberLimit}
        maxPageNumberLimit={maxPageNumberLimit}
        setMaxPageNumberLimit={setMaxPageNumberLimit}
        minPageNumberLimit={minPageNumberLimit}
        setMinPageNumberLimit={setMinPageNumberLimit}
      />
    </S.Wrapper>
  );
};

styled- component

import styled from 'styled-components';

export const Wrapper = styled.div`
  /* width: 144rem; */
  display: flex;
  width: 100%;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
`;

export const BigTitle = styled.div`
  font-size: 0.24rem;
  width: 12.8rem;
  font-weight: 700;
  margin-left: 0.22rem;
`;

export const DataList = styled.ul`
  margin-bottom: 0.24rem;
`;

export const AdminOrdertitle = styled.div`
  width: 12.8rem;
  margin-top: 0.24rem;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  flex-wrap: wrap;
  background-color: ${({ theme }) => theme.palette.whitegreen};
  align-items: end;
  padding: 0.17rem 0.15rem 0.17rem 0.32rem;
  align-items: center;
  border-top: 0.03rem solid ${({ theme }) => theme.palette.txtgray};
  font-size: 0.24rem;
  div {
    &:nth-child(1) {
      flex-grow: 1.3;
    }
    &:nth-child(2) {
      flex-grow: 1.8;
    }
    &:nth-child(3) {
      flex-grow: 1.2;
    }
    &:nth-child(4) {
      flex-grow: 0.8;
    }
    &:nth-child(5) {
      flex-grow: 2;
    }
    &:nth-child(6) {
      flex-grow: 3;
      div {
        &:last-child {
          font-size: 0.15rem;
        }
      }
    }
    &:nth-child(7) {
      flex-grow: 0;
    }
  }
`;
export const Container = styled.div`
  cursor: pointer;
  width: 12.8rem;
  display: flex;
  align-items: center;
  padding: 0.24rem 0.15rem 0.24rem 0.58rem;
  border-bottom: 0.01rem solid ${({ theme }) => theme.palette.lightgray};
  font-size: 0.24rem;
  div {
    &:nth-child(1) {
      width: 0.7rem;
      text-align: left;
    }
    &:nth-child(2) {
      width: 2rem;
      text-align: center;
    }
    &:nth-child(3) {
      width: 1.8rem;
      text-align: center;
    }
    &:nth-child(4) {
      width: 1.3rem;
      text-align: center;
    }
    &:nth-child(5) {
      width: 1.3rem;

      text-align: center;
    }
    &:nth-child(6) {
      width: 2.8rem;
      text-align: center;
    }
    &:nth-child(7) {
      width: 2.3rem;
      text-align: right;
    }
  }
`;

// 검색 박스

export const SearchBox = styled.div`
  background-color: ${({ theme }) => theme.palette.lightgray};
  width: 12.8rem;
  height: 1.52rem;
  padding: 0.24rem;
  margin-bottom: 0.4rem;
  margin-top: 0.82rem;
`;

export const DayButton = styled.button`
  width: 0.92rem;
  height: 0.4rem;
  border: 0.01rem solid ${({ theme }) => theme.palette.txtgray};
  background-color: white;
  font-size: 0.2rem;
  margin-right: 0.08rem;
`;

export const SearchSecon = styled.div`
  display: flex;
`;

export const SearchThird = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
`;

export const DayInput = styled.input`
  width: 2.36rem;
  height: 0.4rem;
  font-size: 0.2rem;
  margin-left: 0.08rem;
  padding-left: 0.05rem;
  border: 0.01rem solid ${({ theme }) => theme.palette.lightgreen};
  ::-webkit-calendar-picker-indicator {
    opacity: 1;
    display: block;
    background: url('/img/calendar.png') center/100% no-repeat white;
    width: 18%;
    height: 100%;
    cursor: pointer;
  }
`;

export const Tilde = styled.div`
  font-size: 0.2rem;
  margin-left: 0.16rem;
  margin-right: 0.08rem;
`;

export const SearchFive = styled.div`
  display: flex;
  align-items: center;
  margin-top: 0.16rem;
`;

export const SearchH2 = styled.h2`
  font-size: 0.24rem;
  margin-right: 0.28rem;
`;

export const SearchInput = styled.input`
  width: 4.65rem;
  height: 0.48rem;
  border: 0.01rem solid ${({ theme }) => theme.palette.txtgray};
  margin-right: 0.16rem;
  padding-left: 0.08rem;
  font-size: 0.2rem;
`;

export const DeliSelect = styled.select`
  width: 1.84rem;
  height: 0.48rem;
  border: 0.01rem solid ${({ theme }) => theme.palette.txtgray};
  font-size: 0.2rem;
  margin-right: 0.08rem;
  padding-left: 0.22rem;
`;

export const SearchButton = styled.button`
  width: 1.12rem;
  height: 0.48rem;
  background-color: ${({ theme }) => theme.palette.green};
  font-size: 0.2rem;
  color: white;
`;

export const NoSearchItem = styled.div`
  ${({ theme }) => theme.common.flexCenter};
  width: 12.8rem;
  height: 3rem;
  border-bottom: 0.02rem solid ${({ theme }) => theme.palette.green};
  font-size: 0.24rem;
  font-weight: 500;
`;

0개의 댓글