Skip to content

Commit

Permalink
수정사항 반영(쉼표 엔터 태그 생성, 윈도우 탑, api 연동, 각종 오류 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
sehyun0518 committed Feb 17, 2024
1 parent 08b6cf5 commit 3eaddbd
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 48 deletions.
33 changes: 29 additions & 4 deletions src/components/SearchPage/SearchComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import Container from '@/styles/SearchComponent';
import useBoolean from '@/hooks/useBoolean';
import useIndex from '@/hooks/useIndex';
import CloseIcon from '@/assets/icons/close-btn.svg?react'
import SearchIcon from '@/assets/icons/search.svg?react';
import { createSearchParams, useNavigate } from 'react-router-dom';

const placeholder = '검색하고 싶은 키워드를 입력해주세요'

interface BaseTagInputProps {
Expand All @@ -27,7 +30,7 @@ const SearchComponent : React.FC<TagInputProps> = ({tags, input, searchType, sel
const [hoverdIndex, setHoveredIndex, setLeaveIndex] = useIndex(null);
const [hoverBtnIndex, setHoverBtnIndex, setLeaveBtnIndex] = useIndex(null);
const [tagIndex, setRemovingTagIndex, setNullTagIndex] = useIndex(null);

const searchNav = useNavigate();
useEffect(() => {
if (tags.length > 3) {
const lastValue = tags[3]
Expand All @@ -45,16 +48,20 @@ const SearchComponent : React.FC<TagInputProps> = ({tags, input, searchType, sel
}, [tags, setTags]);

const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
if (event.code === 'Enter'){
handleSearch();
}
if(!searchType){
if (event.key === 'Enter' && !isComposing) {

if ((event.code === 'Comma' || event.code === 'Space') && !isComposing) {
event.preventDefault();
if (input) {
tags.length > 0 && !input.startsWith('#') ? setTags([...tags, '#' + input]) : setTags([...tags, input])
if(selectedHashtags && setSelectedHashtags && !selectedHashtags.includes(input))
input.startsWith('#') ? setSelectedHashtags([...selectedHashtags, input.substring(1)]) : setSelectedHashtags([...selectedHashtags, input])
setInput('');
}
} else if (event.key === 'Backspace' && !input) {
} else if ((event.key === 'Backspace' || event.code === 'Backspace') && !input) {
if(tags.length > 0){
const lastValue = tags[tags.length - 1]
if(selectedHashtags && setSelectedHashtags && selectedHashtags.includes(lastValue.substring(1)))
Expand Down Expand Up @@ -90,8 +97,23 @@ const SearchComponent : React.FC<TagInputProps> = ({tags, input, searchType, sel
}, 500)
}


const handleSearch = () => {
const params = {
type : searchType === true ? 'keyword' : 'hashtag',
value: searchType ? input : tags.join('&')
};

searchNav({
pathname : '/search/result',
search : `?${createSearchParams(params)}`
})
window.scrollTo(0, 0);
}

return (
<div style={{display : 'flex', flexDirection : 'row'}}>
<div className='input' style={{width : '770px', height : '36px'}}>
<SearchIcon width={36} height={36}/>
<Container className="tag-container" style={{width : '700px', height : '36px'}}>
{tags.map((tag : string, index : number) => (
<span className={`tag ${hoverdIndex === index ? 'hovered' : ''} ${ (index >= 3 || index === tagIndex) ? 'exceed' : ''}`} key={index} onMouseEnter={() => setHoverBtnIndex(index)} onMouseLeave={setLeaveBtnIndex}>
Expand All @@ -110,6 +132,9 @@ const SearchComponent : React.FC<TagInputProps> = ({tags, input, searchType, sel
onChange={(e) => handleOnchage(e)}
/>
</Container>
</div>
<button className='search-btn' onClick={handleSearch} disabled={(input.length === 0 && tags.length === 0)} style={{width : '90px', height : '36px'}}>Search</button>
</div>
);
};

Expand Down
8 changes: 7 additions & 1 deletion src/components/SearchPage/SearchNotFound.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import SearchNotFoundIcon from '@/assets/icons/search-notfound.svg?react';
import styled from '@/styles/SearchResult';
import { useNavigate } from 'react-router-dom';

type NotFoundprop = {
input : string
}

const SearchNotFound : React.FC<NotFoundprop> = ( {input} ) => {
const navigate = useNavigate();

const handleBtn = () => {
navigate('/');
}
return (
<styled.SearchNotFoundContainer>
<SearchNotFoundIcon width={156} height={156}/>
<div className='text'> <span className='user'>{input}</span>에 대한 검색 결과가 없어요</div>
<button>더 많은 영상 변환하기</button>
<button onClick={handleBtn}>더 많은 영상 변환하기</button>
</styled.SearchNotFoundContainer>
);
}
Expand Down
55 changes: 34 additions & 21 deletions src/pages/SearchPage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import { Container, HashtagBox } from '@/styles/SearchPage';
import TooltipImg from '@/assets/icons/tooltip.svg?react';
import SearchIcon from '@/assets/icons/search.svg?react';

import { useState } from 'react';
import { Tooltip } from '@/components/common';
import { useEffect, useState } from 'react';
import TagInput from '@/components/SearchPage/SearchComponent';
import { useNavigate, createSearchParams } from 'react-router-dom';
import { tagAPI } from '@/apis/search';

const SearchPage = () => {
const [tags, setTags] = useState<string[]>([]);
const [input, setInput] = useState<string>('');
const [searchType, setSearchType] = useState(true); // True : keyword | False : hashTag
const userHashTag = ["기획", "광고", "마케팅", "트렌드", "기업", "광고", "마케팅", "트렌드", "기업", "광고"]; // 사용자의 해시태그 데이터 10개 <임의 데이터>
const [userHashTag, setUserHashTag] = useState<string[]>([]);
const [selectedHashtags, setSelectedHashtags] = useState<string[]>([]);
const searchNav = useNavigate();

useEffect(() => {
const handleTagAPI = async () => {
try {
const {data} = (await tagAPI());
const extraData = data.result.map((item) => {
return item.name;
});
const shuffleData = sortShuffle(extraData).slice(0, 10);
setUserHashTag(shuffleData);
} catch(e) {
setUserHashTag(['A','B','C','D','E','F','G','H','I','J']);
}
}
handleTagAPI();
}, []);

const handleHashtagBox = (value : string) => {
const isSelected = selectedHashtags.includes(value);
Expand All @@ -23,17 +36,9 @@ const SearchPage = () => {
setSearchType(false); // 박스를 클릭했을 때도 type 변경
}

const handleSearch = () => {
const params = {
type : searchType === true ? 'keyword' : 'hashtag',
value: searchType ? input : tags.join('&')
};

searchNav({
pathname : '/search/result',
search : `?${createSearchParams(params)}`
})
}
const sortShuffle = (arr : string[]) => {
return arr.sort(() => Math.random() - 0.5);
}

return (
<Container style={{width : '100vw', height : '100vh'}}>
Expand All @@ -48,16 +53,24 @@ const SearchPage = () => {
<div className='inputwrap' style={{width : '908px', height : '72px'}}>
<div className='input-inner' style={{width : '861px', height : '36px'}}>
<div className='input' style={{width : '770px', height : '36px'}}>
<SearchIcon width={36} height={36}/>
<TagInput tags={tags} input={input} searchType={searchType} selectedHashtags={selectedHashtags}
setTags={setTags} setInput={setInput} setSearchType={setSearchType} setSelectedHashtags={setSelectedHashtags}/>
</div>
<button className='search-btn' onClick={handleSearch} disabled={(input.length === 0 && tags.length === 0)} style={{width : '90px', height : '36px'}}>Search</button>
</div>
</div>

</div>
{(input.length === 0 && tags.length === 0)? <TooltipImg/> : ''}
{(input.length === 0 && tags.length === 0) ? (
<Tooltip direction='up'>
<>
1. 키워드 검색 : 키워드를 검색하면 해당 키워드가 언급 된 영상들을 찾아드려요!
<br/>
2. 해시태그 검색 : #을 함께 검색하면 해당 해시태그가 있는 영상들을 찾아드려요!
</>
</Tooltip>
)
: ''
}
</div>

<div className="hashtag" style={{width : '572px', height : '102px'}}>
Expand Down
27 changes: 6 additions & 21 deletions src/pages/SearchResultPage.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { escapeHTML } from "@/utils/string";
import { useState, useEffect} from "react";
import { createSearchParams, useLocation } from "react-router-dom";
import { useLocation } from "react-router-dom";
import Styled from "@/styles/SearchResult";
import TagInput from "@/components/SearchPage/SearchComponent";
import SearchNotFound from "@/components/SearchPage/SearchNotFound";
import SearchIcon from '@/assets/icons/search.svg?react';
import { IVideo } from "@/models/search";
import { searchAPI } from "@/apis/search";
import { useNavigate } from "react-router-dom";

import SearchResultBox from "@/components/SearchPage/SearchResultBox";

Expand All @@ -19,8 +18,6 @@ const SearchResult = () => {
const [errormsg, setErrormsg] = useState('');
const [data, setData] = useState<IVideo[]>([]);
const location = useLocation();
const searchNav = useNavigate();


useEffect(() => {
const searchParams = new URLSearchParams(location.search);
Expand All @@ -41,13 +38,13 @@ const SearchResult = () => {
break;
case 'hashtag':
const tagValues = searchParams.get('value') as string;
const tagtype = searchParams.get('type') as string

setTags(tagValues.split('&'))
const tagtype = searchParams.get('type') as string;
setTags(tagValues.replace(/\ /g, '').split('&'))
setSearchType(false);
handleSearchAPI(tagValues, tagtype, '&');
if(data.length === 0){
setErrormsg(tagValues.replace('&', ' '))
const changeSpace = tagValues.replace(/\&/g, ' ');
setErrormsg(changeSpace)
}
break;

Expand Down Expand Up @@ -109,18 +106,7 @@ const SearchResult = () => {
});
mappingData;
}
const handleReSearch = () => {
const params = {
type : searchType === true ? 'keyword' : 'hashtag',
value: searchType ? input : tags.join('&')
};

searchNav({
pathname : '/search/result',
search : `?${createSearchParams(params)}`
})
window.location.reload();
}


if(loading){
return (
Expand All @@ -140,7 +126,6 @@ const SearchResult = () => {
<TagInput tags={tags} input={input} searchType={searchType}
setTags={setTags} setInput={setInput} setSearchType={setSearchType}/>
</div>
<button className='search-btn' style={{width : '90px', height : '36px'}} disabled={(input.length === 0 && tags.length === 0)} onClick={handleReSearch}>Search</button>
</div>
</div>
</div>
Expand Down
5 changes: 5 additions & 0 deletions src/styles/SearchPage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from "styled-components";
import theme from "./theme";

const Container = styled.div`
display : flex;
Expand Down Expand Up @@ -98,6 +99,10 @@ const Container = styled.div`
border-radius: 8px;
order : 1;
border : 0;
&:hover {
background-color : ${theme.color.green500};
color : ${theme.color.gray500};
}
}
& button:disabled {
Expand Down
12 changes: 11 additions & 1 deletion src/styles/SearchResult.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from "styled-components";
import theme from "./theme";

const Container = styled.div`
display : flex;
Expand Down Expand Up @@ -45,7 +46,7 @@ const Container = styled.div`
& div.input {
display : flex;
gap : 20px;
gap : 10px;
}
& input::placeholder {
Expand All @@ -66,6 +67,10 @@ const Container = styled.div`
border-radius: 8px;
order : 1;
border : 0;
&:hover {
background-color : ${theme.color.green500};
color : ${theme.color.gray500};
}
}
& button:disabled {
Expand Down Expand Up @@ -273,9 +278,14 @@ const SearchNotFoundContainer = styled.div`
& div.text {
${(props) => props.theme.typography.Header3};
display : flex;
flex-direction : column;
justify-content: center;
align-items: center;
}
& span.user {
color : ${(props) => props.theme.color.gray300};
text-align : center;
}
& button {
Expand Down

0 comments on commit 3eaddbd

Please sign in to comment.