본문 바로가기

project/insightLINK

[나만무] 검색 기능

728x90

[나만무] 검색 기능

 

Front 

쿼리 전달

 

features/Dashboard/components/SearchBar.tsx

import React, { useState, KeyboardEvent } from "react";
import { useRouter } from "next/router";

export default function SearchBar() {
 ...
 
  const [keywords, setKeywords] = useState("");
  const onKeyPress = (e: KeyboardEvent) => {
    if (e.key == "Enter") {
      e.preventDefault();
      router.push({
        pathname: '/search',
        query: {search : keywords.replace(/[^ㄱ-ㅎ가-힣a-zA-Z0-9]/g, " ")}
      });
      setKeywords("");
      setSearchBar(false);
    }
  };
  
  
    return (
    <>
		...
        <input
          ref={inputRef}
          type="text"
          className="w-full h-10 font-medium bg-transparent outline-none ring-none"
          value={keywords}
          placeholder="검색"
          onChange={(e) => {
            setKeywords(e.target.value);
          }}
          onBlur={() => setSearchBar(false)}
          onKeyPress={onKeyPress}
        />
		...
    </>
  );
}

 

next로 페이지 전환하면서 query 전달

      router.push({
        pathname: '/search',
        query: {search : keywords.replace(/[^ㄱ-ㅎ가-힣a-zA-Z0-9]/g, " ")}
      });

 

pages/search.tsx

import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import axios from "axios";
// Component
import NavBar from "../features/Dashboard/components/NavBar";
import { Wrapper } from "@/styles/wrapper";
import SearchResult from "@/features/Search/ContentSearch";
// Assets
import { GrFormNext } from "react-icons/gr";

interface ResponseData {
  hasNext: boolean;
  results: {
    cardTags: string[];
    cardKeyword: string;
    cardContent: string;
  }[];
}

export default function Search() {
  const router = useRouter();

  const keywords = router.query.search;

  const [contentsData, setContentsData] = useState<ResponseData | null>(null);
  const [tagsData, setTagsData] = useState<ResponseData | null>(null);
  const [contentsAllData, setContensAllData] = useState<ResponseData | null>(
    null
  );
  const [tagsAllData, setTagsAllData] = useState<ResponseData | null>(null);

  useEffect(() => {
    const contentsData = async () => {
      try {
        const response = await axios.get(
          "http://localhost:8800/dashboard/contents",
          {
            params: {
              search: keywords,
            },
          }
        );
        setContentsData(response.data);
      } catch (error) {
        console.error(error); // Handle any errors that occurred during the request
      }
    };

    if (keywords) {
      contentsData();
    }
  }, [keywords]);



  return (
		...
          {contentsData?.results[0] ? (
            <SearchResult data={contentsData?.results} />
          ) : (
            <div>검색 결과가 없습니다.</div>
          )}
 		....
  );
}

Back 데이터 가공

 

routes/search.js

import express from 'express';
import '../dotenv.js';
import { db } from '../connect.js';
import { searchContent , searchTag} from '../db/searchQueries.js';

const router = express.Router();

router.get('/contents', async (req, res) => {
    // console.log(req.query);
    const { search } = req.query;

    let connection = null;

    try {
        connection = await db.getConnection();
        const [ result ] = await connection.query(searchContent(search));

        let arr = [];
        for (let i = 0; i < result.length / 2; i++) {
          arr.push({
            cardTags: [result[i * 2].tag, result[i + 1].tag],
            cardKeyword: "# 1",
            cardContent: result[i * 2].content,
          });
        }
        // console.log(arr[0]);

        return res.send({results: [arr[0]]});
    } catch(err) {
        connection?.release();
        console.log(err);
        res.status(500).send('Internal Server Error');
    }
});

 

db/searchQueries.js

export const searchContent = (keyword) => { 
    return `SELECT f.file_id, f.content, t.tag  
            FROM File f
            JOIN FileTag ft ON f.file_id = ft.file_id
            JOIN Tag t ON ft.tag_id = t.tag_id
            WHERE f.content LIKE '%${keyword}%'
            ORDER BY f.updated_at ASC;`;
  };


반복되는 코드가 많고 기능이 원할하게 흘러가려면 좀더 디벨롭해야할듯하다.

일단 유저 모달창 만들고! 해당 코드 수정할 예정!