feat: 프로필 이미지(avatarUrl) 필드 + UserAvatar 도입, 색상·이니셜 아바타 제거
- 백엔드: User.avatarUrl(nullable) 추가 → PublicUser/toPublic 로 모든 유저 응답에 노출. - 프론트: 공용 UserAvatar(이미지 있으면 img, 없으면 사람 실루엣 placeholder)로 전 화면 아바타 통일(상단바·저장소·멤버·담당자·활동·내업무·댓글·AI패널). 화면마다 달랐던 색상+이니셜/하드코딩 청록 아바타 제거. - 죽은 코드 정리: 색상·이니셜 시스템(avatarColor/initialOf/AvatarColor 유틸·타입, User/RepoActivityItem 의 initial/color, 전역·컴포넌트 .av-a~.av-f CSS) + 미사용 정적 목업 데이터(USERS/REPOS/REPO_TASKS/TASK_DETAIL/MY_TASKS_*/REPO_MEMBERS/ REPO_ACTIVITY 등) 전부 삭제. relay.mock.ts 는 뷰 타입 + countActive 만 유지. avatar_url 컬럼은 dev synchronize 가 추가. 업로드(실제 사진 설정)는 추후 단계. 검증: 백엔드 build 0, 프론트 type-check/lint/build 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
// 저장소 헤더 카드 — 상세/멤버/활동/설정 화면이 공유
|
||||
import { computed } from 'vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
import type { Repo, User } from '@/mock/relay.mock'
|
||||
|
||||
interface Props {
|
||||
@@ -109,8 +110,10 @@ const extra = computed(() => props.moreCount ?? props.repo.moreCount)
|
||||
v-for="m in avatars"
|
||||
:key="m.id"
|
||||
class="avatar"
|
||||
:class="m.color"
|
||||
>{{ m.initial }}</span>
|
||||
><UserAvatar
|
||||
:url="m.avatarUrl"
|
||||
:name="m.name"
|
||||
/></span>
|
||||
<span
|
||||
v-if="extra > 0"
|
||||
class="avatar av-more"
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
// 공용 사용자 아바타 — 프로필 이미지가 있으면 이미지를, 없으면 사람 실루엣 placeholder 를 표시.
|
||||
// (색상+이니셜 방식은 폐기) 크기/모양은 부모의 사이징 래퍼가 정하고, 이 컴포넌트는 그 안을 채운다.
|
||||
interface Props {
|
||||
url?: string | null // 프로필 이미지 URL (없으면 placeholder)
|
||||
name?: string // 이미지 대체 텍스트(접근성)
|
||||
}
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="user-avatar">
|
||||
<img
|
||||
v-if="url"
|
||||
class="ua-img"
|
||||
:src="url"
|
||||
:alt="name || '프로필 이미지'"
|
||||
>
|
||||
<svg
|
||||
v-else
|
||||
class="ua-ph"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<!-- 사람 실루엣(빈 프로필 placeholder) -->
|
||||
<path d="M12 12.5a4.25 4.25 0 1 0 0-8.5 4.25 4.25 0 0 0 0 8.5Z" />
|
||||
<path d="M4.5 19.25c0-3.04 3.36-5 7.5-5s7.5 1.96 7.5 5v.75H4.5v-.75Z" />
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.user-avatar {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #e5e7eb; /* placeholder 배경(중립 회색) */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ua-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.ua-ph {
|
||||
width: 64%;
|
||||
height: 64%;
|
||||
color: #9aa1ac; /* placeholder 아이콘 색 */
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user