Skip to content
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
8 changes: 4 additions & 4 deletions app/components/HomeMissionPopup.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<template>
<!-- 미션 완료/레벨업 팝업 카드: 왕관(아래→위 상승) + confetti + 메시지 + 확인 -->
<div class="relative w-full max-w-[300px] mx-auto pt-[46px]">
<!-- 왕관 (카드 위로 솟으며 상승) -->
<div class="relative w-full max-w-[300px] mx-auto pt-[60px]">
<!-- 왕관 (카드 위로 솟으며 상승) — SVG 뷰박스(82×60) 비율 유지, 하단이 카드 윗면과 맞닿음 -->
<img
:src="`/icons/levels/lv-${level}.svg`"
:alt="`레벨 ${level} 달성`"
class="crown-rise absolute top-0 left-1/2 w-[84px] h-[84px] z-10"
class="crown-rise absolute top-0 left-1/2 w-[82px] h-[60px] z-10"
/>
<!-- 카드 -->
<div class="popup-pop bg-white rounded-2xl px-5 pt-[56px] pb-5 flex flex-col items-center gap-[14px] shadow-[0_4px_20px_0_rgba(0,0,0,0.1)]">
<div class="popup-pop bg-white rounded-2xl px-5 pt-7 pb-5 flex flex-col items-center gap-[14px] shadow-[0_4px_20px_0_rgba(0,0,0,0.1)]">
<!-- 문구 블록 하단 12px + 카드 gap 14px = 버튼과 26px 간격 (피그마) -->
<div class="flex flex-col items-center gap-2 pb-3">
<p class="text-[17px] font-semibold text-grey-13 text-center tracking-[-0.02em]" style="line-height:140%">
Expand Down
8 changes: 4 additions & 4 deletions app/components/RetrospectProjectSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<div class="flex-1 min-h-0 overflow-y-auto scrollbar-hide px-5">
<div class="flex flex-col items-center">
<!-- 자유 회고 (프로젝트 없음) -->
<button class="flex gap-[14px] items-center w-full py-[11px]" @click="selectFree">
<button class="flex gap-[14px] items-center w-full h-[46px]" @click="selectFree">
<img :src="checkSrc(selectedId === null && !adding)" alt="" class="w-6 h-6 shrink-0" />
<span class="text-body3 font-medium text-left">
<span class="text-grey-13">자유 회고</span>
Expand All @@ -26,23 +26,23 @@
<button
v-for="p in projects"
:key="p.id"
class="flex gap-[14px] items-center w-full py-[11px]"
class="flex gap-[14px] items-center w-full h-[46px]"
@click="selectProject(p.id)"
>
<img :src="checkSrc(selectedId === p.id && !adding)" alt="" class="w-6 h-6 shrink-0" />
<span class="text-body3 font-medium text-grey-13 text-left">{{ p.name }}</span>
</button>

