티스토리 뷰

검색 API를 뚫어서 프론트에 검색창도 만들고 검색 페이지도 만들어서 프론트와 연동을 하려고 했다.

 

검색 페이지의 코드는

import React, { ReactNode, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Box, Container, Flex, SimpleGrid, Input, Button, IconButton, useColorModeValue, background } from "@chakra-ui/react";
import { SearchIcon } from "@chakra-ui/icons"
import axios from "axios";
import ClassCard from "../../components/ClassCard";
import SectionTitle from "../../components/SectionTitle";
import ContentArea from "../../components/ContentArea";

// 강의 정보에 대한 타입 정의
type CourseInfo = {
  title: string;
  description: string;
  classId: number;
  thumbnailPath: string;
};

const ClassCardList = ({ children }: { children: ReactNode }) => (
  <SimpleGrid
    columns={{ base: 1, sm: 2, md: 3 }}
    spacing={5}
    gridAutoRows={"1fr"}
    borderColor={"none"}
  >
    {children}
  </SimpleGrid>
);

function SearchPage() {
  const navigate = useNavigate();
  // 최고의 결과를 저장할 상태
  const [bestResults, setBestResults] = useState<CourseInfo[]>([]);
  // 최신의 결과를 저장할 상태
  const [newResults, setNewResults] = useState<CourseInfo[]>([]);
  // 검색 결과를 저장할 상태
  const [keyword, setKeyword] = useState("");
  const [searchResults, setSearchResults] = useState<CourseInfo[]>([]);

  // 페이지 로드 시 최고의 결과와 최신의 결과를 가져오는 useEffect
  useEffect(() => {
    handleBest();
    handleNew();
  }, []); // 페이지가 로드될 때 한 번만 실행
// 서버에서 최고의 결과를 가져오는 함수
const handleBest = () => {
  axios.get('http://localhost:8080/course/best')
  .then((response) => {
    setBestResults(response.data.data); // 최고의 결과를 state에 저장
  })
  .catch((error) => {
    console.error('Error fetching best results', error);
  });
};

// 서버에서 최신의 결과를 가져오는 함수
const handleNew = () => {
  axios.get('http://localhost:8080/course/new')
  .then((response) => {
    setNewResults(response.data.data); // 최신의 결과를 state에 저장
  })
  .catch((error) => {
    console.error('Error fetching new results', error);
  });
};

  const handleSearch = () => {
    axios.get('http://localhost:8080/course/search', {
      params: {
        keyword: keyword
      }
    })
    .then((response) => {
      setSearchResults(response.data);
    })
    .catch((error) => {
      console.error('Error fetching search results', error);
    });
  };

  return (
    <>
      <ContentArea>
        <Flex
          flexDirection={"column"}
          className={"content-wrapper"}
          p={4}
          width={"100%"}
          gap={4}
        >
          <Box mx="auto" width="50%">
            <Flex align="center" justify="center">
              <input
                type="text"
                placeholder="검색어를 입력하세요"
                value={keyword}
                onChange={(event) => setKeyword(event.target.value)}
                onKeyPress={(event) => {
                  if (event.key === "Enter") {
                    handleSearch();
                  }
                }}
                style={{ padding: "8px", fontSize: "16px", borderRadius: "999px", width: "100%", paddingLeft: "20px" }}
                />
                <Button 
                  onClick={handleSearch}
                  borderRadius="full"
                  bgColor={useColorModeValue("gray.200", "gray.700")}
                  _hover={{ bgColor: useColorModeValue("gray.300", "gray.600")}}
                  ml={2}
                >
                  <SearchIcon />
                 </Button>
              </Flex>
          </Box>
          <Box>
            <SectionTitle title={"BEST"} />
            <ClassCardList>
              {bestResults.map((item, idx) => (
                <ClassCard
                  key={idx}
                  title={item.title}
                  desc={item.description}
                  onClick={() => navigate(`/class/${item.classId}`)}
                  imgSrc={item.thumbnailPath}
                />
              ))}
            </ClassCardList>
          </Box>
          
          <Box>
            <SectionTitle title={"New"} />
            <ClassCardList>
              {newResults.map((item, idx) => (
                <ClassCard
                  key={idx}
                  title={item.title}
                  desc={item.description}
                  onClick={() => navigate(`/class/${item.classId}`)}
                  imgSrc={item.thumbnailPath}
                />
              ))}
            </ClassCardList>
          </Box>
          
        </Flex>
      </ContentArea>
    </>
  );
}


export default SearchPage;

 

내가 검색에서 가져오려는 건 강의 제목, 강의 태그, 강사 이름 이렇게 3개를 가져오려고 하는데

 

기존에 이미 CourseInfo 타입에는 이것이 아닌 다른 것이 들어가있다. 그래서 요청을 보내면 인텔리제이(스프링)에서는 보이는데

 

프론트로 값이 리턴이 되지 않는 것 같다.

 

우선은 지금까지 상황은 이러하고 프론트를 잘 아는 친구에게 조언을 구했더니

 

CourseSearchInfo를 새로 가져오고 백에서 검색은 강의 제목, 강의 태그, 강사 이름 이걸로 검색하는 쿼리를 작성하고

 

CourseSearchInfo에는 기존 CourseInfo에다가 강의 태그, 강사 이름을 추가해서 카드 리스트를 보여주라고 한다.

(강의 제목은 CourseInfo에 이미 존재)

 

그리고 프론트에서 조건문을 이용해서 결과를 검색했을 때 검색 페이지에 보여지는 Best, New를 사라지게 하고 검색 결과를 나타나게 하면 된다고 한다.

 

결국!!

 

1. 우선 백에서 3가지 분류를 이용하여 쿼리를 작성한다.

2. 가져올 때는 CourseSearchInfo에 맞게 가져와야한다. -> 그래야 카드 리스트가 보일 것이다.

3. 프론트에서 조건문을 사용하여 검색을 했을 떄 보여지게 하면 된다.

4. 그 후 디테일한 작업을 하자!!

 

이렇게 순서가 된다. 지금부터 이렇게 하나씩 해결해보자!! 파이팅!!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함