Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[박상준] Week14 #453

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6c0e520
feat: 로그인 회원가입 페이지 수정
sj0724 May 13, 2024
350499f
feat: 유저 id정보 context로 공유
sj0724 May 13, 2024
9792340
feat: 로그인 api추가, 토큰 로컬스토리지 저장
sj0724 May 13, 2024
6e5f12b
feat: 토큰으로 로그인 기능 구현
sj0724 May 13, 2024
babb6cb
feat: 로그인 기능 구현
sj0724 May 14, 2024
97babbd
feat: 로그아웃 기능 추가
sj0724 May 14, 2024
b0ed51d
feat: 회원가입 기능 구현
sj0724 May 14, 2024
94f2d2e
fix: 로그인전 페이지 이동시 로그인 페이지로 이동 및 css 수정
sj0724 May 14, 2024
049aa3d
fix: 모달 에러 메세지 추가 및 css 수정
sj0724 May 14, 2024
c3a8163
fix: 인풋 옵저버 영역 css 수정
sj0724 May 14, 2024
c4867c1
feat: 파일 추가 api 연동
sj0724 May 14, 2024
071bdcc
feat: 폴더 삭제기능 구현
sj0724 May 15, 2024
9c6ab07
fix: kebab메뉴 로직 kebab 컴포넌트로 이돟ㅇ
sj0724 May 16, 2024
445af50
fix: 메인 페이지 card 이미지 코드 수정
sj0724 May 16, 2024
5dd36c1
fix: 폴더 모달 버튼 컴포넌트로 변경 및 모달 로직 수정
sj0724 May 16, 2024
e9350fd
fix: 폴더 id, name state 통합
sj0724 May 16, 2024
445c1ab
fix: 검색바 이미지 삼항연산자로 변경
sj0724 May 16, 2024
05541dd
feat: 링크 추가 기능 구현 및 날짜 구현로직 수정, 케밥에서 링크 추가 기능 구현중
sj0724 May 16, 2024
0b76147
fix: 케밥에서 링크 추가 기능 구현 완료
sj0724 May 17, 2024
b2ff729
feat: 링크 삭제기능 구현 및 addlink 모달 수정
sj0724 May 17, 2024
78bc723
fix: 날짜 계산 함수 수정
sj0724 May 17, 2024
3717a86
fix: document 파일 수정 및 react-hook-form 구현중
sj0724 May 18, 2024
666c40c
feat: 로그인, 회원가입 react-hook-form으로 변경
sj0724 May 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/Button/Button.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const buttonSize = {
lg: '40',
};

export const Cta = styled.span<ButtonProps>`
export const Cta = styled.button<ButtonProps>`
cursor: pointer;
text-decoration: none;
display: flex;
Expand Down
6 changes: 1 addition & 5 deletions components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,5 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
}

export function Button({ children, size }: ButtonProps) {
return (
<>
<S.Cta size={size}>{children}</S.Cta>
</>
);
return <S.Cta size={size}>{children}</S.Cta>;
}
4 changes: 2 additions & 2 deletions components/Card/Card.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const ItemImg = styled.div<{ image: string }>`
background-position: center;

&:hover {
background-size: 130%;
background-size: 150%;
}
`;

Expand Down Expand Up @@ -56,7 +56,6 @@ export const StarIcon = styled.img`
position: absolute;
top: 1.5rem;
right: 1.5rem;
z-index: 10;
`;

export const ItemInfo = styled.div`
Expand Down Expand Up @@ -88,6 +87,7 @@ export const ItemDescription = styled.p`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-top: 0.2rem;

