-
Notifications
You must be signed in to change notification settings - Fork 79
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
[이승현] Sprint10 #643
Merged
kiJu2
merged 18 commits into
codeit-bootcamp-frontend:Next.js-이승현
from
codefug:Next.js-이승현-Sprint10
Jun 11, 2024
The head ref may contain hidden characters: "Next.js-\uC774\uC2B9\uD604-Sprint10"
Merged
[이승현] Sprint10 #643
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
e5c356d
chore: prettier, env 환경 세팅, README 세팅
codefug 908d525
fix: 피드백 반영, resize에 debounce 추가
codefug 15c14c8
feat: react-hook-form 적용, board page ui 완성
codefug 29288bc
feat: 상품 등록 페이지 완성
codefug ce27940
feat: 상세 상품 페이지 api 연결
codefug 9dcb981
feat: shadcn을 이용한 dropdown 생성, 상품 상세 페이지 ui 완성
codefug dad5cf5
feat: date diff lib
codefug 5568613
feat: add interception observer area && infinite Scroll with board page
codefug a1e7f94
fix: 순서 변경시 pageSize 변경하는 로직으로 수정 && 댓글창에 infinite Scroll 적용
codefug 1964399
feat: cookie에 accessToken 저장
codefug eacfe3b
feat: token 기반 post 실패..
codefug fbaef61
feat: multipart/form-data
codefug f8c40e4
feat: 게시글 post까지는 완성
codefug 04293b3
feat: refreshToken 로직 추가, accessToken max-age 추가
codefug e5b9e3b
feat: 댓글 등록 기능 추가, 댓글 무한 스크롤 에러 처리, 댓글 추가시 리렌더링 처리
codefug 88cc914
feat: 게시글 추가 후 라우터처리
codefug 19040a9
fix: image 문제 해결
codefug ee1b471
feat: 게시글 좋아요 기능 추가
codefug File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ yarn-error.log* | |
|
||
# local env files | ||
.env*.local | ||
.env | ||
|
||
# vercel | ||
.vercel | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"plugins": ["prettier-plugin-tailwindcss"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"$schema": "https://ui.shadcn.com/schema.json", | ||
"style": "default", | ||
"rsc": false, | ||
"tsx": true, | ||
"tailwind": { | ||
"config": "tailwind.config.ts", | ||
"css": "styles/globals.css", | ||
"baseColor": "slate", | ||
"cssVariables": false, | ||
"prefix": "" | ||
}, | ||
"aliases": { | ||
"components": "@/components", | ||
"utils": "@/lib/utils" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
import * as React from "react" | ||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" | ||
import { Check, ChevronRight, Circle } from "lucide-react" | ||
|
||
import { cn } from "@/lib/utils" | ||
|
||
const DropdownMenu = DropdownMenuPrimitive.Root | ||
|
||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger | ||
|
||
const DropdownMenuGroup = DropdownMenuPrimitive.Group | ||
|
||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal | ||
|
||
const DropdownMenuSub = DropdownMenuPrimitive.Sub | ||
|
||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup | ||
|
||
const DropdownMenuSubTrigger = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & { | ||
inset?: boolean | ||
} | ||
>(({ className, inset, children, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.SubTrigger | ||
ref={ref} | ||
className={cn( | ||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-slate-100 data-[state=open]:bg-slate-100 dark:focus:bg-slate-800 dark:data-[state=open]:bg-slate-800", | ||
inset && "pl-8", | ||
className | ||
)} | ||
{...props} | ||
> | ||
{children} | ||
<ChevronRight className="ml-auto h-4 w-4" /> | ||
</DropdownMenuPrimitive.SubTrigger> | ||
)) | ||
DropdownMenuSubTrigger.displayName = | ||
DropdownMenuPrimitive.SubTrigger.displayName | ||
|
||
const DropdownMenuSubContent = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> | ||
>(({ className, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.SubContent | ||
ref={ref} | ||
className={cn( | ||
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
DropdownMenuSubContent.displayName = | ||
DropdownMenuPrimitive.SubContent.displayName | ||
|
||
const DropdownMenuContent = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Content>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> | ||
>(({ className, sideOffset = 4, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Portal> | ||
<DropdownMenuPrimitive.Content | ||
ref={ref} | ||
sideOffset={sideOffset} | ||
className={cn( | ||
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white p-1 text-slate-950 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
</DropdownMenuPrimitive.Portal> | ||
)) | ||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName | ||
|
||
const DropdownMenuItem = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { | ||
inset?: boolean | ||
} | ||
>(({ className, inset, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Item | ||
ref={ref} | ||
className={cn( | ||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50", | ||
inset && "pl-8", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName | ||
|
||
const DropdownMenuCheckboxItem = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> | ||
>(({ className, children, checked, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.CheckboxItem | ||
ref={ref} | ||
className={cn( | ||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50", | ||
className | ||
)} | ||
checked={checked} | ||
{...props} | ||
> | ||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> | ||
<DropdownMenuPrimitive.ItemIndicator> | ||
<Check className="h-4 w-4" /> | ||
</DropdownMenuPrimitive.ItemIndicator> | ||
</span> | ||
{children} | ||
</DropdownMenuPrimitive.CheckboxItem> | ||
)) | ||
DropdownMenuCheckboxItem.displayName = | ||
DropdownMenuPrimitive.CheckboxItem.displayName | ||
|
||
const DropdownMenuRadioItem = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> | ||
>(({ className, children, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.RadioItem | ||
ref={ref} | ||
className={cn( | ||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-slate-100 focus:text-slate-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-slate-800 dark:focus:text-slate-50", | ||
className | ||
)} | ||
{...props} | ||
> | ||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> | ||
<DropdownMenuPrimitive.ItemIndicator> | ||
<Circle className="h-2 w-2 fill-current" /> | ||
</DropdownMenuPrimitive.ItemIndicator> | ||
</span> | ||
{children} | ||
</DropdownMenuPrimitive.RadioItem> | ||
)) | ||
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName | ||
|
||
const DropdownMenuLabel = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Label>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & { | ||
inset?: boolean | ||
} | ||
>(({ className, inset, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Label | ||
ref={ref} | ||
className={cn( | ||
"px-2 py-1.5 text-sm font-semibold", | ||
inset && "pl-8", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName | ||
|
||
const DropdownMenuSeparator = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator> | ||
>(({ className, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Separator | ||
ref={ref} | ||
className={cn("-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-800", className)} | ||
{...props} | ||
/> | ||
)) | ||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName | ||
|
||
const DropdownMenuShortcut = ({ | ||
className, | ||
...props | ||
}: React.HTMLAttributes<HTMLSpanElement>) => { | ||
return ( | ||
<span | ||
className={cn("ml-auto text-xs tracking-widest opacity-60", className)} | ||
{...props} | ||
/> | ||
) | ||
} | ||
DropdownMenuShortcut.displayName = "DropdownMenuShortcut" | ||
|
||
export { | ||
DropdownMenu, | ||
DropdownMenuTrigger, | ||
DropdownMenuContent, | ||
DropdownMenuItem, | ||
DropdownMenuCheckboxItem, | ||
DropdownMenuRadioItem, | ||
DropdownMenuLabel, | ||
DropdownMenuSeparator, | ||
DropdownMenuShortcut, | ||
DropdownMenuGroup, | ||
DropdownMenuPortal, | ||
DropdownMenuSub, | ||
DropdownMenuSubContent, | ||
DropdownMenuSubTrigger, | ||
DropdownMenuRadioGroup, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,60 @@ | ||
import { formatDate } from "@/shared/lib/formatDate"; | ||
import { Article } from "@/shared/model"; | ||
import { ItemImage } from "@/shared/ui/itemImage"; | ||
import { LikeCount } from "@/shared/ui/LikeCount"; | ||
import Image from "next/image"; | ||
|
||
interface Props { | ||
article: Article; | ||
title: string; | ||
image: string | null; | ||
nickname: string; | ||
likeCount: number; | ||
createdAt: string; | ||
id: number; | ||
} | ||
|
||
export function BestPostCard({ article }: Props) { | ||
export function BestPostCard({ | ||
title, | ||
image, | ||
nickname, | ||
likeCount, | ||
createdAt, | ||
id, | ||
}: Props) { | ||
Comment on lines
+15
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오호 해당 컴포넌트가 사용하는 Props� 들로만 이루어졌군요 ! |
||
return ( | ||
<section className="relative bg-[#f9fafb] h-full rounded-lg px-6 pb-4"> | ||
<header className="w-[103px] h-[30px] relative"> | ||
<section className="relative h-full rounded-lg bg-[#f9fafb] px-6 pb-4"> | ||
<header className="relative h-[30px] w-[103px]"> | ||
<Image | ||
fill | ||
src="/images/bestPostLabel.png" | ||
alt="best Post Label" | ||
className="z-0" | ||
/> | ||
<div className="z-10 absolute left-5 top-2 flex gap-2 h-4 items-center"> | ||
<div className="absolute left-5 top-2 z-10 flex h-4 items-center gap-2"> | ||
<Image width={16} height={16} src="/icons/medal.png" alt="medal" /> | ||
<p className="text-base font-semibold text-white tracking-wide"> | ||
<p className="text-base font-semibold tracking-wide text-white"> | ||
Best | ||
</p> | ||
</div> | ||
</header> | ||
<main className="overflow-hidden"> | ||
<header className="text-lg scrollbar-hide font-semibold flex gap-2 mt-4 h-[72px] overflow-auto"> | ||
{article.title} | ||
<ItemImage imageUrl={article.image} /> | ||
<header className="mt-4 flex h-[72px] gap-2 overflow-auto text-lg font-semibold scrollbar-hide"> | ||
{title} | ||
<ItemImage imageUrl={image} /> | ||
</header> | ||
</main> | ||
<footer className="mt-4 text-sm flex justify-between"> | ||
<header className="flex gap-2 text-[#4b5563] font-normal items-center"> | ||
{article.writer.nickname} | ||
<figure className="flex items-center gap-1"> | ||
<button type="button"> | ||
<Image | ||
src="/icons/heart.png" | ||
alt="heart icon" | ||
width={16} | ||
height={16} | ||
/> | ||
</button> | ||
<div className="text-[#9ca3af]">{article.likeCount}</div> | ||
</figure> | ||
<footer className="mt-4 flex justify-between text-sm"> | ||
<header className="flex items-center gap-2 font-normal text-[#4b5563]"> | ||
{nickname} | ||
<LikeCount | ||
className="flex items-center gap-1" | ||
height={16} | ||
id={id} | ||
likeCount={likeCount} | ||
width={16} | ||
/> | ||
</header> | ||
<footer className="text-[#9ca3af]"> | ||
{formatDate(new Date(article.createdAt))} | ||
{formatDate(new Date(createdAt))} | ||
</footer> | ||
</footer> | ||
</section> | ||
|
Empty file.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호☺️
shadcn/ui
인가욤? 후기가 궁금하네요There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
러닝커브 하나도 없이 적용하면 됐었습니다. shadcn자체에서 무언가를 하기 보다는 시니어 개발자분이 좋은 라이브러리를 활용해서 만든 더 쉬운 라이브러리를 활용하는 기분이었어요! 잘할려면 더 봐야되긴 하겠지만 사용하기 편한것 같습니다 😊