Skip to content

Commit

Permalink
Merge branch 'feature-view_product' into viewProduct/#112
Browse files Browse the repository at this point in the history
  • Loading branch information
Happhee authored Jul 20, 2022
2 parents 494b030 + 7031def commit cb91b5a
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 46 deletions.
66 changes: 52 additions & 14 deletions components/viewProduct/FilterDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import styled from '@emotion/styled';
import { FilterDropdownProps } from '../../types/viewProduct';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { checkedItemsState, filterTagState } from '../../core/atom';
import { FilterDropdownProps, FilterTagProps } from '../../types/viewProduct';

export default function FilterDropdown(props: FilterDropdownProps) {
const {
Expand All @@ -8,31 +10,67 @@ export default function FilterDropdown(props: FilterDropdownProps) {
isExcept,
categoryIdx,
checkedItem,
handleCheckedItems,
categoryKey,
} = props;
const [checkedItems, setCheckedItems] = useRecoilState(checkedItemsState);
const [filterTagList, setFilterTagList] =
useRecoilState<FilterTagProps[]>(filterTagState);
const filterTagKeys = Object.keys(filterTagList);
const filterTagValues = Object.values(filterTagList);
const handleCheckedItems = (
categoryIdx: number,
elementIdx: number,
tagText: string,
) => {
const tag: FilterTagProps = {
categoryIdx: categoryIdx,
elementIdx: elementIdx,
categoryKey: categoryKey,
tagText: tagText,
};
if (checkedItems[categoryIdx].has(elementIdx)) {
checkedItems[categoryIdx].delete(elementIdx);
const deleteidx = filterTagList.findIndex((item) => {
return (
item.categoryIdx === categoryIdx && item.elementIdx === elementIdx
);
});

const handleCheckedItem = (elementIdx: number) => {
if (checkedItem.has(elementIdx)) {
checkedItem.delete(elementIdx);
let copyFilterTagList = [...filterTagList];
copyFilterTagList.splice(deleteidx, 1);
setFilterTagList(copyFilterTagList);
console.log(filterTagList);
} else {
checkedItem.add(elementIdx);
checkedItems[categoryIdx].add(elementIdx);
setFilterTagList([...filterTagList, tag]);
console.log(filterTagList);
}

handleCheckedItems(checkedItem, categoryIdx);
setCheckedItems({
...checkedItems,
[categoryIdx]: checkedItems[categoryIdx],
});
};

return (
<StDropdownWrapper isDrop={isDrop} isExcept={isExcept}>
{categoryInfo.map((sort: string, elementIdx: number) => {
{categoryInfo.map((tagText: string, elementIdx: number) => {
return (
<StLabel
htmlFor={sort}
key={sort}
onChange={() => handleCheckedItem(elementIdx)}
isChecked={checkedItem.has(elementIdx)}
htmlFor={`${tagText}${categoryIdx}`}
key={`${tagText}${categoryIdx}`}
onChange={() =>
handleCheckedItems(categoryIdx, elementIdx, tagText)
}
isChecked={checkedItems[categoryIdx].has(elementIdx)}
>
<StInput type="checkbox" id={sort} name={sort} />
<StFilterElement>{sort}</StFilterElement>
<StInput
type="checkbox"
id={`${tagText}${categoryIdx}`}
name={`${tagText}${categoryIdx}`}
checked={checkedItems[categoryIdx].has(elementIdx)}
/>
<StFilterElement>{tagText}</StFilterElement>
</StLabel>
);
})}
Expand Down
76 changes: 76 additions & 0 deletions components/viewProduct/FilterTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil';
import {
checkedItemsState,
filterListState,
filterTagState,
} from '../../core/atom';
import { IcDeleteTag } from '../../public/assets/icons';
import { FilterTagProps } from '../../types/viewProduct';

export default function FilterTag(props: FilterTagProps) {
const { categoryIdx, elementIdx, categoryKey, tagText } = props;
const [checkedItems, setCheckedItems] = useRecoilState(checkedItemsState);
const [filterTagList, setFilterTagList] =
useRecoilState<FilterTagProps[]>(filterTagState);
const filterTagValues = Object.values(filterTagList);
const handleFilterTag = (
categoryIdx: number,
elementIdx: number,
tagText: string,
) => {
const tag: FilterTagProps = {
categoryIdx: categoryIdx,
elementIdx: elementIdx,
categoryKey: categoryKey,
tagText: tagText,
};
if (checkedItems[categoryIdx].has(elementIdx)) {
checkedItems[categoryIdx].delete(elementIdx);
const deleteidx = filterTagList.findIndex((item) => {
return (
item.categoryIdx === categoryIdx && item.elementIdx === elementIdx
);
});

let copyFilterTagList = [...filterTagList];
copyFilterTagList.splice(deleteidx, 1);
setFilterTagList(copyFilterTagList);
} else {
checkedItems[categoryIdx].add(elementIdx);
setFilterTagList([...filterTagList, tag]);
console.log(filterTagList);
}

setCheckedItems({
...checkedItems,
[categoryIdx]: checkedItems[categoryIdx],
});
};
return (
<StFilterTag>
<h2>{tagText === '기타' ? `${tagText} (${categoryKey})` : tagText}</h2>
<StDeleteBtn
onClick={() => handleFilterTag(categoryIdx, elementIdx, tagText)}
/>
</StFilterTag>
);
}
const StFilterTag = styled.div`
display: flex;
align-items: center;
width: fit-content;
padding: 0.6rem 0.8rem 0.6rem 1rem;
margin: 0.5rem;
border-radius: 0.6rem;
background-color: ${({ theme }) => theme.colors.gray002};
color: ${({ theme }) => theme.colors.gray009};
${({ theme }) => theme.fonts.b5_14_medium_140};
`;
const StDeleteBtn = styled(IcDeleteTag)`
margin-left: 0.713rem;
cursor: pointer;
`;
41 changes: 13 additions & 28 deletions components/viewProduct/ProductFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import styled from '@emotion/styled';
import { LoaderValue } from 'next/dist/shared/lib/image-config';
import React, { EventHandler, useState } from 'react';
import { useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { checkedItemsState, filterListState } from '../../core/atom';
import { IcClose, IcOpen } from '../../public/assets/icons';
import FilterDropdown from './FilterDropdown';
import { useRecoilState, useRecoilValue } from 'recoil';
import { filterListState } from '../../core/atom';
interface ProductFilterIcon {
title: string;
value: boolean;
}

export default function ProductFilter() {
const { filterList } = useRecoilValue(filterListState);
const filterlist = useRecoilValue(filterListState);

const filterListData = Object.values(filterList);
const filterListKeys = Object.keys(filterList);
const [visibility, setVisibility] = useState<boolean[]>([
false,
false,
false,
false,
false,
]);
const [checkedItems, setCheckedItems] = useState<Set<number>[]>([
new Set<number>(),
new Set<number>(),
new Set<number>(),
new Set<number>(),
new Set<number>(),
]);
console.log(checkedItems);

const filterListData = Object.values(filterlist.filterList);
const filterListKeys = Object.keys(filterlist.filterList);
const [checkedItems, setcheckedItems] = useRecoilState(checkedItemsState);

const handleDropdown = (idx: number) => {
setVisibility({
Expand All @@ -37,10 +27,6 @@ export default function ProductFilter() {
});
};

const handleCheckedItems = (copyCheckedItem: Set<number>, idx: number) => {
setCheckedItems({ ...checkedItems, [idx]: copyCheckedItem });
};

//const [repeat, setRepeat] = useState<null | number | void | string>();
// const handleDrop = (idx: number) => {
// if (visibility[idx]) {
Expand Down Expand Up @@ -83,7 +69,9 @@ export default function ProductFilter() {
isDrop={visibility[idx]}
checkedItem={checkedItems[idx]}
categoryKey={title}

handleCheckedItems={handleCheckedItems}

/>
)}
</StFilterSection>
Expand All @@ -94,9 +82,10 @@ export default function ProductFilter() {

const StFilterWrapper = styled.div`
width: 20rem;
height: 28rem;
height: fit-content;
padding-left: 1.2rem;
margin-right: 2.4rem;
margin-bottom: 7.2rem;
`;
const StFilterTitle = styled.div`
display: flex;
Expand All @@ -114,7 +103,3 @@ const StFilterSection = styled.section<{ isDrop: boolean }>`
${({ theme }) => theme.fonts.b4_15_semibold_146};
cursor: pointer;
`;

// function repeat(repeat: any) {
// throw new Error('Function not implemented.');
// }
65 changes: 65 additions & 0 deletions components/viewProduct/TagSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { filterListState, filterTagState } from '../../core/atom';
import { IcUndoBtn } from '../../public/assets/icons';
import { FilterTagProps } from '../../types/viewProduct';
import FilterTag from './FilterTag';

export default function TagSection() {
const filterTagList = useRecoilValue<FilterTagProps[]>(filterTagState);

return (
<StTagSection>
<StTagWrapper>
{filterTagList.map(
({ categoryIdx, elementIdx, categoryKey, tagText }) => {
return (
<FilterTag
key={`${categoryKey}${tagText}`}
categoryIdx={categoryIdx}
elementIdx={elementIdx}
categoryKey={categoryKey}
tagText={tagText}
/>
);
},
)}
</StTagWrapper>
<StUndoAllTagBtn>
<h2>모두 해제</h2>
<IcUndoBtn />
</StUndoAllTagBtn>
</StTagSection>
);
}

const StTagWrapper = styled.article`
display: flex;
justify-content: flex-start;
flex-flow: row wrap;
width: 77.6rem;
height: fit-content;
`;
const StTagSection = styled.div`
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 1.5rem 0;
margin-left: 2.4rem;
border-bottom: 0.1rem solid ${({ theme }) => theme.colors.gray002};
`;
const StUndoAllTagBtn = styled.button`
display: flex;
align-items: center;
padding: 0 0 0 1rem;
margin-top: 0.5rem;
background-color: ${({ theme }) => theme.colors.white};
border-radius: 0.6rem;
border: 0.1rem solid ${({ theme }) => theme.colors.gray004};
color: ${({ theme }) => theme.colors.gray007};
${({ theme }) => theme.fonts.b5_14_medium_140};
`;
2 changes: 2 additions & 0 deletions components/viewProduct/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ export { default as ProductFilter } from './ProductFilter';
export { default as FilterDropdown } from './FilterDropdown';
export { default as ToyList } from './ToyList';
export { default as ToyPreview } from './ToyPreview';
export { default as FilterTag } from './FilterTag';
export { default as TagSection } from './TagSection';
export { default as TopFloatingBtn } from './TopFloatingBtn';
18 changes: 16 additions & 2 deletions core/atom.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { atom } from 'recoil';
import { atom, selector, selectorFamily } from 'recoil';
import { recoilPersist } from 'recoil-persist'; //페이지가 변경되더라도 상태관리를 유지
import { PostCommunityBody } from '../types/community';
import { PostLoginBody, UserData } from '../types/user';
import { FilterTagProps } from '../types/viewProduct';
import { FilterDropdownProps, FilterTagProps } from '../types/viewProduct';


const { persistAtom } = recoilPersist();

Expand All @@ -17,6 +18,7 @@ export const userInfoState = atom<PostLoginBody>({
effects_UNSTABLE: [persistAtom],
});


export const newPostInfoState = atom<PostCommunityBody>({
key: 'newPostInfo',
default: {
Expand All @@ -26,6 +28,7 @@ export const newPostInfoState = atom<PostCommunityBody>({
},
effects_UNSTABLE: [persistAtom],
});

export const filterListState = atom({
key: 'filterListState',
default: {
Expand Down Expand Up @@ -82,3 +85,14 @@ export const filterTagState = atom<FilterTagProps[]>({
key: 'filterTagState',
default: [],
});

export const checkedItemsState = atom<Set<number>[]>({
key: 'checkedItemsState',
default: [
new Set<number>(),
new Set<number>(),
new Set<number>(),
new Set<number>(),
new Set<number>(),
],
});
Loading

0 comments on commit cb91b5a

Please sign in to comment.