diff --git a/package-lock.json b/package-lock.json index 9822503..01c307f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9987,6 +9987,17 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "name": "rolldown-vite", "version": "7.1.14", diff --git a/src/assets/icons/ghost.svg b/src/assets/icons/ghost.svg new file mode 100644 index 0000000..c683167 --- /dev/null +++ b/src/assets/icons/ghost.svg @@ -0,0 +1,45 @@ + + + Entertainment Events Hobbies Horror Ghost Streamline Icon: https://streamlinehq.com + + entertainment-events-hobbies-horror-ghost + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/Avatar/Avatar.tsx b/src/components/Avatar/Avatar.tsx new file mode 100644 index 0000000..304a495 --- /dev/null +++ b/src/components/Avatar/Avatar.tsx @@ -0,0 +1,25 @@ +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; + +import Ghost from "@/assets/icons/ghost.svg?react"; + +export interface AvatarProps extends Omit, "src"> { + src?: string | null; +} + +export default function Avatar({ src, alt = "사용자 아바타", className, ...props }: AvatarProps) { + return ( +
+ {src ? ( + {alt} + ) : ( + + )} +
+ ); +} diff --git a/src/features/friends/list/List.tsx b/src/features/friends/list/List.tsx index 69aba57..7d679c3 100644 --- a/src/features/friends/list/List.tsx +++ b/src/features/friends/list/List.tsx @@ -1,6 +1,7 @@ import { Home, UserMinus2 } from "lucide-react"; import { useEffect, useState } from "react"; +import Avatar from "@/components/Avatar/Avatar"; import Button from "@/components/Button/Button"; import BevelScrollContainer from "@/components/Container/BevelScrollContainer"; import { useAuthStore } from "@/stores/useAuthStore"; @@ -62,12 +63,8 @@ export default function List() { return (
  • -
    - 프로필 아바타 +
    +
    {profile.nickname} diff --git a/src/features/friends/request/Request.tsx b/src/features/friends/request/Request.tsx index 5e98126..a2f15a8 100644 --- a/src/features/friends/request/Request.tsx +++ b/src/features/friends/request/Request.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from "react"; +import Avatar from "@/components/Avatar/Avatar"; import Button from "@/components/Button/Button"; import BevelScrollContainer from "@/components/Container/BevelScrollContainer"; import { useAuthStore } from "@/stores/useAuthStore"; @@ -59,13 +60,8 @@ export default function Request() { {requests.map((request) => (
  • -
    - 프로필 아바타 +
    +
    diff --git a/src/features/friends/search/Search.tsx b/src/features/friends/search/Search.tsx index 4cb131d..45e1073 100644 --- a/src/features/friends/search/Search.tsx +++ b/src/features/friends/search/Search.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from "react"; +import Avatar from "@/components/Avatar/Avatar"; import Button from "@/components/Button/Button"; import BevelScrollContainer from "@/components/Container/BevelScrollContainer"; import Input from "@/components/Input/Input"; @@ -75,13 +76,8 @@ export default function Search() { {results.map((Profile) => (
  • -
    - 프로필 아바타 +
    +
    {Profile.nickname} diff --git a/src/features/minihome/gallery/GalleryDetailPanel.tsx b/src/features/minihome/gallery/GalleryDetailPanel.tsx index bbeb174..a3b34a1 100644 --- a/src/features/minihome/gallery/GalleryDetailPanel.tsx +++ b/src/features/minihome/gallery/GalleryDetailPanel.tsx @@ -3,6 +3,7 @@ import { ChevronLeft, Heart, Send, X } from "lucide-react"; import { useEffect, useState } from "react"; import { twMerge } from "tailwind-merge"; +import Avatar from "@/components/Avatar/Avatar"; import Button from "@/components/Button/Button"; import Input from "@/components/Input/Input"; import { useAuthStore } from "@/stores/useAuthStore"; @@ -304,22 +305,13 @@ export default function GalleryDetailPanel({ comments.map((comment) => { const nickname = comment.author?.nickname ?? "알 수 없음"; const avatar = comment.author?.avatar_url; - const fallbackInitial = nickname.charAt(0); const body = stringifyCommentContent(comment.content); return (
    - {avatar ? ( - {`${nickname} - ) : ( - fallbackInitial - )} +
    diff --git a/src/features/minihome/home/HomePage.tsx b/src/features/minihome/home/HomePage.tsx index 050d383..0e62d6e 100644 --- a/src/features/minihome/home/HomePage.tsx +++ b/src/features/minihome/home/HomePage.tsx @@ -1,8 +1,9 @@ import dayjs from "dayjs"; -import { MessageCircle, UserRound, Star } from "lucide-react"; +import { MessageCircle, Star } from "lucide-react"; import { useEffect, useState, type Dispatch, type SetStateAction } from "react"; import { twMerge } from "tailwind-merge"; +import Avatar from "@/components/Avatar/Avatar"; import { useAuthStore } from "@/stores/useAuthStore"; import type { Database } from "@/types/database.types"; import type { MiniHomeTabs } from "@/types/minihome.types"; @@ -205,21 +206,12 @@ export default function HomePage({ }; return ( -
    +
    {/* 왼쪽 프로필 영역 */}
    {/* 프로필 이미지 */} -
    - {avatarUrl ? ( -
    - -
    - ) : ( -
    - -
    - )} -
    + + {/* 이름 */}

    {nickname}

    diff --git a/src/features/minihome/post/detail/CommentItem.tsx b/src/features/minihome/post/detail/CommentItem.tsx index 67e0716..c59faec 100644 --- a/src/features/minihome/post/detail/CommentItem.tsx +++ b/src/features/minihome/post/detail/CommentItem.tsx @@ -1,8 +1,9 @@ import dayjs from "dayjs"; import "dayjs/locale/ko"; import relativeTime from "dayjs/plugin/relativeTime"; -import { Trash, User } from "lucide-react"; +import { Trash } from "lucide-react"; +import Avatar from "@/components/Avatar/Avatar"; import { useAuthUser } from "@/hooks/useAuthUser"; import type { CommentWithProfile } from "@/types/post.types"; @@ -24,13 +25,7 @@ export default function CommentItem({ comment, onDelete, isMyHome }: CommentItem return (
    - {avatarUrl ? ( - {authorName} - ) : ( -
    - -
    - )} +