Skip to content

Commit

Permalink
feat: 구독하기 검색 드롭다운 박스 기능
Browse files Browse the repository at this point in the history
  • Loading branch information
thewoowon committed Jun 23, 2024
1 parent 10588bb commit 96c8a8a
Show file tree
Hide file tree
Showing 8 changed files with 362 additions and 21 deletions.
12 changes: 10 additions & 2 deletions components/bottomSheet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
JobForm,
SkillForm,
} from "components/feed/feed-filter/feed-filter-only-input";
import { useSearchParams } from "next/navigation";
import { usePathname, useSearchParams } from "next/navigation";
import { useEffect, useMemo, useState, useTransition } from "react";
import { toast } from "react-toastify";
import { getJobTags, getSkillTags } from "services/feed/queries";
import { CompanySize } from "services/feed/types";
import { switchCompanySize } from "services/feed/utils";
import { subscriptionAction } from "./actions";
import Image from "next/image";
import { companyMap } from "constants/company";

type FormFieldValues = {
email: string;
Expand All @@ -40,6 +41,7 @@ const BottomSheet = () => {
const [modal, setModal] = useState(false);
// 파라미터 가져오기
const searchParams = useSearchParams();
const pathname = usePathname();
const params = useMemo(() => {
return new URLSearchParams(searchParams);
}, [searchParams]);
Expand Down Expand Up @@ -97,7 +99,9 @@ const BottomSheet = () => {
preferredCompanySizeArr: form.searchCompanySize.map((size) =>
switchCompanySize(size as CompanySize)
),
preferredCompanyArr: [],
preferredCompanyArr: form.searchCompanyName.map(
(name) => companyMap[name]
),
preferredJobArr: form.searchJobIds,
preferredSkillArr: form.searchSkillIds,
});
Expand All @@ -123,6 +127,10 @@ const BottomSheet = () => {
});
};

console.log(pathname);

if (pathname !== "/") return null;

