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

[박소현] week15 #550

56 changes: 36 additions & 20 deletions pages/folder/FolderContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
import { ChangeEvent, useContext, useEffect, useState } from "react";
import useSWR from "swr";
import { useRouter } from "next/router";

import { FolderContext } from "@/context/FolderContext";
import FolderUI from "./FolderPresenter";
import { FolderData, LinkData } from "@/types/folder";
import { FolderData, FolderNameData, LinkData, SharedFolderData } from "@/types/folder";
import { useFolder } from "@/hooks/useFolder";

export const DEFAULT = "전체";
const USER_ID = 1;
// const USER_ID = 1;

/**
* @TODO
* /folders, /links api로 변경
* 토큰을 가져와서 hearder에 함께 보내기
* 다른 폴더를 선택한 경우 folder/folderId 페이지로 이동
*/

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

const [links, setLinks] = useState<LinkData[]>([]);
const [filteredLinks, setFilteredLinks] = useState<LinkData[]>([]);
const [folders, setFolders] = useState<FolderData[]>([]);
const [folders, setFolders] = useState<SharedFolderData[]>([]);
const [selected, setSelected] = useState(DEFAULT);
const [selectedFolderId, setSelectedFolderId] = useState("");
const [addLinkValue, setAddLinkValue] = useState("");
const [keyword, setKeyword] = useState("");

const {
data: linkData,
isLoading,
error: linkError,
} = useSWR(`/api/users/${USER_ID}/links?folderId=${selectedFolderId ?? ""}`);
const { data: folderData, error: folderError } = useSWR(`/api/users/${USER_ID}/folders`);
const { data: foldersData, isLoading } = useFolder("/api/folders");
const { data: linksData } = useFolder("/api/links");
console.log(foldersData); // 삭제예정
console.log(linksData); // 삭제예정

const { handleFolderUpdate } = useContext(FolderContext);

Expand Down Expand Up @@ -54,7 +62,8 @@ export default function Folder() {
};

const changeFolderId = (category: string) => {
const selectedFolder = folders.find((folder: FolderData) => folder.name === category)?.id ?? "";
const selectedFolder =
folders.find((folder: SharedFolderData) => folder.name === category)?.id ?? "";
setSelectedFolderId(selectedFolder as string);
};

Expand All @@ -69,17 +78,24 @@ export default function Folder() {
};

useEffect(() => {
if (linkData && folderData) {
setLinks(linkData.data);
setFilteredLinks(linkData.data);
setFolders(folderData.data);
updateFolderList(folderData.data);
if (!localStorage.getItem("accessToken")) {
alert("로그인 후 이용가능합니다.");
router.push("/signin");
}
}, [router]);

useEffect(() => {
if (linksData && foldersData) {
setLinks(linksData.data.folder);
setFilteredLinks(linksData.data.folder);
setFolders(foldersData.data.folder);
// updateFolderList(foldersData.data.folder);
}
}, [linkData, folderData, selectedFolderId]);
}, [linksData, foldersData, selectedFolderId]);

if (linkError || folderError) {
console.log(linkError || folderError);
}
// if (linkError || folderError) {
// console.log(linkError || folderError);
// }

return (
<FolderUI
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChangeEvent, useEffect, useState } from "react";
import useSWR from "swr";
import { useRouter } from "next/router";
import * as S from "./ShareContainerStyles";

import Layout from "@/components/layout/Layout";
Expand All @@ -8,30 +9,38 @@ import Searchbar from "@/components/inputs/Searchbar";
import Hero from "@/components/hero/Hero";
import Loading from "@/components/Loading";

import { Owner } from "@/types/user";
import { SampleFolderData, SampleLinkData } from "@/types/folder";
import { LinkData, SharedFolderData } from "@/types/folder";

