Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
94c4211
fix: 공용 모달·결과 화면 설명의 줄바꿈이 무시되는 문제 수정
xeoxxn Oct 8, 2026
5a87bd5
chore: 학생회비 송금 플로우 에셋과 색상 토큰 추가
xeoxxn Oct 8, 2026
f5f4c18
feat: 학생회비 계좌 송금 플로우 화면 구현
xeoxxn Oct 8, 2026
d9fbf5b
fix: 캡처 예시 이미지를 고해상도로 교체하고 타이포 variant 수정
xeoxxn Oct 8, 2026
7a6cceb
feat: 토스 송금 딥링크 연결
xeoxxn Oct 8, 2026
d4c6db2
Revert "feat: 토스 송금 딥링크 연결"
xeoxxn Oct 8, 2026
e637bd3
fix: 캡처 예시 카드가 375px 밖에서 그림이 잘리던 문제 수정
xeoxxn Oct 8, 2026
966e826
docs: 송금 플로우 일러스트의 미구현 모션을 코드에 명시
xeoxxn Oct 8, 2026
9ef1160
feat: 송금 플로우 일러스트에 Lottie 모션 적용
xeoxxn Oct 8, 2026
b02d9fd
Merge branch 'main' into feat/#105-fee-transfer-flow
xeoxxn Oct 27, 2026
7e88fd6
refactor: 학생회비 송금 플로우를 useFunnel 퍼널 하나로 묶음
xeoxxn Oct 27, 2026
0de9b62
docs: 계좌 송금 퍼널 구조와 File을 context에 담은 이유 기록
xeoxxn Oct 27, 2026
3120451
Merge branch 'main' into feat/#105-fee-transfer-flow
xeoxxn Oct 27, 2026
af6fe47
fix: 토스 열림 판정과 퍼널 탈출 히스토리 처리 수정
xeoxxn Oct 27, 2026
e77e3fd
refactor: 외부 링크 여는 처리를 lib로 모으고 단계는 콜백만 받게
xeoxxn Oct 27, 2026
03dfdea
refactor: 캡처 파일을 퍼널 context 한곳에서만 들고 있게
xeoxxn Oct 27, 2026
661a2d1
fix: 플로우로 바로 들어왔을 때 첫 단계 뒤로가기가 먹통이던 문제 수정
xeoxxn Oct 27, 2026
f92203e
refactor: 송금 플로우의 px 임의값을 Tailwind 단계로 바꿈
xeoxxn Oct 27, 2026
7a6cfb5
fix: 캡처 미리보기를 열어도 초점이 뒤 화면에 남던 문제 수정
xeoxxn Oct 27, 2026
4fe6126
feat: 홈에서 학생회비 계좌 송금 플로우로 진입
xeoxxn Oct 27, 2026
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
50 changes: 50 additions & 0 deletions docs/conventions/wds-component-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -746,3 +746,53 @@ Figma 프레임의 상태 표시줄(54px)과 홈 바(34px)는 앱 셸 몫이라
### 로그인·가입은 useFunnel 퍼널 하나(`AuthSignupScreen`)다

로그인 → 연락처 → 약관 동의 → 약관 상세 → 가입 완료를 `@use-funnel/react-router-dom`의 `useFunnel`로 묶었다(라우트 `/auth`, 단계는 `?auth.step=`). 퍼널 파일(`AuthSignupScreen.tsx`)은 단계 전환(어느 단계에서 어디로, 무슨 값을 넘기는지)만 맡고, 단계 화면은 `features/auth/steps/`에 파일 하나씩(`AuthLoginStep`, `AuthPhoneStep`, `AuthTermsStep`, `AuthTermsDetailStep`, `AuthCompleteStep`) 나눠 두며 전환은 콜백 prop으로 받는다. 단계·context 타입과 `guard`는 `constants/authSignupFunnel.ts`, 단계 화면이 함께 쓰는 뒤로가기 버튼·하단 버튼은 `components/`(`AuthBackButton`, `AuthBottomAction`)에 있다. 단계 사이에 넘기는 이름·연락처·약관 동의는 퍼널 context가 들고 있어서, 약관 상세(`history.push`)를 다녀와도 동의 상태가 유지된다(별도 저장소·navigate state 불필요). 동의 체크나 연락처 입력은 단계를 바꾸지 않고 `history.replace`로 context만 갈아 끼운다(히스토리가 늘지 않음). 앞 단계 값이 없이 중간 단계로 들어오면(새로고침·주소 직접 입력) 각 단계의 `guard`가 걸러서 로그인으로 돌려보낸다. 단계가 바뀌는 이동(`push`, 가입 완료로의 `replace`)에는 슬라이드(View Transition)를 켜고, 체크·연락처 입력처럼 context만 갈아 끼우는 `replace`에는 켜지 않는다. 라이브러리 기본 `useFunnel`은 옵션 이름을 `unstable_viewTransition`으로 넘기는데 React Router 7.18은 `viewTransition`만 알아서(소스에 이전 이름이 없다) 슬라이드가 무시된다. 그래서 `src/lib/useFunnel.ts`에 같은 라우터 어댑터를 `createUseFunnel`로 직접 만들고 옵션 이름만 바꿨다(라이브러리의 "라우터 직접 만들기" 가이드 방식) — 라이브러리를 올릴 때 이 이름이 고쳐졌는지 확인하고 고쳐졌다면 이 파일을 지운다.