a {
text-decoration: none;
Expand Down
100 changes: 46 additions & 54 deletions components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,79 +1,71 @@
import { useEffect, useRef, useState } from 'react';
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { changeDate, calculateDate } from '../../util/util';
import * as S from './Card.styled';
import KebabMenu from '../KebabMenu/KebabMenu';
import { Link } from '../../hooks/useGetFolder';
import { LinkData } from '../../hooks/useGetFolder';
import Image from 'next/image';
import Link from 'next/link';

function Card({ item }: { item: Link }) {
function Card({
item,
setUrl,
}: {
item: LinkData;
setUrl: Dispatch<SetStateAction<string>>;
}) {
const [createdAt, setCreatedAt] = useState({ time: 0, result: '' });
const [fullDate, setFullDate] = useState('');
const { image_source } = item;
const [kebabView, setKebaView] = useState(false);
const [kebabView, setKebabView] = useState(false);
const [like, setLike] = useState(false);
const kebabRef = useRef<HTMLObjectElement>(null);

const { url, description } = item;
const { url, description, id } = item;

const createdText = `${createdAt.time} ${createdAt.result} ago`;

useEffect(() => {
const nowDate = new Date();
let createdate = new Date(item.created_at);
const createdate = new Date(item.created_at);
const date = (Number(nowDate) - Number(createdate)) / 1000;
setCreatedAt(calculateDate(date));
setFullDate(changeDate(createdate));
}, [item]);

useEffect(() => {
function handleClickOutside(e: any) {
if (
kebabView &&
kebabRef.current &&
!kebabRef.current.contains(e.target)
) {
setKebaView(false);
}
}

document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [kebabView]);

return (
<S.ItemCard>
<S.StarIcon
src={like ? '/full_star.svg' : '/star.svg'}
alt="별 이미지"
onClick={() => {
setLike(!like);
}}
/>
{image_source ? (
<S.ItemImg image={image_source} />
) : (
<S.EmptyImg>
<Image src="/logo.svg" alt="빈 이미지" width={133} height={24} />
</S.EmptyImg>
)}
<S.ItemInfo>
<S.KebabIcon
src="/kebab.svg"
alt="kebabIcon"
onClick={() => setKebaView(!kebabView)}
<Link href={url} target="_blank" rel="noreferrer">
<S.ItemCard>
<S.StarIcon
src={like ? '/full_star.svg' : '/star.svg'}
alt="별 이미지"
onClick={(e) => {
setLike(!like);
e.preventDefault();
}}
/>
<S.ItemDate>{createdText}</S.ItemDate>
<S.ItemDescription>
<a href={url} target="_blank" rel="noreferrer">
{image_source ? (
<S.ItemImg image={image_source} />
) : (
<S.EmptyImg>
<Image src="/logo.svg" alt="빈 이미지" width={133} height={24} />
</S.EmptyImg>
)}
<S.ItemInfo>
<S.KebabIcon
src="/kebab.svg"
alt="kebabIcon"
onClick={(e) => {
setKebabView(!kebabView);
e.preventDefault();
}}
/>
<S.ItemDate>{createdText}</S.ItemDate>
<S.ItemDescription>
{description ? description : url}
</a>
</S.ItemDescription>
<S.ItemFullDate>{fullDate}</S.ItemFullDate>
</S.ItemInfo>
{kebabView && <KebabMenu menuRef={kebabRef} />}
</S.ItemCard>
</S.ItemDescription>
<S.ItemFullDate>{fullDate}</S.ItemFullDate>
</S.ItemInfo>
{kebabView && <KebabMenu url={url} setUrl={setUrl} id={id} />}
</S.ItemCard>
</Link>
);
}

Expand Down
2 changes: 2 additions & 0 deletions components/ContentsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { ReactNode } from 'react';
import styled from 'styled-components';

const Container = styled.div<{ $empty: number }>`
min-height: 40rem;
gap: 2rem;
display: grid;
grid-template-columns: ${(props) =>
props.$empty > 0 ? 'repeat(3, 1fr)' : 'none'};
margin: 0 auto;
position: relative;
margin-bottom: 10rem;

@media (max-width: 1199px) {
grid-template-columns: ${(props) => (props.$empty > 0 ? '1fr 1fr' : '1fr')};
Expand Down
5 changes: 5 additions & 0 deletions components/FolderButton/FolderButton.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export const FolderName = styled.span<{ $select: string | boolean }>`
white-space: nowrap;
color: ${(props) => (props.$select === 'select' ? '#fff' : '#000')};

&:hover {
background-color: var(--Primary);
color: #fff;
}

@media (max-width: 768px) {
font-size: 1.2rem;
}
Expand Down
11 changes: 5 additions & 6 deletions components/FolderButton/FolderButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ import { Folder } from '@/hooks/useGetFolderList';

function FolderButton({
item,
setFolderId,
setFolderName,
isSelected,
handleMenuClick,
index,
setOnSelect,
}: {
item: Folder;
setFolderId: React.Dispatch<React.SetStateAction<number>>;
setFolderName: React.Dispatch<React.SetStateAction<string>>;
isSelected: string;
handleMenuClick: (index: number) => void;
index: number;
setOnSelect: React.Dispatch<
React.SetStateAction<{ id: number; name: string }>
>;
}) {
const changeFolder = () => {
setFolderId(item.id);
setFolderName(item.name);
setOnSelect({ id: item.id, name: item.name });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 반영해주셨는데요!

props 로
setOnSelect -> onSelect: ({id, name}: {id: string; name: string}) => void;
요렇게 넘겨주면 어떨까요?

상태를 업데이트 한다는 지식을 이 컴포넌트가 갖지 않도록요~

handleMenuClick(index);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export const FolderButtons = styled.div`
display: flex;
align-items: center;
gap: 1.2rem;
flex-wrap: wrap;
overflow: auto;
width: 100%;
`;

export const TotalFolderButton = styled(FolderName)``;
Expand Down
23 changes: 14 additions & 9 deletions components/FolderButtonContainer/FolderButtonContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import * as S from './FolderButtonContainer.styled';
import FolderButton from '../FolderButton/FolderButton';
import { useModal } from '../../contexts/ModalContext';
import { Folders } from '../../hooks/useGetFolderList';
import ModalPortal from '@/Portal';
import AddFolderModal from '../Modal/AddFolderModal/AddFolderModal';

function FolderButtonContainer({
link,
setFolderName,
setFolderId,
setOnSelect,
}: {
link: Folders;
setFolderName: React.Dispatch<React.SetStateAction<string>>;
setFolderId: React.Dispatch<React.SetStateAction<number>>;
setOnSelect: React.Dispatch<
React.SetStateAction<{ id: number; name: string }>
>;
}) {
const [linkSelected, setLinkSelected] = useState<string[]>([]);
const [totalBtn, setTotalBtn] = useState(true);
const { openModal } = useModal();
const { modalState, openModal } = useModal();

const handleMenuClick = (index: number) => {
const booleanArr: string[] = new Array(link.length).fill('white');
Expand All @@ -27,8 +29,7 @@ function FolderButtonContainer({
const handleClickTotalButton = () => {
const totalArr: string[] = new Array(link.length).fill('white');
setLinkSelected(totalArr);
setFolderId(0);
setFolderName('');
setOnSelect({ id: 0, name: '' });
setTotalBtn(true);
};

Expand All @@ -46,8 +47,7 @@ function FolderButtonContainer({
<FolderButton
item={item}
key={item.name}
setFolderId={setFolderId}
setFolderName={setFolderName}
setOnSelect={setOnSelect}
isSelected={linkSelected[index]}
handleMenuClick={handleMenuClick}
index={index}
Expand All @@ -59,6 +59,11 @@ function FolderButtonContainer({
폴더 추가
<S.PlusIcon />
</S.AddFolderButton>
{modalState.addFolder && (
<ModalPortal>
<AddFolderModal />
</ModalPortal>
)}
</S.FolderMenu>
);
}
Expand Down
16 changes: 16 additions & 0 deletions components/FolderModalContainer/FolderModals.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styled from 'styled-components';

export const FolderModal = styled.div`
display: flex;
align-items: center;
gap: 1.2rem;
`;

export const FolderModalIcon = styled.div`
cursor: pointer;
display: flex;
align-items: center;
gap: 0.4rem;
color: var(--Linkbrary-gray60);
font-size: 1.4rem;
`;
62 changes: 62 additions & 0 deletions components/FolderModalContainer/FolderModals.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Image from 'next/image';
import { ReactNode } from 'react';
import * as S from './FolderModals.styled';
import { useModal } from '@/contexts/ModalContext';
import ModalPortal from '@/Portal';
import ShareModal from '../Modal/ShareModal/ShareModal';
import EditModal from '../Modal/EditModal/EditModal';
import DeleteModal from '../Modal/DeleteModal/DeleteModal';

function FolderIcon({
image,
children,
onOpen,
state,
}: {
image: string;
children: ReactNode;
onOpen: (modalName: string) => void;
state: string;
}) {
return (
<S.FolderModalIcon onClick={() => onOpen(`${state}`)}>
<Image src={image} alt={`${image}`} width={20} height={20} />
{children}
</S.FolderModalIcon>
);
}
Comment on lines +10 to +27
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

가급적 컴포넌트 파일 하나엔 하나의 컴포넌트 함수만 있도록 하거나, 최소한 파일명에 해당하는 컴포넌트를 위쪽에 배치하는게 좋을 것 같습니당


function FolderModals({ id, name }: { id: number; name: string }) {
const { modalState, openModal, closeModal } = useModal();

return (
<S.FolderModal>
<FolderIcon image="/share.svg" onOpen={openModal} state={'share'}>
공유
</FolderIcon>
<FolderIcon image="/pen.svg" onOpen={openModal} state={'edit'}>
이름 변경
</FolderIcon>
<FolderIcon image="/Group36.svg" onOpen={openModal} state={'delete'}>
삭제
</FolderIcon>
{modalState.share && (
<ModalPortal>
<ShareModal folderName={name} />
</ModalPortal>
)}
{modalState.edit && (
<ModalPortal>
<EditModal />
</ModalPortal>
)}
{modalState.delete && (
<ModalPortal>
<DeleteModal folderName={name} folderId={id} />
</ModalPortal>
)}
</S.FolderModal>
);
}

export default FolderModals;
4 changes: 2 additions & 2 deletions components/Footer/Footer.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Description } from '../MainSectionCard/MainSectionCard.styled';

export const Footer = styled.div`
width: 100%;
margin: 6rem auto 0;
margin: auto 0;
background: var(--Footer-black);
padding: 3.2rem 10.4rem 6.4rem;
color: #cfcfcf;
Expand All @@ -26,7 +26,7 @@ export const Footer__menu = styled.div`
justify-content: space-between;
`;

export const FooterDescrption = styled(Description)`
export const FooterDescription = styled(Description)`
width: fit-content;

@media (max-width: 768px) {
Expand Down
Loading
Loading