export default function Share() {
const [folder, setFolder] = useState("");
const [profile, setProfile] = useState<Owner>({ id: 0, name: "", profileImageSource: "" });
const [links, setLinks] = useState<SampleLinkData[]>([]);
const [filteredLinks, setFilteredLinks] = useState<SampleLinkData[]>([]);
const router = useRouter();
const folderId = router.query.id;

const [links, setLinks] = useState<LinkData[]>([]);
const [filteredLinks, setFilteredLinks] = useState<LinkData[]>([]);
const [keyword, setKeyword] = useState("");

const { data, isLoading, error } = useSWR<SampleFolderData>("/api/sample/folder");
const { data, isLoading, error } = useSWR<{ data: SharedFolderData[] }>(
`/api/folders/${folderId}`,
);
const { data: linksData } = useSWR<{ data: LinkData[] }>(
`/api/users/${data?.data[0].user_id}/links?folderId=${folderId}`,
);

/** @TODO 검색바 관련 로직 분리해보기(folder에서도 사용하므로) */
const handleOnChangeInput = (e: ChangeEvent<HTMLInputElement>) => {
setKeyword(e.target.value);
const searchedLinks = checkMatchedAllLinks(e.target.value, links);
setFilteredLinks(searchedLinks.length !== 0 ? searchedLinks : []);
if (linksData?.data) {
setKeyword(e.target.value);
const searchedLinks = checkMatchedAllLinks(e.target.value, linksData?.data);
setFilteredLinks(searchedLinks.length !== 0 ? searchedLinks : []);
}
};

const handleDeletekeyword = () => {
setKeyword("");
setFilteredLinks(links);
};

const checkMatchedAllLinks = (keyword: string, links: SampleLinkData[]) => {
const checkMatchedAllLinks = (keyword: string, links: LinkData[]) => {
const filteredLinks = links.filter((link) => {
return (
(link.title && link.title.includes(keyword)) ||
Expand All @@ -43,15 +52,11 @@ export default function Share() {
};

useEffect(() => {
if (data) {
const { name: folderName, owner, links } = data.folder;

setFolder(folderName);
setProfile(owner);
setLinks(links);
setFilteredLinks(links);
if (linksData) {
setLinks(linksData.data);
setFilteredLinks(linksData.data);
}
}, [data]);
}, [linksData]);

if (error) console.log(error);

Expand All @@ -61,9 +66,7 @@ export default function Share() {
<Loading />
) : (
<Layout>
<S.HeroContainer>
<Hero folder={folder} profile={profile} />
</S.HeroContainer>
<S.HeroContainer>{data && <Hero folder={data?.data[0]} />}</S.HeroContainer>
<section>
<S.Contents>
<Searchbar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import styled from "styled-components";
import { breakPoints } from "@/common/media";

export const HeroContainer = styled.section`
height: 15.25rem;
text-align: center;
background-color: var(--color-primary-varient);
`;
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/components/Kebabmenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function KebabMenu({ link }: KebabMenuProps) {

return (
<>
<img src="assets/kebab.svg" onClick={handleMenuToggle} alt="memu" />
<img src="/assets/kebab.svg" onClick={handleMenuToggle} alt="memu" />
{isOpenMenu && <PopoverMenu onClickModal={handleModalOpen} />}

{isOpenModal && (
Expand Down
33 changes: 22 additions & 11 deletions src/components/hero/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import useSWR from "swr";
import * as S from "./HeroStyles";
import { Owner } from "@/types/user";

import { SharedFolderData } from "@/types/folder";
import { User } from "@/types/user";
import Loading from "@/components/Loading";

interface HeroProps {
folder: string;
profile: Owner;
folder: SharedFolderData;
}

export default function Hero({ folder, profile }: HeroProps) {
export default function Hero({ folder }: HeroProps) {
const { data, isLoading } = useSWR<{ data: User[] }>(`/api/users/${folder.user_id}`);

return (
<>
<S.Profile>
<S.Image src={profile?.profileImageSource} alt="avatar" />
<S.Name>{profile?.name}</S.Name>
</S.Profile>
<S.Title>{folder}</S.Title>
</>
<S.HeroContainer>
{isLoading ? (
<Loading />
) : (
<>
<S.Profile>
<S.Image src={data?.data[0].image_source} alt="avatar" />
<S.Name>{data?.data[0].name}</S.Name>
</S.Profile>
<S.Title>{folder?.name}</S.Title>
</>
)}
</S.HeroContainer>
);
}
12 changes: 10 additions & 2 deletions src/components/hero/HeroStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@ import styled from "styled-components";
import { breakPoints } from "@/common/media";
import LinkIcon from "public/assets/link.svg";

export const HeroContainer = styled.div`
margin-top: 4.2rem;
padding-bottom: 3.75rem;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
`;

export const Profile = styled.div`
padding-top: 5.5rem;
margin: 0;
text-align: center;

Expand Down Expand Up @@ -33,7 +42,6 @@ export const Name = styled.p`
`;

export const Title = styled.h2`
padding-bottom: 3.75rem;
font-size: 2.5rem;
font-weight: var(--font-semibold);
margin: 0 auto;
Expand Down
36 changes: 36 additions & 0 deletions src/hooks/useFolder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import useSWR from "swr";
import { useEffect, useState } from "react";
import { DOMAIN_URL } from "@/common/constants";

export function useFolder(url: string) {
const [accessToken, setAccessToken] = useState<string | null>();

// accessToken 없을때 401 에러나는 로직
// const fetcher = (url: string) =>
// fetch(`${DOMAIN_URL}${url}`, {
// headers: { Authorization: `Bearer ${accessToken}` },
// }).then((res) => res.json());

const fetcher = (url: string) => {
if (accessToken) {
return fetch(`${DOMAIN_URL}${url}`, {
headers: { Authorization: `Bearer ${accessToken}` },
}).then((res) => res.json());
}
};

const { data, isLoading, mutate } = useSWR(url, fetcher);

useEffect(() => {
if (localStorage.getItem("accessToken") !== null) {
setAccessToken(localStorage.getItem("accessToken"));
mutate();
}
}, [mutate, accessToken]);

return {
data,
isLoading,
mutate,
};
}
7 changes: 7 additions & 0 deletions src/types/folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,11 @@ export interface SampleFolderData {
};
}

export interface SharedFolderData {
id: number;
name: string;
user_id: number;
created_at: string;
}

export type FolderNameData = Omit<FolderData, "created_at">;