<!-- 새 프로젝트 입력 (초록 체크 = 선택됨, 포커스 시 하단 보더 — /projects와 동일) -->
<div v-if="adding" class="flex gap-[14px] items-center w-full py-[11px]">
<div v-if="adding" class="flex gap-[14px] items-center w-full h-[46px]">
<img src="/icons/check-circle-on.svg" alt="" class="w-6 h-6 shrink-0" />
<div class="flex-1 min-w-0 self-stretch flex items-center border-b border-transparent focus-within:border-grey-5 transition-colors">
<input
ref="newProjectEl"
v-model="newProjectName"
maxlength="15"
placeholder="프로젝트 이름을 입력하세요"
class="w-full bg-transparent text-label1 text-grey-13 placeholder:text-[15px] placeholder:font-normal placeholder:text-grey-7 outline-none py-1"
class="w-full bg-transparent text-body3 font-medium text-grey-13 placeholder:text-[15px] placeholder:font-normal placeholder:text-grey-7 outline-none py-1"
@keydown.enter="onNewProjectEnter"
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/components/RetrospectTagEdit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
</span>
</button>
<button class="shrink-0" aria-label="태그 삭제" @click="askDelete(tag)">
<img src="/icons/close-sharp.svg" alt="삭제" class="w-[18px] h-[18px]" />
<img src="/icons/trash.svg" alt="삭제" class="w-[18px] h-[18px]" />
</button>
</div>
</div>
Expand Down
22 changes: 11 additions & 11 deletions app/pages/home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@
<p class="text-[14px] font-medium text-grey-7 leading-[1.4] tracking-[-0.02em] mt-[3px]">제안 받은 피드백을 업무에 적용해보세요</p>
<div class="mt-3.5 bg-white rounded-[18px] px-5 py-[22px] flex flex-col gap-[14px]">
<template v-for="(r, i) in recentList" :key="r.id">
<button class="flex items-center gap-3 text-left w-full" @click="navigateTo(`/retrospects/${r.id}`)">
<button class="flex items-center gap-3 text-left w-full" @click="navigateTo(`/retrospects/${r.id}?from=home`)">
<div class="shrink-0 w-[42px] h-[42px] rounded-[10px] bg-grey-4 flex items-center justify-center">
<span class="text-[12px] font-semibold text-grey-7 leading-[1.36] tracking-[-0.02em]">{{ r.completedAt ? formatDate(r.completedAt) : '' }}</span>
</div>
<div class="flex-1 min-w-0 flex flex-col gap-1">
<!-- 상단: 피드백 (최대 2줄) -->
<p class="text-[15px] font-medium text-grey-13 leading-[1.5] tracking-[-0.02em] line-clamp-2">{{ r.summary || r.title }}</p>
<!-- 상단: 다음 행동 제안 요약구 (최대 2줄) -->
<p class="text-[15px] font-medium text-grey-13 leading-[1.5] tracking-[-0.02em] line-clamp-2">{{ r.nextAction || r.title }}</p>
<!-- 하단: 프로젝트명 · 회고제목 (자유회고는 제목만) -->
<div class="flex items-center gap-[5px]">
<template v-if="r.projectName">
Expand Down Expand Up @@ -221,11 +221,11 @@ const greetingMessage = computed(() =>

function formatDate(dateStr: string): string {
const d = parseServerDate(dateStr)
return `${String(d.getMonth() + 1).padStart(2, '0')}/${String(d.getDate()).padStart(2, '0')}`
return `${d.getMonth() + 1}/${d.getDate()}`
}

// 최근 회고 최대 3개 — 피드백 슬라이더(요약 있는 것)와 최근 회고 리스트에 사용
const topFeedbacks = computed(() => recentRetrospectives.value.filter((r) => r.summary).slice(0, 3))
// 최근 회고 최대 3개 — 피드백 슬라이더(다음 행동 제안 있는 것)와 최근 회고 리스트에 사용
const topFeedbacks = computed(() => recentRetrospectives.value.filter((r) => r.nextAction).slice(0, 3))
const recentList = computed(() => recentRetrospectives.value.slice(0, 5))

// 피드백 캐러셀 (transform 방식 — 모든 카드 좌측 정렬 + 우측 peek, 마우스/터치 드래그)
Expand Down Expand Up @@ -313,14 +313,14 @@ onUnmounted(() => setBadgeBannerHold(false))
// 레벨업 축하 메시지 (백엔드 PopupStatus에 문구가 없어 프론트에서 매핑)
const LEVEL_UP_MESSAGES: Record<number, string> = {
2: '한 주 동안 꾸준히 회고를 작성했네요.\n작은 기록이 좋은 습관의 시작이 될 수 있어요.',
3: '꾸준히 기록하는 습관이 만들어졌네요.\n다음 회고도 차근차근 이어가 보세요.',
3: '꾸준히 기록하는 습관이 만들어졌어요.\n다음 회고도 차근차근 이어가 보세요.',
4: '3번의 회고를 작성했어요.\n계속해서 나만의 회고 루틴을 이어가 보세요.',
5: '꾸준히 기록하는 습관이 만들어졌네요.\n다음 회고도 차근차근 이어가 보세요.',
5: '꾸준히 기록하는 습관이 만들어졌어요.\n다음 회고도 차근차근 이어가 보세요.',
6: '5번의 회고를 작성했어요.\n기록하는 습관이 조금씩 자리를 잡고 있어요.',
7: '꾸준히 기록하는 습관이 만들어졌네요.\n다음 회고도 차근차근 이어가 보세요.',
7: '꾸준히 기록하는 습관이 만들어졌어요.\n다음 회고도 차근차근 이어가 보세요.',
8: '7번의 회고를 작성했어요.\n꾸준히 쌓아온 기록이 성장의 기반이 돼요.',
9: '꾸준히 기록하는 습관이 만들어졌네요.\n다음 회고도 차근차근 이어가 보세요.',
10: '10번의 회고를 작성하고 최고 레벨에 도달했어요.\n앞으로도 꾸준히 회고를 남겨보세요!',
9: '꾸준히 기록하는 습관이 만들어졌어요.\n다음 회고도 차근차근 이어가 보세요.',
10: '10번의 회고를 작성했어요.\n최고 레벨에 도달했어요. 앞으로도 꾸준히 회고를 남겨보세요!',
}
const levelUpMessage = computed(() => LEVEL_UP_MESSAGES[mission.value?.currentLevel ?? 0] ?? '미션을 완료했어요!')

Expand Down
6 changes: 3 additions & 3 deletions app/pages/projects/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<li
v-for="(project, index) in localProjects"
:key="project.id ?? `new-${index}`"
class="flex items-center px-5 h-[54px] bg-white"
class="flex items-center px-5 h-[46px] bg-white"
>
<!-- 삭제 버튼 -->
<button class="shrink-0 mr-3" @click="requestDelete(project)">
Expand All @@ -59,14 +59,14 @@
type="text"
maxlength="15"
:placeholder="project.isNew ? '프로젝트 이름을 입력하세요' : ''"
class="w-full bg-transparent text-label1 text-grey-13 placeholder:text-[15px] placeholder:font-normal placeholder:text-[#989898] outline-none py-1"
class="w-full bg-transparent text-body3 font-medium text-grey-13 placeholder:text-[15px] placeholder:font-normal placeholder:text-[#989898] outline-none py-1"
@focus="focusedIndex = index"
@blur="onInputBlur(project, index)"
@keydown.enter.prevent="inputRefs[index]?.blur()"
/>
<span
v-else
class="w-full text-label1 text-grey-13 py-1 cursor-text"
class="w-full text-body3 font-medium text-grey-13 py-1 cursor-text"
@click="startEditing(project, index)"
>{{ project.name }}</span>
</div>
Expand Down
7 changes: 6 additions & 1 deletion app/pages/retrospects/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="h-full bg-grey-1 flex flex-col">
<!-- 헤더 -->
<div class="flex items-center justify-between h-[50px] px-5 shrink-0">
<button class="p-1 -ml-1" aria-label="뒤로" @click="navigateTo('/retrospects')">
<button class="p-1 -ml-1" aria-label="뒤로" @click="goBack">
<img src="/icons/back.svg" alt="뒤로" class="w-6 h-6" />
</button>

Expand Down Expand Up @@ -135,6 +135,11 @@ const { show } = useToast()
const { track } = useAmplitude()

const id = computed(() => String(route.params.id))

// 진입점에 따라 뒤로가기 목적지 결정 — 홈에서 들어오면 홈, 그 외(목록/검색 등)는 회고 목록
function goBack() {
navigateTo(route.query.from === 'home' ? '/home' : '/retrospects')
}
const detail = ref<RetrospectiveDetail | null>(null)
const isLoading = ref(true)
const authFailed = ref(false) // 인증 만료 시 에러 화면 대신 로그인 리다이렉트(인터셉터)
Expand Down
2 changes: 1 addition & 1 deletion app/pages/retrospects/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
<ul class="flex flex-col px-5 py-3">
<template v-for="group in groupedRetrospects" :key="group.label || 'this-week'">
<!-- 주 단위 디바이더 (이번 주는 미표시) -->
<li v-if="group.label" class="relative flex items-center justify-center py-3">
<li v-if="group.label" class="relative flex items-center justify-center py-6">
<!-- 전체 폭 구분선 (라벨이 bg-background로 가운데를 가림) -->
<span class="absolute inset-x-0 h-px bg-grey-5" aria-hidden="true" />
<span class="relative bg-background px-5 text-caption1 font-medium text-grey-7">{{ group.label }}</span>
Expand Down
3 changes: 2 additions & 1 deletion app/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ export interface HomeResponse {
export interface RecentRetrospective {
id: string
title: string | null
summary: string | null
// 홈 "최근 제안 받은 행동" 카드는 회고 요약이 아니라 다음 행동 제안 요약구를 노출
nextAction: string | null
completedAt: string | null
projectName: string | null
tags: Tag[]
Expand Down
26 changes: 8 additions & 18 deletions public/badges/first-record.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading