-
Notifications
You must be signed in to change notification settings - Fork 1
Feat(onboarding): 온보딩 회원가입 api 연결 #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
78b0308
1e6bc1a
19b0081
205b66f
7dd8a8c
9ddf810
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,8 +6,10 @@ import AlarmStep from './step/AlarmStep'; | |
| import MacStep from './step/MacStep'; | ||
| import FinalStep from './step/FinalStep'; | ||
| import { cva } from 'class-variance-authority'; | ||
| import { usePostSignUp } from '@shared/apis/queries'; | ||
| const stepProgress = [{ progress: 30 }, { progress: 60 }, { progress: 100 }]; | ||
|
|
||
| import { AlarmsType } from '@constants/alarms'; | ||
| import { normalizeTime } from '@pages/onBoarding/utils/formatRemindTime'; | ||
| const variants = { | ||
| slideIn: (direction: number) => ({ | ||
| x: direction > 0 ? 200 : -200, | ||
|
|
@@ -36,6 +38,8 @@ const MainCard = () => { | |
| const [direction, setDirection] = useState(0); | ||
| const [alarmSelected, setAlarmSelected] = useState<1 | 2 | 3>(1); | ||
| const [isMac, setIsMac] = useState(false); | ||
| // api 구간 | ||
| const {mutate:postSignData} = usePostSignUp(); | ||
|
|
||
| useEffect(() => { | ||
| const ua = navigator.userAgent.toLowerCase(); | ||
|
|
@@ -62,15 +66,33 @@ const MainCard = () => { | |
| } | ||
| }; | ||
|
|
||
| const [remindTime, setRemindTime] = useState('09:00'); | ||
| const nextStep = () => { | ||
| console.log(step) | ||
| if (step === 3) { | ||
| // 이거 이후에 api 붙일 자리 표시임! console.log('선택된 알람:', AlarmsType[alarmSelected - 1].time); | ||
| // 이거 이후에 api 붙일 자리 표시임! | ||
|
|
||
| } | ||
|
Comment on lines
+69
to
75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain기본 알람(1,2) 선택 시 현재 상수의 한글 포맷을 그대로 넘기면 수정 후 1/2/3 각 선택 케이스에서 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== rg: normalizeTime ==="
rg -n --hidden -S "normalizeTime" -g '!node_modules' -C3 || true
echo "=== rg: AlarmsType ==="
rg -n --hidden -S "AlarmsType" -g '!node_modules' -C3 || true
if [ -f "apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx" ]; then
echo "=== cat: apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx (1-320) ==="
sed -n '1,320p' apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx || true
else
echo "MainCard.tsx not found at expected path"
fi
echo "=== search: Korean time literals (오전|오후) ==="
rg -n --hidden -S "오전|오후" -g '!node_modules' -C2 || true
echo "=== search: '09:00' or '20:00' literals ==="
rg -n --hidden -S "09:00|20:00" -g '!node_modules' -C2 || true
echo "=== search: AlarmsType array/object definitions ==="
rg -n --hidden -S "const\\s+\\w*Alarms\\w*\\s*=|export\\s+const\\s+\\w*Alarms\\w*\\s*=" -g '!node_modules' -C4 || true
echo "=== search: normalizeTime implementation ==="
rg -n --hidden -S "function\\s+normalizeTime|normalizeTime\\s*=|normalizeTime\\s*:\\s*\\(" -g '!node_modules' -C4 || true
echo "=== done ==="Length of output: 5565 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo "=== list top-level ==="
ls -la | sed -n '1,200p'
echo
echo "=== check common paths for formatRemindTime / alarms ==="
paths=(
"apps/client/src/pages/onBoarding/utils/formatRemindTime.ts"
"apps/client/src/pages/onBoarding/utils/formatRemindTime.tsx"
"apps/client/src/pages/onBoarding/utils/formatRemindTime/index.ts"
"apps/client/src/pages/onBoarding/utils/formatRemindTime/index.tsx"
"apps/client/src/constants/alarms.ts"
"apps/client/src/constants/alarms/index.ts"
"apps/client/src/constants/alarms.tsx"
"src/constants/alarms.ts"
"src/pages/onBoarding/utils/formatRemindTime.ts"
"apps/client/src/constants/alarms/index.ts"
)
for p in "${paths[@]}"; do
if [ -f "$p" ]; then
echo "FOUND: $p"
sed -n '1,240p' "$p" || true
echo "----"
else
echo "MISSING: $p"
fi
done
echo
echo "=== find files with relevant names (case-insensitive) ==="
find . -type f \( -iname '*formatremindtime*' -o -iname '*formatremind*' -o -iname '*alarms*' \) -print | sed -n '1,200p' || true
echo
echo "=== grep for symbols (exclude node_modules) ==="
grep -RIn --exclude-dir=node_modules --include=\*.{ts,tsx,js,jsx} "normalizeTime" . || true
grep -RIn --exclude-dir=node_modules --include=\*.{ts,tsx,js,jsx} "formatRemindTime" . || true
grep -RIn --exclude-dir=node_modules --include=\*.{ts,tsx,js,jsx} "AlarmsType" . || true
echo
echo "=== list utils and constants dirs if present ==="
[ -d "apps/client/src/pages/onBoarding/utils" ] && ls -la "apps/client/src/pages/onBoarding/utils" || true
[ -d "apps/client/src/constants" ] && ls -la "apps/client/src/constants" || true
[ -d "src/pages/onBoarding/utils" ] && ls -la "src/pages/onBoarding/utils" || true
[ -d "src/constants" ] && ls -la "src/constants" || trueLength of output: 6206 기본 알람(1/2) 선택 시 시간 포맷 방어 필요 —
🤖 Prompt for AI Agents |
||
| if (step < 5) { | ||
| setDirection(1); | ||
| setStep((prev) => prev + 1); | ||
| } else if (step === 5) { | ||
| window.location.href = '/'; | ||
| const raw = AlarmsType[alarmSelected - 1].time; | ||
| setRemindTime(normalizeTime(raw)); | ||
|
|
||
| postSignData({ | ||
| "email": "tesdfdfsst@gmail.com", | ||
| "remindDefault": remindTime, | ||
| "fcmToken": "adlfdjlajlkadfsjlkfdsdfsdfsdfsdfsa" | ||
| }, | ||
|
Comment on lines
+83
to
+87
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. key에 string으로 저렇게 작성해도 잘 동작하나요??
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵네! 첫 회원가입 로직이라서, |
||
| { | ||
| onSuccess:()=>{ | ||
| window.location.href = '/'; | ||
| } | ||
| } | ||
| ) | ||
|
|
||
|
|
||
| } | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,26 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function normalizeTime(input: string): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let hours = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let minutes = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ampmMatch = input.match(/(AM|PM)\s?(\d{1,2}):(\d{1,2})/i); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (ampmMatch) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [, ampm, h, m] = ampmMatch; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hours = parseInt(h, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minutes = parseInt(m, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (ampm.toUpperCase() === "PM" && hours < 12) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hours += 12; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (ampm.toUpperCase() === "AM" && hours === 12) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hours = 0; // 12 AM → 00시 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [h, m] = input.split(":"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hours = parseInt(h, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| minutes = parseInt(m, 10); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hh = String(hours).padStart(2, "0"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const mm = String(minutes).padStart(2, "0"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${hh}:${mm}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 한글(오전/오후) 포맷 미지원으로 NaN:NaN 발생 가능 현재 아래처럼 다국어 포맷을 안전하게 처리하는 방향을 제안합니다. -export function normalizeTime(input: string): string {
- let hours = 0;
- let minutes = 0;
-
- const ampmMatch = input.match(/(AM|PM)\s?(\d{1,2}):(\d{1,2})/i);
- if (ampmMatch) {
- const [, ampm, h, m] = ampmMatch;
- hours = parseInt(h, 10);
- minutes = parseInt(m, 10);
-
- if (ampm.toUpperCase() === "PM" && hours < 12) {
- hours += 12;
- }
- if (ampm.toUpperCase() === "AM" && hours === 12) {
- hours = 0; // 12 AM → 00시
- }
- } else {
- const [h, m] = input.split(":");
- hours = parseInt(h, 10);
- minutes = parseInt(m, 10);
- }
-
- const hh = String(hours).padStart(2, "0");
- const mm = String(minutes).padStart(2, "0");
- return `${hh}:${mm}`;
-}
+export function normalizeTime(input: string): string {
+ const fallback = '09:00';
+ if (!input || typeof input !== 'string') return fallback;
+ const s = input.trim();
+
+ // 1) AM/PM 앞: "AM 9:05", "PM 12:00"
+ const ampmFront = s.match(/^(AM|PM)\s*(\d{1,2})(?::(\d{1,2}))?$/i);
+ // 2) AM/PM 뒤: "9:05 AM", "12 PM"
+ const ampmBack = s.match(/^(\d{1,2})(?::(\d{1,2}))?\s*(AM|PM)$/i);
+ // 3) 한글: "오전 9시", "오후 8시", "오전 9시 5분"
+ const kor = s.match(/^(오전|오후)\s*(\d{1,2})\s*시(?:\s*(\d{1,2})\s*분)?$/);
+ // 4) 24시간: "09:00", "9:5"
+ const h24 = s.match(/^(\d{1,2})(?::(\d{1,2}))$/);
+
+ let hours: number | null = null;
+ let minutes: number | null = null;
+ let meridiem: 'AM' | 'PM' | null = null;
+
+ if (ampmFront) {
+ const [, ampm, h, m] = ampmFront;
+ hours = parseInt(h!, 10);
+ minutes = m ? parseInt(m, 10) : 0;
+ meridiem = ampm.toUpperCase() as 'AM' | 'PM';
+ } else if (ampmBack) {
+ const [, h, m, ampm] = ampmBack;
+ hours = parseInt(h!, 10);
+ minutes = m ? parseInt(m, 10) : 0;
+ meridiem = ampm.toUpperCase() as 'AM' | 'PM';
+ } else if (kor) {
+ const [, ap, h, m] = kor;
+ hours = parseInt(h!, 10);
+ minutes = m ? parseInt(m, 10) : 0;
+ meridiem = ap === '오후' ? 'PM' : 'AM';
+ } else if (h24) {
+ const [, h, m] = h24;
+ hours = parseInt(h!, 10);
+ minutes = parseInt(m!, 10);
+ }
+
+ if (hours === null || minutes === null || Number.isNaN(hours) || Number.isNaN(minutes)) {
+ return fallback;
+ }
+
+ if (meridiem) {
+ if (meridiem === 'PM' && hours < 12) hours += 12;
+ if (meridiem === 'AM' && hours === 12) hours = 0;
+ }
+
+ if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return fallback;
+
+ const hh = String(hours).padStart(2, '0');
+ const mm = String(minutes).padStart(2, '0');
+ return `${hh}:${mm}`;
+}추가로 간단한 유닛 테스트(예: '오전 9시'→'09:00', '오후 8시'→'20:00', 'AM 9:05'→'09:05', 빈 문자열→'09:00')도 부탁드립니다. 원하시면 테스트 템플릿을 바로 드리겠습니다. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,3 +20,14 @@ export const getAcorns = async () => { | |||||||||
| }); | ||||||||||
| return data.data; | ||||||||||
| }; | ||||||||||
|
|
||||||||||
| export interface postSignUpRequest { | ||||||||||
| email: string, | ||||||||||
| remindDefault: string, | ||||||||||
| fcmToken: string | ||||||||||
| } | ||||||||||
|
|
||||||||||
| export const postSignUp = async (data: postSignUpRequest) => { | ||||||||||
| const response = await apiRequest.post('/api/v1/auth/signup', data); | ||||||||||
| return response.data; | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게도 가능하고 받을 때 바로 구조 분해 할당도 가능합니다!
Suggested change
|
||||||||||
| }; | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import { useMutation, useQuery, UseQueryResult } from '@tanstack/react-query'; | ||
| import { getDashboardCategories, postCategory } from '@shared/apis/axios'; | ||
| import { getDashboardCategories, postCategory, postSignUp, postSignUpRequest } from '@shared/apis/axios'; | ||
| import { AxiosError } from 'axios'; | ||
| import { DashboardCategoriesResponse, AcornsResponse } from '@shared/types/api'; | ||
| import { getAcorns } from './axios'; | ||
|
|
@@ -26,3 +26,21 @@ export const useGetArcons = (): UseQueryResult<AcornsResponse, AxiosError> => { | |
| queryFn: () => getAcorns(), | ||
| }); | ||
| }; | ||
|
|
||
| export const usePostSignUp = () => { | ||
| return useMutation({ | ||
| mutationFn: (data: postSignUpRequest) => postSignUp(data), | ||
| onSuccess: (data) => { | ||
|
Comment on lines
+30
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion useMutation 제네릭 지정으로 응답 스키마 고정 및 안전성 확보 현재 추가 타입(파일 상단 임의 위치): type SignUpResponse = { token: string };선택 라인 변경: -export const usePostSignUp = () => {
- return useMutation({
- mutationFn: (data: postSignUpRequest) => postSignUp(data),
- onSuccess: (data) => {
+export const usePostSignUp = () => {
+ return useMutation<SignUpResponse, AxiosError, postSignUpRequest>({
+ mutationFn: (payload) => postSignUp(payload),
+ onSuccess: (resp) => {🤖 Prompt for AI Agents |
||
| const newToken = data?.data?.token || data?.token; | ||
|
|
||
| if (newToken) { | ||
| localStorage.setItem("token", newToken); | ||
| } | ||
|
|
||
| console.log("회원가입 성공:", data); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 불필요한 콘솔은 이후에 제거! |
||
| }, | ||
| onError: (error) => { | ||
| console.error("회원가입 실패:", error); | ||
| }, | ||
| }); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
중복 제출 방지: 로딩 상태 처리 및 버튼 비활성화
useMutation의isPending을 사용해 전송 중 중복 클릭을 막아주세요.적용 제안(diff 1/2):
적용 제안(diff 2/2 — 파일 하단 버튼, 외부 범위 변경):
📝 Committable suggestion
🤖 Prompt for AI Agents