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

[#603] [내 프로필] ErrorBoundary 제거 #604

Merged
merged 6 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 src/app/profile/me/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const MyProfileForUnAuth = () => {
return (
<>
<TopHeader text="Profile" />
<div className="flex flex-col gap-[2rem]">
<div className="flex flex-col gap-[3rem]">
<div className="mb-[2rem] flex items-center gap-[1rem]">
<Avatar size="large" />
<div className="flex-grow">
Expand Down
7 changes: 4 additions & 3 deletions src/queries/bookshelf/useMySummaryBookShelfQuery.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import bookshelfAPI from '@/apis/bookshelf';
import { useQuery } from '@tanstack/react-query';
import type { QueryOptions } from '@/types/query';
import type { APIBookshelf } from '@/types/bookshelf';
import type { QueryOptions } from '@/types/query';

import useQueryWithSuspense from '@/hooks/useQueryWithSuspense';
import bookShelfKeys from './key';

const useMySummaryBookshelfQuery = (options?: QueryOptions<APIBookshelf>) =>
useQuery(
useQueryWithSuspense(
bookShelfKeys.summary('me'),
() => bookshelfAPI.getMySummaryBookshelf().then(({ data }) => data),
options
Expand Down
8 changes: 2 additions & 6 deletions src/v1/profile/bookShelf/MyProfileBookshelfContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@ import ProfileBookshelfPresenter from './ProfileBookshelfPresenter';
import useMySummaryBookshelfQuery from '@/queries/bookshelf/useMySummaryBookShelfQuery';

const MyProfileBookshelfContainer = () => {
const { isSuccess, data } = useMySummaryBookshelfQuery({
suspense: true,
});
const { data } = useMySummaryBookshelfQuery();

if (!isSuccess) return null;

return <ProfileBookshelfPresenter {...data}></ProfileBookshelfPresenter>;
return <ProfileBookshelfPresenter {...data} />;
};

export default MyProfileBookshelfContainer;
48 changes: 5 additions & 43 deletions src/v1/profile/bookShelf/ProfileBookShelf.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,14 @@
import QueryErrorBoundaryFallback from '@/v1/base/QueryErrorBoundaryFallback';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import type { APIUser } from '@/types/user';

import MyProfileBookshelfContainer from './MyProfileBookshelfContainer';
import UserProfileBookshelfContainer from './UserProfileBookshelfContainer';
import useMounted from '@/hooks/useMounted';
import Loading from '@/v1/base/Loading';

const ProfileBookShelf = ({ userId }: { userId: 'me' | APIUser['userId'] }) => {
const mounted = useMounted();

if (!mounted) return null;

return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<QueryErrorBoundaryFallback
resetErrorBoundary={resetErrorBoundary}
/>
)}
>
<Suspense fallback={<ProfileBookShelfSkeleton />}>
{userId === 'me' ? (
<MyProfileBookshelfContainer />
) : (
<UserProfileBookshelfContainer userId={userId} />
)}
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
return userId === 'me' ? (
<MyProfileBookshelfContainer />
) : (
<UserProfileBookshelfContainer userId={userId} />
);
};

export default ProfileBookShelf;

const ProfileBookShelfSkeleton = () => {
return (
<div className="flex animate-pulse flex-col gap-[2rem]">
<div className="h-[2.7rem] w-[5rem] bg-placeholder" />

<div className="flex h-[13.2rem] items-center justify-center">
<Loading />
</div>
</div>
);
};
8 changes: 2 additions & 6 deletions src/v1/profile/bookShelf/UserProfileBookshelfContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ const UserProfileBookshelfContainer = ({
}: {
userId: APIUser['userId'];
}) => {
const { isSuccess, data } = useUserSummaryBookshelfQuery(userId, {
suspense: true,
});
const { data } = useUserSummaryBookshelfQuery(userId);

if (!isSuccess) return null;

return <ProfileBookshelfPresenter {...data}></ProfileBookshelfPresenter>;
return <ProfileBookshelfPresenter {...data} />;
};

export default UserProfileBookshelfContainer;
68 changes: 28 additions & 40 deletions src/v1/profile/group/ProfileGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,44 @@
import useMounted from '@/hooks/useMounted';
import SSRSafeSuspense from '@/components/SSRSafeSuspense';

import { APIUser } from '@/types/user';
import QueryErrorBoundaryFallback from '@/v1/base/QueryErrorBoundaryFallback';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';

import Skeleton from '@/v1/base/Skeleton';
import ProfileGroupContainer from './ProfileGroupContainer';

const ProfileGroup = ({ userId }: { userId: 'me' | APIUser['userId'] }) => {
const mounted = useMounted();

if (!mounted) return null;

return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<QueryErrorBoundaryFallback
resetErrorBoundary={resetErrorBoundary}
/>
)}
>
<Suspense fallback={<ProfileGroupSkeleton />}>
<ProfileGroupContainer userId={userId} />
</Suspense>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
<SSRSafeSuspense fallback={<ProfileGroupSkeleton />}>
<ProfileGroupContainer userId={userId} />
</SSRSafeSuspense>
);
};

