-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* ✨ feat: 알림 관련 스키마 및 api 정의 * ✨ feat: 서비스 워커 추가 * ✨ feat: 알림 구독 커스텀훅 및 input 값 설정 * 🐛 fix: 그래프, 주식 정보의 높이가 옆의 컴포넌트와 맞지 않는 문제 수정 * 🐛 fix: 소유 주식이 아니더라도 스크롤 허용 * 🐛 fix: alarm api 관련 스키마 구조 및 useQuery 옵션 변경 * ✨ feat: 마이페이지에 알림 정보 추가 및 리팩토링 * ✨ feat: staleTime, invalidateQueries 지정 * ✨ feat: 주식 상세페이지에 알림 컴포넌트 구현 * 🐛 fix: contexts 내부에 theme 폴더 생성 및 이동 * ✨ feat: context api로 로그인 상태 관리 * 🐛 fix: 로그인 상태 확인 api 호출, props drilling을 모두 context로 대체 * 🐛 fix: 안내 문구 말투 변경 * 🐛 fix: modal 내용이 줄바꿈 되도록 설정 * 🐛 fix: 문장 사이의 띄어쓰기 삭제 * 🐛 fix: tradingVolume string 타입으로 변경 * 🐛 fix: 알림 권한은 처음 한번만 요청하도록 설정 * 🐛 fix: 알림 추가 디자인 수정
- Loading branch information
Showing
41 changed files
with
504 additions
and
1,611 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
self.addEventListener('push', (event) => { | ||
const data = event.data | ||
? event.data.json() | ||
: { title: '알림', body: '내용 없음' }; | ||
|
||
self.registration.showNotification(data.title, { | ||
body: data.body, | ||
// icon: 'icon.png', | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export * from './schema'; | ||
export * from './useGetAlarm'; | ||
export * from './useGetStockAlarm'; | ||
export * from './usePostCreateAlarm'; | ||
export * from './usePostInitAlarm'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { z } from 'zod'; | ||
|
||
const KeysSchema = z.object({ | ||
p256dh: z.string(), | ||
auth: z.string(), | ||
}); | ||
|
||
export const PostInitAlarmRequestSchema = z.object({ | ||
endpoint: z.string(), | ||
keys: KeysSchema, | ||
}); | ||
|
||
export type PostInitAlarmRequest = z.infer<typeof PostInitAlarmRequestSchema>; | ||
|
||
export const PostInitAlarmResponseSchema = z.object({ | ||
message: z.string(), | ||
}); | ||
|
||
export type PostInitAlarmResponse = z.infer<typeof PostInitAlarmResponseSchema>; | ||
|
||
export const PostCreateAlarmRequestSchema = z.object({ | ||
stockId: z.string(), | ||
targetPrice: z.number().optional(), | ||
targetVolume: z.number().optional(), | ||
alarmDate: z.string().datetime(), | ||
}); | ||
|
||
export type PostCreateAlarmRequest = z.infer< | ||
typeof PostCreateAlarmRequestSchema | ||
>; | ||
|
||
export const AlarmInfoSchema = z.object({ | ||
alarmId: z.number(), | ||
stockId: z.string(), | ||
targetPrice: z.number().nullable(), | ||
targetVolume: z.string().nullable(), | ||
alarmDate: z.string().datetime(), | ||
}); | ||
|
||
export const AlarmResponseSchema = z.array(AlarmInfoSchema); | ||
export type AlarmResponse = z.infer<typeof AlarmResponseSchema>; | ||
|
||
export const StockAlarmRequestSchema = z.object({ | ||
stockId: z.string(), | ||
}); | ||
|
||
export type StockAlarmRequest = z.infer<typeof StockAlarmRequestSchema>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useQuery } from '@tanstack/react-query'; | ||
import { type AlarmResponse, AlarmResponseSchema } from './schema'; | ||
import { get } from '@/apis/utils/get'; | ||
|
||
const getAlarm = () => | ||
get<AlarmResponse>({ | ||
schema: AlarmResponseSchema, | ||
url: '/api/alarm/user', | ||
}); | ||
|
||
export const useGetAlarm = ({ isLoggedIn }: { isLoggedIn: boolean }) => { | ||
return useQuery({ | ||
queryKey: ['getAlarm'], | ||
queryFn: getAlarm, | ||
enabled: isLoggedIn, | ||
}); | ||
}; |
24 changes: 24 additions & 0 deletions
24
packages/frontend/src/apis/queries/alarm/useGetStockAlarm.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { useQuery } from '@tanstack/react-query'; | ||
import { | ||
type AlarmResponse, | ||
StockAlarmRequest, | ||
AlarmResponseSchema, | ||
} from './schema'; | ||
import { get } from '@/apis/utils/get'; | ||
|
||
const getStockAlarm = ({ stockId }: StockAlarmRequest) => | ||
get<AlarmResponse>({ | ||
schema: AlarmResponseSchema, | ||
url: `/api/alarm/stock/${stockId}`, | ||
}); | ||
|
||
export const useGetStockAlarm = ({ | ||
stockId, | ||
isLoggedIn, | ||
}: StockAlarmRequest & { isLoggedIn: boolean }) => { | ||
return useQuery({ | ||
queryKey: ['getStockAlarm', stockId], | ||
queryFn: () => getStockAlarm({ stockId }), | ||
enabled: isLoggedIn, | ||
}); | ||
}; |
35 changes: 35 additions & 0 deletions
35
packages/frontend/src/apis/queries/alarm/usePostCreateAlarm.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { useMutation, useQueryClient } from '@tanstack/react-query'; | ||
import { | ||
type PostCreateAlarmRequest, | ||
type AlarmResponse, | ||
AlarmInfoSchema, | ||
} from './schema'; | ||
import { post } from '@/apis/utils/post'; | ||
|
||
const postCreateAlarm = ({ | ||
stockId, | ||
targetPrice, | ||
targetVolume, | ||
alarmDate, | ||
}: PostCreateAlarmRequest) => | ||
post<AlarmResponse>({ | ||
params: { stockId, targetPrice, targetVolume, alarmDate }, | ||
schema: AlarmInfoSchema, | ||
url: '/api/alarm', | ||
}); | ||
|
||
export const usePostCreateAlarm = () => { | ||
const queryClient = useQueryClient(); | ||
return useMutation({ | ||
mutationKey: ['createAlarm'], | ||
mutationFn: ({ | ||
stockId, | ||
targetPrice, | ||
targetVolume, | ||
alarmDate, | ||
}: PostCreateAlarmRequest) => | ||
postCreateAlarm({ stockId, targetPrice, targetVolume, alarmDate }), | ||
onSuccess: () => | ||
queryClient.invalidateQueries({ queryKey: ['getStockAlarm'] }), | ||
}); | ||
}; |
20 changes: 20 additions & 0 deletions
20
packages/frontend/src/apis/queries/alarm/usePostInitAlarm.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { useMutation } from '@tanstack/react-query'; | ||
import { | ||
type PostInitAlarmResponse, | ||
PostInitAlarmResponseSchema, | ||
} from './schema'; | ||
import { post } from '@/apis/utils/post'; | ||
|
||
const postInitAlarm = (subscription: PushSubscription) => | ||
post<PostInitAlarmResponse>({ | ||
params: subscription, | ||
schema: PostInitAlarmResponseSchema, | ||
url: '/api/push/subscribe', | ||
}); | ||
|
||
export const usePostInitAlarm = () => { | ||
return useMutation({ | ||
mutationKey: ['initAlarm'], | ||
mutationFn: (subscription: PushSubscription) => postInitAlarm(subscription), | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,23 @@ | ||
import Date from '@/assets/date.svg?react'; | ||
import Flag from '@/assets/flag.svg?react'; | ||
import Bell from '@/assets/small-bell.svg?react'; | ||
|
||
export interface AlarmProps { | ||
goalPrice?: number; | ||
method?: 'push' | 'email'; | ||
date?: string; | ||
option: string; | ||
goalPrice: number | string; | ||
alarmDate: string; | ||
} | ||
|
||
export const Alarm = ({ goalPrice, method, date }: AlarmProps) => { | ||
export const Alarm = ({ option, goalPrice, alarmDate }: AlarmProps) => { | ||
return ( | ||
<article className="display-medium14 text-dark-gray bg-extra-light-gray flex flex-col gap-2 rounded-md p-4"> | ||
<span className="flex items-center gap-2"> | ||
<Flag /> | ||
목표가: {goalPrice?.toLocaleString()}원 | ||
</span> | ||
<span className="flex items-center gap-2"> | ||
<Bell /> | ||
{method === 'push' ? '웹 푸시' : '이메일'} 알림 | ||
{option}: {goalPrice?.toLocaleString()}원 | ||
</span> | ||
<span className="flex items-center gap-2"> | ||
<Date /> | ||
{date} | ||
{alarmDate.slice(0, 10)} | ||
</span> | ||
<section> | ||
<button className="mr-2">수정</button> | ||
<button>삭제</button> | ||
</section> | ||
</article> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
export const ALARM_OPTIONS = [ | ||
{ id: 1, label: '목표가' }, | ||
{ id: 2, label: '등락률' }, | ||
{ id: 3, label: '거래가' }, | ||
export type AlarmOptionName = 'targetVolume' | 'targetPrice'; | ||
|
||
interface AlarmOption { | ||
id: number; | ||
name: AlarmOptionName; | ||
label: string; | ||
} | ||
|
||
export const ALARM_OPTIONS: AlarmOption[] = [ | ||
{ id: 1, name: 'targetPrice', label: '목표가' }, | ||
{ id: 2, name: 'targetVolume', label: '거래가' }, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './loginContext'; | ||
export * from './loginProvider'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { createContext } from 'react'; | ||
import { GetLoginStatus } from '@/apis/queries/auth/schema'; | ||
|
||
interface LoginContextType extends Partial<GetLoginStatus> { | ||
isLoggedIn: boolean; | ||
} | ||
|
||
export const LoginContext = createContext<LoginContextType>({ | ||
isLoggedIn: false, | ||
nickname: '', | ||
subName: '', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { type ReactNode } from 'react'; | ||
import { LoginContext } from './loginContext'; | ||
import { useGetLoginStatus } from '@/apis/queries/auth'; | ||
|
||
interface LoginProviderProps { | ||
children: ReactNode; | ||
} | ||
|
||
export const LoginProvider = ({ children }: LoginProviderProps) => { | ||
const { data: loginStatus } = useGetLoginStatus(); | ||
|
||
if (!loginStatus) return; | ||
const { message, nickname, subName } = loginStatus; | ||
|
||
return ( | ||
<LoginContext.Provider | ||
value={{ isLoggedIn: message === 'Authenticated', nickname, subName }} | ||
> | ||
{children} | ||
</LoginContext.Provider> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './themeContext'; | ||
export * from './themeProvider'; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.