return (
<div className="z-[99] w-full flex justify-center fixed bottom-0">
<div className="relative w-full max-w-screen-laptop px-[15px] pt-[15px] bg-[#26272b] z-[99] rounded-tr-[20px] rounded-tl-[20px]">
Expand Down
235 changes: 217 additions & 18 deletions components/feed/feed-filter/feed-filter-only-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
import Badge from "components/badge";
import Input from "components/input";
import FilterIcon from "icons/filter-icon.svg";
import { useEffect, useRef, useState, type PropsWithChildren } from "react";
import {
useCallback,
useEffect,
useState,
type PropsWithChildren,
} from "react";
import type { CompanySize } from "services/feed/types";
import styled from "@emotion/styled";
import { toast } from "react-toastify";
import { companyList } from "constants/company";
import { debounce } from "lodash";

const MAX_COMPANY_COUNT = 3;

Expand All @@ -22,7 +29,12 @@ export const CompanyNameForm = ({
setSearchCompanyName,
}: CompanyNameProps) => {
const [value, setValue] = useState<string>("");

const [list, setList] = useState<
{
companyName: string;
id: number;
}[]
>([]);
const handleRemoveHashtag = (hashtagToRemove: string) => {
const filteredList = searchCompanyName.filter(
(hashtag) => hashtag !== hashtagToRemove
Expand All @@ -33,20 +45,127 @@ export const CompanyNameForm = ({
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
event.stopPropagation();
setValue(event.target.value);

setList(
companyList.filter((company) =>
company.companyName.includes(event.target.value)
)
);
};

const debouncedHandleInput = useCallback(
debounce((event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter" && value !== "") {
if (searchCompanyName.length >= MAX_COMPANY_COUNT) {
toast.error(`최대 ${MAX_COMPANY_COUNT}개까지 등록 가능합니다.`);
return;
}
// companyList에 있는 기업명이 아닌 경우
if (!companyList.find((company) => company.companyName === value)) {
toast.error("존재하지 않는 기업명입니다.");
setValue("");
return;
}
if (!searchCompanyName.find((hashtag) => hashtag === value)) {
setSearchCompanyName([...searchCompanyName, value]);
}
setValue("");
}

// 방향키 아래로 눌렀을 때
// if (event.key === "ArrowDown" && list.length > 0) {
// const firstLi = document.getElementById("company-list-item-0");
// // 첫 번째 li 태그에 focus를 줌
// if (firstLi) {
// firstLi.setAttribute("tabindex", "0");
// firstLi.focus();
// }
// }
}, 200),
[value]
);

const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
event.stopPropagation();
if (event.key === "Enter" && value !== "") {
if (searchCompanyName.length >= MAX_COMPANY_COUNT) {
toast.error(`최대 ${MAX_COMPANY_COUNT}개까지 등록 가능합니다.`);
return;
debouncedHandleInput(event);
};

const debounceHandleListKeyDown = useCallback(
debounce((key, currentTarget, searchCompanyName) => {
if (key === "Enter") {
if (searchCompanyName.length >= MAX_COMPANY_COUNT) {
toast.error(`최대 ${MAX_COMPANY_COUNT}개까지 등록 가능합니다.`);
return;
}
// companyList에 있는 기업명이 아닌 경우
if (
!companyList.find(
(company) => company.companyName === currentTarget.textContent
)
) {
toast.error("존재하지 않는 기업명입니다.");
setValue("");
return;
}
if (
!searchCompanyName.find(
(hashtag: string) => hashtag === currentTarget.textContent
)
) {
setSearchCompanyName([
...searchCompanyName,
currentTarget.textContent,
]);
}
setValue("");
}
// 방향키 위로 눌렀을 때
if (key === "ArrowUp") {
// 내 형제 중에 이전 li 태그를 가져옴
const prevLi = currentTarget.previousElementSibling as HTMLLIElement;
// 이전 li 태그가 있으면
if (prevLi) {
// 이전 li
prevLi.focus();

// 현재 li 태그에 tabindex를 제거
currentTarget.removeAttribute("tabindex");

// 이전 li 태그에 tabindex를 추가
prevLi.setAttribute("tabindex", "0");

return;
}
}
if (!searchCompanyName.find((hashtag) => hashtag === value)) {
setSearchCompanyName([...searchCompanyName, value]);

// 방향키 아래로 눌렀을 때
if (key === "ArrowDown") {
// 내 형제 중에 다음 li 태그를 가져옴
const nextLi = currentTarget.nextElementSibling as HTMLLIElement;
// 다음 li 태그가 있으면
if (nextLi) {
// 다음 li
nextLi.focus();

// 현재 li 태그에 tabindex를 제거
currentTarget.removeAttribute("tabindex");

// 다음 li 태그에 tabindex를 추가
nextLi.setAttribute("tabindex", "0");

return;
}
}
setValue("");
}
}, 300),
[]
);

const handleListKeyDown = (event: React.KeyboardEvent<HTMLLIElement>) => {
const currentTarget = event.currentTarget;
const key = event.key;
const latestSearchCompanyName = [...searchCompanyName];
event.stopPropagation();
debounceHandleListKeyDown(key, currentTarget, latestSearchCompanyName);
};

useEffect(() => {
Expand All @@ -66,14 +185,49 @@ export const CompanyNameForm = ({
(꼭 받고 싶은 기업명을 태그로 입력)
</span>
</Label>
<Input
value={value}
onChange={handleInputChange}
onKeyDown={handleInputKeyDown}
className="w-[208px] h-[40px]"
defaultValue={""}
placeholder="기업명을 입력해주세요"
/>
<div
style={{
position: "relative",
}}
>
<Input
value={value}
onChange={handleInputChange}
onKeyDown={handleInputKeyDown}
className="w-[208px] h-[40px]"
placeholder="기업명을 검색하세요!"
/>
{value && list.length > 0 && (
<Ul id="company-list">
{list.map(({ companyName }, index) => (
<Li
id={"company-list-item-" + index}
key={index}
onClick={() => {
if (searchCompanyName.length >= MAX_COMPANY_COUNT) {
toast.error(
`최대 ${MAX_COMPANY_COUNT}개까지 등록 가능합니다.`
);
return;
}

if (
!searchCompanyName.find(
(hashtag) => hashtag === companyName
)
) {
setSearchCompanyName([...searchCompanyName, companyName]);
}
setValue("");
}}
onKeyDown={handleListKeyDown}
>
{companyName}
</Li>
))}
</Ul>
)}
</div>
<TagContainer>
{searchCompanyName.map((hashtag, index) => (
<TagSpan key={index}>
Expand Down Expand Up @@ -312,3 +466,48 @@ const TagRemoveButton = styled.button`
outline: none;
margin-left: 0.5rem;
`;

const Ul = styled.ul`
position: absolute;
top: 40px;
left: 0;
width: 208px;
border: 1px solid #ccc;
border-top: none;
background-color: white;
list-style: none;
margin: 0;
padding: 0;
max-height: 152px;
overflow-y: auto;
z-index: 1000;
height: 192px;
overflow-x: hidden;
overflow-y: auto;
ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
background-color: #1c1c20;
// 좌하단 둥근 모서리
// border-bottom-left-radius: 5px;
// border-bottom-right-radius: 5px;
border-radius: 5px;
`;

const Li = styled.li`
padding: 10px;
cursor: pointer;
color: white;
font-size: 12px;
&:hover {
background-color: #33333b;
}
&:focus {
background-color: #33333b;
outline: none;
}
`;
Loading

0 comments on commit 96c8a8a

Please sign in to comment.