export default ProfileGroup;

const ProfileGroupSkeleton = () => {
return (
<div className="flex animate-pulse flex-col gap-[0.6rem]">
<div className="flex h-[2.7rem] w-[6rem] bg-placeholder" />
<div className="flex gap-[1rem] overflow-scroll">
<div className="flex flex-col gap-[0.5rem]">
<div className="h-[11.6rem] w-[10rem] bg-placeholder" />
<div className="h-[1.5rem] bg-placeholder" />
</div>
<div className="flex flex-col gap-[0.5rem]">
<div className="h-[11.6rem] w-[10rem] bg-placeholder" />
<div className="h-[1.5rem]bg-placeholder" />
</div>
<div className="flex flex-col gap-[0.5rem]">
<div className="h-[11.6rem] w-[10rem] bg-placeholder" />
<div className="h-[1.5rem] bg-placeholder" />
<Skeleton>
<div className="flex flex-col gap-[1.5rem]">
<Skeleton.Text fontSize="2xlarge" width="6rem" />
<div className="flex gap-[1rem] overflow-scroll">
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
<div className="flex flex-col gap-[1rem]">
<Skeleton.Rect rounded="small" width="10rem" height="12.3rem" />
<Skeleton.Text fontSize="small" width="10rem" />
</div>
</div>
</div>
</div>
</Skeleton>
);
};
4 changes: 1 addition & 3 deletions src/v1/profile/group/ProfileGroupContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ const ProfileGroupContainer = ({
}: {
userId: 'me' | APIUser['userId'];
}) => {
const { isSuccess, data } = useMyGroupsQuery({ suspense: true });
const { data } = useMyGroupsQuery();
const {
data: { userId: myId },
} = useMyProfileQuery({ enabled: userId === 'me' });

const isMeOwner = (ownerId: number) => ownerId === myId;

if (!isSuccess) return null;

return (
<ProfileGroupPresenter userId={userId} isGroupOwner={isMeOwner} {...data} />
);
Expand Down
64 changes: 23 additions & 41 deletions src/v1/profile/info/ProfileInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,42 @@
import { ReactNode, Suspense } from 'react';
import type { APIUser } from '@/types/user';

import SSRSafeSuspense from '@/components/SSRSafeSuspense';

import Skeleton from '@/v1/base/Skeleton';
import MyProfileContainer from './MyProfileInfoContainer';
import UserProfileInfoContainer from './UserProfileInfoContainer';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { ErrorBoundary } from 'react-error-boundary';
import type { APIUser } from '@/types/user';
import QueryErrorBoundaryFallback from '@/v1/base/QueryErrorBoundaryFallback';
import useMounted from '@/hooks/useMounted';

type ProfileInfoProps = {
children?: ReactNode;
userId: 'me' | APIUser['userId'];
};

const ProfileInfo = ({ userId, children }: ProfileInfoProps) => {
const mounted = useMounted();

if (!mounted) return null;

const ProfileInfo = ({ userId }: ProfileInfoProps) => {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary }) => (
<QueryErrorBoundaryFallback
resetErrorBoundary={resetErrorBoundary}
/>
)}
>
<Suspense fallback={<ProfileInfoSkeleton />}>
{userId === 'me' ? (
<MyProfileContainer />
) : (
<UserProfileInfoContainer userId={userId} />
)}
{children && children}
</Suspense>
</ErrorBoundary>
<SSRSafeSuspense fallback={<ProfileInfoSkeleton />}>
{userId === 'me' ? (
<MyProfileContainer />
) : (
<UserProfileInfoContainer userId={userId} />
)}
</QueryErrorResetBoundary>
</SSRSafeSuspense>
);
};

export default ProfileInfo;

const ProfileInfoSkeleton = () => {
return (
<div className="mb-[2rem] flex animate-pulse flex-col gap-[2rem]">
<div className="flex gap-[0.8rem]">
<div className="h-[2.1rem] w-[3.8rem] rounded-lg bg-placeholder" />
<div className="h-[2.1rem] w-[7.6rem] rounded-lg bg-placeholder" />
</div>
<div className="flex items-center gap-[1rem]">
<div className="h-[7rem] w-[7rem] rounded-full bg-placeholder" />
<div className="h-[2.7rem] w-[11rem] bg-placeholder" />
<Skeleton>
<div className="mb-[2rem] flex flex-col gap-[2rem]">
<div className="flex gap-[0.8rem]">
<Skeleton.Rect width="3.8rem" height="2.1rem" />
<Skeleton.Rect width="10.4rem" height="2.1rem" />
</div>
<div className="flex items-center gap-[1rem]">
<Skeleton.Circle size="large" />
<Skeleton.Text fontSize="2xlarge" width="18rem" />
</div>
</div>
</div>
</Skeleton>
);
};
Loading