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

feat: scaffold pages (Post 플로우) #14

Merged
merged 6 commits into from
Apr 21, 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
11 changes: 8 additions & 3 deletions app/(public)/users/[userHandle]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import Link from 'next/link';

import { List, Settings } from 'lucide-react';
import { List, Settings, Share2 } from 'lucide-react';

import { AppBar, AppBarBack } from '@/components/ui-unstable/app-bar';
import { CopyCurrentPageTrigger } from '@/components/ui-unstable/copy-current-page-trigger';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import { IconButton } from '@/components/ui/icon-button';
import { ROUTES } from '@/constants/routes';
import { EditUserProfileSheet } from '@/features/user-handle-page/edit-user-profile-sheet';
import { PostByCategorySection } from '@/features/user-handle-page/post-by-category-section';
import { UserHandlePageShareAction } from '@/features/user-handle-page/user-handle-page-share-action';
import { UserHandlePageTrendingPostSection } from '@/features/user-handle-page/user-handle-page-trending-post-section';
import {
getFollowerDescriptor,
Expand Down Expand Up @@ -43,7 +44,11 @@ const UserHandlePage = ({ params: { username: _ } }: UserHandlePageProps) => {
<AppBar className="justify-between border-none bg-transparent text-white">
<AppBarBack />
<div className="flex items-center">
<UserHandlePageShareAction />
<CopyCurrentPageTrigger asChild>
<IconButton size="lg">
<Share2 className="h-5 w-5" />
</IconButton>
</CopyCurrentPageTrigger>
<Link href={ROUTES.SETTINGS}>
<div className="px-3 py-4">
<Settings className="h-5 w-5" />
Expand Down
66 changes: 61 additions & 5 deletions app/(public)/users/[userHandle]/posts/[slug]/comments/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,71 @@
import { Fragment } from 'react';

import { randomInt } from 'crypto';
import { CornerDownRight } from 'lucide-react';

import {
AppBar,
AppBarBack,
AppBarTitle,
} from '@/components/ui-unstable/app-bar';
import { ChatInput } from '@/components/ui-unstable/chat-input';
import { CommentableListItem } from '@/features/comments-page/commentable-list-item';
import { generateCommentsWithReplies } from '@/lib/utils';

type CommentsPageProps = {
params: {
username: string;
userHandle: string;
slug: string;
};
};

const CommentsPage = ({ params: { username, slug } }: CommentsPageProps) => {
const commentWithRepliesCount = randomInt(1, 10);

const commentsWithReplies = generateCommentsWithReplies(
commentWithRepliesCount,
);

const CommentsPage = ({
params: { userHandle: _, slug: __ },
}: CommentsPageProps) => {
return (
<div>
CommentsPage (username: {username}, slug: {slug})
</div>
<>
<AppBar>
<AppBarBack />
<AppBarTitle>댓글</AppBarTitle>
</AppBar>
<div className="flex flex-col gap-2 px-4 pb-20 pt-14">
<div className="h-2" />
{commentsWithReplies.map((commentWithReplies, index) => (
<div key={index}>
<CommentableListItem
username={commentWithReplies.comment.user.username}
handle={commentWithReplies.comment.user.handle}
profileImage={commentWithReplies.comment.user.profileImage}
content={commentWithReplies.comment.content}
/>
<div className="relative ml-10 mt-2 flex flex-col gap-2">
{commentWithReplies.replies.map((reply, index) => (
<Fragment key={index}>
{index === 0 && (
<CornerDownRight className="absolute -left-7 top-2 h-4 w-4 text-blccu-neutral-400" />
)}
<CommentableListItem
username={reply.user.username}
handle={reply.user.handle}
profileImage={reply.user.profileImage}
content={reply.content}
/>
</Fragment>
))}
</div>
</div>
))}
</div>
<div className="fixed bottom-0 mx-auto h-20 w-full max-w-md bg-blccu-white/80 backdrop-blur">
<ChatInput />
</div>
</>
);
};

Expand Down
82 changes: 77 additions & 5 deletions app/(public)/users/[userHandle]/posts/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,87 @@
import Image from 'next/image';

import { EllipsisVertical, Share2 } from 'lucide-react';

import {
AppBar,
AppBarBack,
AppBarTitle,
} from '@/components/ui-unstable/app-bar';
import { CopyCurrentPageTrigger } from '@/components/ui-unstable/copy-current-page-trigger';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { IconButton } from '@/components/ui/icon-button';
import { PostPageAllPostSection } from '@/features/post-page/post-page-all-post-section';
import { PostPageBottomBar } from '@/features/post-page/post-page-bottom-bar';
import { ReportPostBottomActionSheet } from '@/features/post-page/report-post-bottom-action-sheet';
import { UserHandlePageTrendingPostSection } from '@/features/user-handle-page/user-handle-page-trending-post-section';
import { generatePost } from '@/lib/utils';

const post = generatePost();

const { author, thumbnail } = post;

type PostPageProps = {
params: {
username: string;
userHandle: string;
slug: string;
};
};

const PostPage = ({ params: { username, slug } }: PostPageProps) => {
const PostPage = ({ params: { userHandle: _, slug: __ } }: PostPageProps) => {
return (
<div>
PostPage (username: {username}, slug: {slug})
</div>
<>
<AppBar className="border-b-0 bg-blccu-white/90 backdrop-blur-lg">
<AppBarBack />
<div className="item-center flex w-full justify-between">
<AppBarTitle className="flex items-center gap-3">
<Avatar size="xs">
<AvatarImage src={author.profileImage} />
<AvatarFallback className="bg-blccu-neutral-400" />
</Avatar>
<p className="text-sm font-medium">{author.username}</p>
</AppBarTitle>
<ReportPostBottomActionSheet
trigger={
<IconButton size="lg">
<EllipsisVertical className="h-5 w-5" />
</IconButton>
}
/>
</div>
</AppBar>
<div className="pt-14">
<Image
src={thumbnail}
alt="Post thumbnail"
width={1280}
height={2000}
/>
<Image
src={thumbnail}
alt="Post thumbnail"
width={1280}
height={2000}
/>
<div className="flex items-center">
<ReportPostBottomActionSheet
trigger={
<IconButton size="lg">
<EllipsisVertical className="h-5 w-5" />
</IconButton>
}
/>
<CopyCurrentPageTrigger asChild>
<IconButton size="lg">
<Share2 className="h-5 w-5" />
</IconButton>
</CopyCurrentPageTrigger>
</div>
<PostPageAllPostSection user={author} />
<UserHandlePageTrendingPostSection user={author} />
<div className="h-[24px]" />
</div>
<PostPageBottomBar />
</>
);
};

Expand Down
92 changes: 89 additions & 3 deletions app/(signed-in-only)/report/comments/[commentId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,99 @@
'use client';

import { useRouter } from 'next/navigation';

import { type UUID } from 'crypto';
import { toast } from 'sonner';

import {
AppBar,
AppBarBack,
AppBarTitle,
} from '@/components/ui-unstable/app-bar';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Textarea } from '@/components/ui/textarea';
import { TOAST_MESSAGES } from '@/constants/messages';
import { ROUTES } from '@/constants/routes';
import { generatePost } from '@/lib/utils';

const post = generatePost();

const { author, slug } = post;

type ReportCommentIdPageProps = {
params: {
commentId: number;
postId: UUID;
};
};

const ReportCommentIdPage = ({
params: { commentId },
params: { postId: _ },
}: ReportCommentIdPageProps) => {
return <div>ReportCommentIdPage (commentId: {commentId})</div>;
const router = useRouter();

const handleClick = () => {
toast.success(TOAST_MESSAGES.REPORT_COMMENT_SUCCESS);

router.push(ROUTES.COMMENTS_OF(author.handle, slug));
};

return (
<>
<AppBar>
<AppBarBack />
<AppBarTitle>댓글 신고</AppBarTitle>
</AppBar>
<div className="flex h-dvh flex-col justify-between">
<div className="px-4 pt-14">
<RadioGroup defaultValue="spam" className="mt-4">
<Label
htmlFor="r1"
className="flex items-center justify-between py-2"
>
<p className="font-normal">스팸성 댓글</p>
<RadioGroupItem value="spam" id="r1" />
</Label>
<Label
htmlFor="r2"
className="flex items-center justify-between py-2"
>
<p className="font-normal">사기 또는 거짓의 댓글</p>
<RadioGroupItem value="fraud" id="r2" />
</Label>
<Label
htmlFor="r3"
className="flex items-center justify-between py-2"
>
<p className="font-normal">성적인 댓글</p>
<RadioGroupItem value="sexual" id="r3" />
</Label>
<Label
htmlFor="r4"
className="flex items-center justify-between py-2"
>
<p className="font-normal">기타 문제</p>
<RadioGroupItem value="other" id="r3" />
</Label>
</RadioGroup>
<Textarea
className="mt-4"
placeholder="자세한 신고 이유를 작성해주세요."
/>
</div>
<div className="flex w-full gap-2 px-4 pb-4">
<Button
variant="destructive"
className="flex-1"
onClick={handleClick}
>
신고하기
</Button>
</div>
</div>
</>
);
};

export default ReportCommentIdPage;
Loading
Loading