From 126487e69215699196eb848ca64d4df21257a603 Mon Sep 17 00:00:00 2001 From: JS MacBook Pro Date: Fri, 28 Aug 2026 21:12:18 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EA=B0=80=EB=A1=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EC=B9=B4=EB=93=9C=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ui/card-list/card-list.tsx | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/shared/components/ui/card-list/card-list.tsx diff --git a/src/shared/components/ui/card-list/card-list.tsx b/src/shared/components/ui/card-list/card-list.tsx new file mode 100644 index 0000000..87b2217 --- /dev/null +++ b/src/shared/components/ui/card-list/card-list.tsx @@ -0,0 +1,77 @@ +'use client'; + +import { cn } from '@/lib/cn'; +import { BookmarkIcon } from '@/shared/components/icons'; +import { CommonImage } from '@/shared/components/ui/common-image/common-image'; + +interface CardListImage { + src: string; + alt: string; +} + +interface CardListProps { + title: string; + description: string; + images: CardListImage[]; + isBookmarked: boolean; + onBookmarkClick: () => void; + className?: string; +} + +export const CardList = ({ + title, + description, + images, + isBookmarked, + onBookmarkClick, + className, +}: CardListProps) => { + return ( +
+
+
+
+ {title} +
+

+ {description} +

+
+ + +
+ +
+ {images.map(({ src, alt }) => ( + + ))} +
+
+ ); +}; From 94852bcd0634d37b6a00ec00db353a3dd8b84ba7 Mon Sep 17 00:00:00 2001 From: JS MacBook Pro Date: Fri, 28 Aug 2026 21:12:37 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EC=B9=B4=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=8A=A4=EC=BC=88=EB=A0=88=ED=86=A4=20UI?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/card-list/card-list-skeleton.tsx | 37 +++++++++++++++++++ src/shared/components/ui/card-list/index.ts | 2 + src/shared/components/ui/index.ts | 1 + 3 files changed, 40 insertions(+) create mode 100644 src/shared/components/ui/card-list/card-list-skeleton.tsx create mode 100644 src/shared/components/ui/card-list/index.ts diff --git a/src/shared/components/ui/card-list/card-list-skeleton.tsx b/src/shared/components/ui/card-list/card-list-skeleton.tsx new file mode 100644 index 0000000..d14c97a --- /dev/null +++ b/src/shared/components/ui/card-list/card-list-skeleton.tsx @@ -0,0 +1,37 @@ +import { cn } from '@/lib/cn'; + +const SKELETON_IMAGE_KEYS = [1, 2, 3, 4] as const; + +interface CardListSkeletonProps { + className?: string; +} + +export const CardListSkeleton = ({ className }: CardListSkeletonProps) => { + return ( +
+
+
+
+
+
+
+
+
+ +
+ {SKELETON_IMAGE_KEYS.map((imageKey) => ( +
+ ))} +
+
+ ); +}; diff --git a/src/shared/components/ui/card-list/index.ts b/src/shared/components/ui/card-list/index.ts new file mode 100644 index 0000000..1a26620 --- /dev/null +++ b/src/shared/components/ui/card-list/index.ts @@ -0,0 +1,2 @@ +export { CardList } from './card-list'; +export { CardListSkeleton } from './card-list-skeleton'; diff --git a/src/shared/components/ui/index.ts b/src/shared/components/ui/index.ts index f19096a..8962e41 100644 --- a/src/shared/components/ui/index.ts +++ b/src/shared/components/ui/index.ts @@ -15,6 +15,7 @@ export { IconButton, type IconButtonProps } from './button/icon-button'; export { Card } from './card/card'; export { CardDate } from './card/card-date'; export { PostStatusTag, type RecruitmentStatus, Tag } from './card/card-tag'; +export { CardList, CardListSkeleton } from './card-list'; export { Chip, ChipButton } from './chip/chip'; export { ChipGroup, type ChipGroupProps } from './chip-group/chip-group'; export { CommonImage } from './common-image/common-image'; From 23ef3503bd9a7810d11e9702b83bf08a3e154430 Mon Sep 17 00:00:00 2001 From: JS MacBook Pro Date: Fri, 28 Aug 2026 21:31:14 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EC=B9=B4=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=8A=A4=EC=BC=88=EB=A0=88=ED=86=A4=20?= =?UTF-8?q?=EC=9B=A8=EC=9D=B4=EB=B8=8C=20=EC=95=A0=EB=8B=88=EB=A9=94?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/globals.css | 1 + .../ui/card-list/card-list-skeleton.tsx | 8 ++--- src/styles/animations.css | 30 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/styles/animations.css diff --git a/src/app/globals.css b/src/app/globals.css index ef0cae6..d2c0510 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,4 +2,5 @@ @import '../styles/colors.css'; @import '../styles/typography.css'; +@import '../styles/animations.css'; @import '../styles/base.css'; diff --git a/src/shared/components/ui/card-list/card-list-skeleton.tsx b/src/shared/components/ui/card-list/card-list-skeleton.tsx index d14c97a..042832e 100644 --- a/src/shared/components/ui/card-list/card-list-skeleton.tsx +++ b/src/shared/components/ui/card-list/card-list-skeleton.tsx @@ -11,16 +11,16 @@ export const CardListSkeleton = ({ className }: CardListSkeletonProps) => {
-
+
-
+
@@ -28,7 +28,7 @@ export const CardListSkeleton = ({ className }: CardListSkeletonProps) => { {SKELETON_IMAGE_KEYS.map((imageKey) => (
))}
diff --git a/src/styles/animations.css b/src/styles/animations.css new file mode 100644 index 0000000..02a6c92 --- /dev/null +++ b/src/styles/animations.css @@ -0,0 +1,30 @@ +@keyframes skeleton-gradient-wave { + to { + transform: translateX(100%); + } +} + +@utility animate-skeleton-wave { + position: relative; + overflow: hidden; + + &::after { + position: absolute; + inset: 0; + background: linear-gradient( + 100deg, + transparent 20%, + color-mix(in srgb, var(--color-white) 55%, transparent) 50%, + transparent 80% + ); + content: ''; + transform: translateX(-100%); + animation: skeleton-gradient-wave 1.7s linear infinite; + } +} + +@media (prefers-reduced-motion: reduce) { + .animate-skeleton-wave::after { + animation: none; + } +} From 5d775bda754e24abdc20d2ab3e22a932302d9f2c Mon Sep 17 00:00:00 2001 From: JS MacBook Pro Date: Fri, 28 Aug 2026 22:23:39 +0900 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=EC=B9=B4=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A0=9C=EB=AA=A9=20=EB=B0=8F=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=84=B1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/components/ui/card-list/card-list.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/shared/components/ui/card-list/card-list.tsx b/src/shared/components/ui/card-list/card-list.tsx index 87b2217..390a99b 100644 --- a/src/shared/components/ui/card-list/card-list.tsx +++ b/src/shared/components/ui/card-list/card-list.tsx @@ -35,9 +35,9 @@ export const CardList = ({ >
-
+

{title} -

+

{description}

@@ -59,7 +59,12 @@ export const CardList = ({
-
+
{images.map(({ src, alt }) => ( Date: Sat, 29 Aug 2026 15:31:25 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20=EA=B3=B5=ED=86=B5=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=88=EB=A0=88=ED=86=A4=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EC=B9=B4=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ui/card-list/card-list-skeleton.tsx | 14 ++++---------- src/shared/components/ui/index.ts | 1 + src/shared/components/ui/skeleton/skeleton.tsx | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 src/shared/components/ui/skeleton/skeleton.tsx diff --git a/src/shared/components/ui/card-list/card-list-skeleton.tsx b/src/shared/components/ui/card-list/card-list-skeleton.tsx index 042832e..9a3d12c 100644 --- a/src/shared/components/ui/card-list/card-list-skeleton.tsx +++ b/src/shared/components/ui/card-list/card-list-skeleton.tsx @@ -1,4 +1,5 @@ import { cn } from '@/lib/cn'; +import { Skeleton } from '@/shared/components/ui/skeleton/skeleton'; const SKELETON_IMAGE_KEYS = [1, 2, 3, 4] as const; @@ -16,20 +17,13 @@ export const CardListSkeleton = ({ className }: CardListSkeletonProps) => { )} >
-
-
-
-
-
-
+ +
{SKELETON_IMAGE_KEYS.map((imageKey) => ( -
+ ))}
diff --git a/src/shared/components/ui/index.ts b/src/shared/components/ui/index.ts index 8962e41..b3d3408 100644 --- a/src/shared/components/ui/index.ts +++ b/src/shared/components/ui/index.ts @@ -32,6 +32,7 @@ export { ProfileImageInput } from './profile-image-input/profile-image-input'; export { ProgressBar } from './progress-bar/progress-bar'; export { Searchbar, type SearchbarSize } from './searchbar/searchbar'; export { SearchbarWithDropdown } from './searchbar/searchbar-with-dropdown'; +export { Skeleton } from './skeleton/skeleton'; export { Tab } from './tab/tab'; export { TextArea, type TextAreaStatus } from './text-area/text-area'; export { TextField, type TextFieldStatus } from './text-field/text-field'; diff --git a/src/shared/components/ui/skeleton/skeleton.tsx b/src/shared/components/ui/skeleton/skeleton.tsx new file mode 100644 index 0000000..82f4ca0 --- /dev/null +++ b/src/shared/components/ui/skeleton/skeleton.tsx @@ -0,0 +1,14 @@ +import { cn } from '@/lib/cn'; + +interface SkeletonProps { + className?: string; +} + +export const Skeleton = ({ className }: SkeletonProps) => { + return ( +
+ ); +}; From df7e1194089e023bc40a9a2b90e78702c8d83820 Mon Sep 17 00:00:00 2001 From: JS MacBook Pro Date: Sun, 30 Aug 2026 21:53:58 +0900 Subject: [PATCH 6/7] =?UTF-8?q?refactor:=20=EB=B6=81=EB=A7=88=ED=81=AC=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EA=B3=B5=ED=86=B5=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bookmark-container/bookmark-container.tsx | 25 ++++--------- .../post-detail-profile-header.tsx | 21 +++-------- .../ui/bookmark-button/bookmark-button.tsx | 35 +++++++++++++++++++ src/shared/components/ui/index.ts | 1 + 4 files changed, 47 insertions(+), 35 deletions(-) create mode 100644 src/shared/components/ui/bookmark-button/bookmark-button.tsx diff --git a/src/domains/home/components/bookmark-container/bookmark-container.tsx b/src/domains/home/components/bookmark-container/bookmark-container.tsx index a6f8192..7e1fc6c 100644 --- a/src/domains/home/components/bookmark-container/bookmark-container.tsx +++ b/src/domains/home/components/bookmark-container/bookmark-container.tsx @@ -3,7 +3,7 @@ import type { ReactNode } from 'react'; import { cn } from '@/lib/cn'; -import { BookmarkIcon } from '@/shared/components/icons'; +import { BookmarkButton } from '@/shared/components/ui'; type BookmarkOverlayVariant = 'card' | 'summary'; @@ -29,24 +29,11 @@ export const BookmarkContainer = ({
{children} - +
); }; diff --git a/src/domains/posts/components/post-detail-profile-header/post-detail-profile-header.tsx b/src/domains/posts/components/post-detail-profile-header/post-detail-profile-header.tsx index 7f079ba..517ea6d 100644 --- a/src/domains/posts/components/post-detail-profile-header/post-detail-profile-header.tsx +++ b/src/domains/posts/components/post-detail-profile-header/post-detail-profile-header.tsx @@ -8,11 +8,9 @@ import { POST_MUTATION_OPTIONS } from '@/domains/posts/api/query'; import { PostRecruitmentStatusBottomSheet } from '@/domains/posts/components/post-recruitment-status-bottom-sheet/post-recruitment-status-bottom-sheet'; import { PostRecruitmentStatusButton } from '@/domains/posts/components/post-recruitment-status-button/post-recruitment-status-button'; import type { PostRecruitmentStatusTypes } from '@/domains/posts/model/post-recruitment-status'; -import { cn } from '@/lib/cn'; import { POST_QUERY_KEY, RECOMMENDATION_QUERY_KEY } from '@/shared/api'; import { defaultProfileImage } from '@/shared/assets/illustrations'; -import { BookmarkIcon } from '@/shared/components/icons'; -import { useToast } from '@/shared/components/ui'; +import { BookmarkButton, useToast } from '@/shared/components/ui'; import { CommonImage } from '@/shared/components/ui/common-image/common-image'; import { ROUTES } from '@/shared/config'; @@ -146,20 +144,11 @@ export const PostDetailProfileHeader = ({ /> ) : ( - + /> )} ); diff --git a/src/shared/components/ui/bookmark-button/bookmark-button.tsx b/src/shared/components/ui/bookmark-button/bookmark-button.tsx new file mode 100644 index 0000000..b28d331 --- /dev/null +++ b/src/shared/components/ui/bookmark-button/bookmark-button.tsx @@ -0,0 +1,35 @@ +'use client'; + +import { cn } from '@/lib/cn'; +import { BookmarkIcon } from '@/shared/components/icons'; + +interface BookmarkButtonProps { + isBookmarked: boolean; + onClick: () => void; + className?: string; +} + +export const BookmarkButton = ({ + isBookmarked, + onClick, + className, +}: BookmarkButtonProps) => { + return ( + + ); +}; diff --git a/src/shared/components/ui/index.ts b/src/shared/components/ui/index.ts index b3d3408..8a89905 100644 --- a/src/shared/components/ui/index.ts +++ b/src/shared/components/ui/index.ts @@ -8,6 +8,7 @@ export { AsyncLoadingState, type AsyncLoadingStateProps, } from './async-boundary'; +export { BookmarkButton } from './bookmark-button/bookmark-button'; export { BottomActionBar } from './bottom-action-bar/bottom-action-bar'; export { BottomSheet } from './bottom-sheet/bottom-sheet'; export { Button, type ButtonProps } from './button/button'; From 7e4f17352128e85d86248b1783e1dc052e0300ef Mon Sep 17 00:00:00 2001 From: JS MacBook Pro Date: Sun, 30 Aug 2026 21:54:22 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=EC=B9=B4=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=83=81=EC=84=B8=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ui/card-list/card-list.tsx | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/shared/components/ui/card-list/card-list.tsx b/src/shared/components/ui/card-list/card-list.tsx index 390a99b..099a36b 100644 --- a/src/shared/components/ui/card-list/card-list.tsx +++ b/src/shared/components/ui/card-list/card-list.tsx @@ -1,7 +1,9 @@ 'use client'; +import Link from 'next/link'; + import { cn } from '@/lib/cn'; -import { BookmarkIcon } from '@/shared/components/icons'; +import { BookmarkButton } from '@/shared/components/ui/bookmark-button/bookmark-button'; import { CommonImage } from '@/shared/components/ui/common-image/common-image'; interface CardListImage { @@ -15,6 +17,7 @@ interface CardListProps { images: CardListImage[]; isBookmarked: boolean; onBookmarkClick: () => void; + href?: string; className?: string; } @@ -24,8 +27,18 @@ export const CardList = ({ images, isBookmarked, onBookmarkClick, + href, className, }: CardListProps) => { + const information = ( + <> +

{title}

+

+ {description} +

+ + ); + return (
-
-

- {title} -

-

- {description} -

-
+ {href ? ( + + {information} + + ) : ( +
+ {information} +
+ )} - + />