## 학생회비 계좌 송금 플로우(`3562:162833` 외 5종) 구현 중 확정된 매핑

| Figma 인스턴스 | 코드 | 확정 근거 |
|---|---|---|
| `Textinput/Textfield` | `TextField`(`@wanteddev/wds`) | 메인 컴포넌트 Node ID `445:8591` + [공식 문서](https://montage.wanted.co.kr/docs/components/selection-and-input/text-field/design). 남은 학기 수 입력칸(`3562:162844`)이 335×48·radius 12px로 실측 일치 |
| `Icon/Normal/Upload` | `IconUpload`(`@wanteddev/wds-icon`) | 메인 컴포넌트 Node ID `3716:22984`("내용을 업로드할 때 사용합니다") |
| `Icon/Normal/Trash` | `IconTrash`(`@wanteddev/wds-icon`) | 메인 컴포넌트 Node ID `3562:162692`("내용을 삭제할 때 사용합니다") |
| `Modal`(`3562:162972`) | 공용 `ConfirmModal` | 311×190·radius 24px·버튼 2개로 기존 `Modal`(`995:34701`)과 같은 인스턴스다 |

### `Image Upload Button`은 WDS가 아니다

업로드 버튼(`3716:23609`, 335×46·radius 10px·1px `Line/Normal/Neutral` 테두리 + primary 라벨)은
`search_design_system`에 같은 모양이 없다. 안쪽 아이콘만 WDS `Icon/Normal/Upload`고 껍데기는 Stream
로컬이다 — WDS `Button`의 outlined는 radius·높이가 달라서 쓰지 않았다.

### 파일 행 아이콘(`fa7-solid:image`)도 WDS가 아니다

업로드한 파일 행의 28px 이미지 아이콘(`3562:162924`)은 이름 그대로 FontAwesome 글리프다. WDS
`IconImage`는 외곽선 스타일이라 **이름은 비슷해도 모양이 달라서** SVG를 받아
`src/assets/icons/fee/image-file.svg`로 커밋했다.

### 48px 일러스트는 `export`로 받고 캔버스 배경을 걷어내야 한다

`Won Icon`(`3562:163032`)·`Send Fast Icon`(`3562:162980`)은 `svgAssets`가 레이어별로 쪼개져 나와
`download_assets`의 `export`(format `svg`)를 써야 한다. 그때 붙는 `<rect fill="#EFEFEF">`와 캔버스
전체를 덮는 `<g id="UI">` 조상 path들을 지우고 아이콘 그룹만 남겼다(사물함 유의사항 일러스트와 같은 처리).

### 송금 확인 화면의 Sub Action은 `ActionArea variant="strong"`이다

주 버튼 아래 텍스트 버튼을 세로로 쌓는 배치(`3562:162974`)는 WDS가 `variant="strong"`일 때만
`flex-direction: column` + `gap: 8px`가 된다(기본값은 가로 12px). 다만 `ActionAreaButton variant="sub"`가
세로 margin 8px을 따로 갖고 있어 그대로 두면 간격이 16px이 되므로 `sx`로 `marginBlock: 0`을 준다.
높이도 Figma가 44px인데 WDS는 28px이라 `paddingBlock: "12px"`로 보정한다.

### 카드 테두리를 `border`로 그리면 안쪽 폭이 2px 깎인다

업로드한 이미지 카드(`3562:162918`)는 Figma에서 335×104 안에 303px 행이 들어간다. CSS `border`는
`box-sizing: border-box` 때문에 가로·세로를 각각 2px씩 먹어서 333/102가 된다 — `outline-1`
`-outline-offset-1`로 그려야 Figma 수치와 맞는다.

### 계좌 송금은 useFunnel 퍼널 하나(`FeeTransferScreen`)다

남은 학기 수 → 학점이수현황 캡처 → 토스 이동 → 송금 확인 → 확인요청 완료를 `@use-funnel/react-router-dom`의 `useFunnel`로 묶었다(라우트 `/fee/transfer`, 단계는 `?fee.step=`). 로그인·가입 퍼널(`AuthSignupScreen`)과 같은 구성이다 — 퍼널 파일(`FeeTransferScreen.tsx`)은 단계 전환만 맡고, 단계 화면은 `features/fee/steps/`에 파일 하나씩(`FeeTransferSemesterStep`, `FeeTransferTranscriptStep`, `FeeTransferTossStep`, `FeeTransferConfirmStep`, `FeeTransferCompleteStep`) 두며 전환은 콜백 prop으로 받는다. 단계·context 타입과 `guard`는 `constants/feeTransferFunnel.ts`에 있고, 단계 화면이 공유하는 뼈대는 `components/FeeTransferStepLayout.tsx`다(뒤로가기는 `onBack` prop으로 받아서 첫 단계는 플로우 밖으로, 나머지는 이전 단계로 간다).

처음에는 단계마다 라우트를 따로 뒀는데(`/fee/transfer/semester` 등 5개), 그러면 단계 사이에 값을 navigate state로 넘겨야 해서 남은 학기 수가 캡처 단계에서 읽히지 않고 고른 파일도 다음 단계로 넘어가지 않았다. 퍼널 context로 바꾸면서 두 값이 플로우 끝까지 이어지고, 토스 단계에서 뒤로 돌아와도 입력이 남는다. 학기 수 입력·파일 선택은 단계를 바꾸지 않고 `history.replace`로 context만 갈아 끼운다(히스토리가 늘지 않음). 앞 단계 값 없이 중간 단계로 들어오면(새로고침·주소 직접 입력) `guard`가 걸러서 첫 단계로 돌려보낸다.

캡처 이미지는 `File`을 context에 그대로 담는다 — `File`은 구조화 복제가 되는 값이라 history.state에 실린다. 다만 history.state는 브라우저마다 크기 상한이 있어서(Firefox 16MiB) 업로드 API가 붙으면 파일 대신 서버가 준 식별자를 담는 쪽으로 바꾸는 게 안전하다. `File`이 history.state에서 되살아나지 못하는 경우도 있어 `guard`가 `instanceof File`로 확인하고, 아니면 첫 단계로 돌려보낸다.

토스 이동 안내/실패(`3562:163025` / `3562:163046`)와 캡처 업로드 전/후(`3562:162845` / `3562:162891`)는 각각 **한 단계 안의 state**다. Figma가 프레임을 나눠 뒀지만 퍼널 단계로는 올리지 않았다 — 뒤로가기로 돌아갈 지점이 아니기 때문이다.
12 changes: 12 additions & 0 deletions src/app/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import EventsApplicationScreen from "@/features/events/EventsApplicationScreen";
import EventsDetailScreen from "@/features/events/EventsDetailScreen";
import EventsListScreen from "@/features/events/EventsListScreen";
import FeePaymentsScreen from "@/features/fee/FeePaymentsScreen";
import FeeTransferScreen from "@/features/fee/FeeTransferScreen";
import FeedbacksDetailScreen from "@/features/feedbacks/FeedbacksDetailScreen";
import FeedbacksListScreen from "@/features/feedbacks/FeedbacksListScreen";
import FeedbacksMineDetailScreen from "@/features/feedbacks/FeedbacksMineDetailScreen";
Expand Down Expand Up @@ -199,6 +200,17 @@ const routes = [
// 시트만 있는 화면이라 뒤에 Bottom Nav가 비쳐도 Figma(홈 위에 뜨는 시트)와 같다
path: "/lockers/apply",
},
{
element: <FeeTransferScreen />,
// 학생회비 계좌 송금 퍼널 하나가 모든 단계(남은 학기 수, 학점이수현황 캡처, 토스 이동,
// 송금 확인, 확인요청 완료)를 그린다 — 단계는 `?fee.step=`으로 나뉜다.
// 전부 하단 고정 버튼(Action Area)이 있는 흰 배경 화면이라 Bottom Nav가 없다.
handle: {
background: "normal",
hasBottomNav: false,
} satisfies ScreenRouteHandle,
path: "/fee/transfer",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[a] 마지막 커밋에서 라우트 5개가 /fee/transfer 하나 + useFunnel 퍼널로 바뀌었는데, PR 본문은 아직 이전 구조(라우트 5개, navigate(..., { state })로 학기 수 전달, FeeTransferTranscriptScreen)로 적혀 있는 것 같습니다. 리뷰하는 분들이 헷갈리지 않도록 본문도 지금 구조로 맞춰주시면 감사하겠습니다!

그리고 main이 5커밋 앞서 있어서 이 파일과 fee.ts에서 충돌이 나는 것 같습니다. 라우트 경로 /fee/transfer 자체는 용어 사전 규칙(회비 납부 → fee)에 맞는 것 같아요.

},
{
element: <SearchScreen />,
// 검색 화면은 Figma에 Bottom Nav가 없고(뒤로가기로 진입한 화면에 복귀) 배경이 흰 면이다
Expand Down
5 changes: 5 additions & 0 deletions src/assets/icons/fee/image-file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/fee/transcript-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading