-
Notifications
You must be signed in to change notification settings - Fork 2
Update after demo #55
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 all commits
23dbe48
698ed91
b6cb35d
55f4a75
2763cf3
cf2157a
4ec8eaf
2b3894e
d1ca615
0a0ea18
eda3e43
86acdfe
978b3aa
a16fd87
ee6afc7
70ebaa3
bcc1cd5
7d5250b
02b17e6
7041351
5bf678b
5104f2a
df656bb
a5446c8
fabde4e
68ce4ea
21316d4
272432d
2e05c03
583c613
d29eeff
7a7a68a
3136c68
8801660
5c7a59d
3dc406c
b2629d4
dfac342
f065d94
525b888
8bf61b6
f08aa2a
08b4560
ee7a20e
1eb042b
396aab4
9387475
ab5fa12
8ee477b
d294635
55a220a
f07a016
e1b6af9
891c5e5
c2f7bec
08de64e
3f3ad2d
3d64154
99ac5b6
1589563
6a2f808
25a404b
23bc5da
af4bcf6
7c97603
d494c02
d313a9c
059e897
15c7ec4
2e7f446
b2f3216
5f81d91
c4a0e97
b7c9b3a
074ebf4
bc22043
010a449
a5e0ba9
be8d56d
4b3ae63
3ac8db2
3544b0a
3df8115
f290846
6d9f881
e8f1572
5e429ea
96c1443
81f8a50
2880789
2b186c7
0fa30b6
48d36d9
7a294f4
f996952
fc1fc8c
0843420
e551646
8084437
4c51f90
7335ef3
398f6c5
d4527a1
80b7d35
43e0d7b
e5eebd3
742c292
fc3f8b0
6b0e02b
b05e3a5
efee88a
71b6498
b78646d
8543b55
e750173
7cd8527
78d9b87
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 | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,32 +1,246 @@ | ||||||||||||||||||||||
| # Motimo: FE | ||||||||||||||||||||||
| <div align="center"> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 임시 내용.. Token관련 | ||||||||||||||||||||||
| # 🚀 Motimo | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > 일단 수동으로 tailwind 토큰화한다. | ||||||||||||||||||||||
| **목표를 효과적으로 달성하는 방법, 모티모** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - upstream의 design 브랜치에 토큰 json이 업데이트 된다. | ||||||||||||||||||||||
| - `npm run build-tokens`를 통해 app/tokens.css를 업데이트 한다 | ||||||||||||||||||||||
| <br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## ✨ Motimo 프론트엔드 레포지토리에 오신 것을 환영합니다! | ||||||||||||||||||||||
| <img width="394" height="567" alt="모티모 포스터" src="https://github.com/user-attachments/assets/d78bffcc-99cf-4367-8b54-71a82944eb20" /> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > 디자인 시스템 배포 페이지 | ||||||||||||||||||||||
| [버그 신고](https://github.com/prography/10th-Motimo-FE/issues) · [기능 요청](https://github.com/prography/10th-Motimo-FE/issues) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <a href="10th-motimo-storybook.vercel.app">10th-motimo-storybook.vercel.app</a> | ||||||||||||||||||||||
| **[데모 링크](https://motimo-fe-dev.netlify.app)** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| --- | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 📋 목차 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - [📑 소개](#-소개) | ||||||||||||||||||||||
| - [✨ 주요 기능](#-주요-기능) | ||||||||||||||||||||||
| - [🛠️ 기술 스택](#️-기술-스택) | ||||||||||||||||||||||
| - [⭐ 주요 페이지 동작](#-주요-페이지-동작) | ||||||||||||||||||||||
| - [👥 팀](#-팀) | ||||||||||||||||||||||
| - [🚀 Moiomo 디자인 시스템 둘러보기](#-motimo-디자인-시스템-둘러보기) | ||||||||||||||||||||||
| - [🤝 기여하기](#-기여하기) | ||||||||||||||||||||||
|
Comment on lines
+30
to
+31
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. Typo in ToC: “Moiomo” → “Motimo” Rename for consistency and to avoid broken ToC expectations. -- [🚀 Moiomo 디자인 시스템 둘러보기](#-motimo-디자인-시스템-둘러보기)
+- [🚀 Motimo 디자인 시스템 둘러보기](#-motimo-디자인-시스템-둘러보기)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| - [📄 라이선스](#-라이선스) | ||||||||||||||||||||||
| - [🙏 감사의 말](#-감사의-말) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 📑 소개 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - 혼자 꾸준히 지속하기 어려운 **기간이 긴 목표** 달성. 모티모에서 다른 사람들과 함께 동기부여를 주며 목표를 달성해보세요! | ||||||||||||||||||||||
| - **그룹방**에서 여러 사람들이 투두를 달성하는 것을 보고 동기부여를 얻을 수 있어요! | ||||||||||||||||||||||
| - 혼자가 아니라 함께하면 목표 달성률이 올라가요! 서로에게 동기부여를 주며 목표를 달성해봐요! | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## ✨ 주요 기능 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| #### 🌟 **중장기 목표 설정** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 목표 - 세부목표 - 투두 단계로 할 일을 세분화 할 수 있습니다. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| #### 🔥 **기록 남기기** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 투두를 완료 후 감정과 사진 등 기록을 남겨 상세히 정리할 수 있습니다. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| #### 💡 **그룹** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 그룹에 들어가 다른 사람들과 투두에 대해 상호작용하며 동기부여를 얻을 수 있습니다. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| #### 🎯 **피드** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 보다 많은 사람들의 목표와 달성 과정을 확인하며 동기부여를 얻을 수 있습니다. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🚀 Motimo 프론트엔드의 핵심 목표 | ||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🛠️ 기술 스택 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🚧 현재 상태 및 기여 | ||||||||||||||||||||||
| <div align="center"> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### Frontend | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### DevOps & Tools | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## ⭐ 주요 페이지 동작 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### 온보딩 | ||||||||||||||||||||||
| - 회원가입 및 로그인 | ||||||||||||||||||||||
| - 목표 생성과정을 온보딩에 적용 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [온보딩](https://github.com/user-attachments/assets/34f0ff79-a5f7-42ea-902d-c8d8deabb9de) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### 메인 페이지 | ||||||||||||||||||||||
| - 목표 선택 및 세부 목표별 투두 작성 | ||||||||||||||||||||||
| - 투두 결과 제출 | ||||||||||||||||||||||
| - 투두 수정 및 삭제 | ||||||||||||||||||||||
| - 목표 추가 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [메인페이지](https://github.com/user-attachments/assets/9901e0e8-49b8-4ece-83ff-5f5dfc25dfa0) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### 목표 상세 페이지 | ||||||||||||||||||||||
| - 세부 목표 완료, 목표 달성 처리 | ||||||||||||||||||||||
| - 투두 결과 제출 | ||||||||||||||||||||||
| - 목표명, 기간, 세부 목표 위치와 이름 수정 및 삭제 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [목표 상세 페이지](https://github.com/user-attachments/assets/8b9b888d-cc5d-4f27-b417-544165a8c1aa) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### 그룹 페이지 | ||||||||||||||||||||||
| - 그룹 참여 | ||||||||||||||||||||||
| - 투두 완료, 결과 제출에 대한 리액션 | ||||||||||||||||||||||
| - 그룹 참여원 찌르기 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [그룹페이지](https://github.com/user-attachments/assets/cc3c99a8-a7e9-4191-bd8d-ba7b2ae693e2) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 시작하기 | ||||||||||||||||||||||
| > ### 마이 페이지 | ||||||||||||||||||||||
| ### 기여 방법 | ||||||||||||||||||||||
| - 개인정보 및 관심사 수정 | ||||||||||||||||||||||
| - 달성한 목표 확인 | ||||||||||||||||||||||
| - 알림 설정 | ||||||||||||||||||||||
| - 로그아웃 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🔗 백엔드 레포지토리 | ||||||||||||||||||||||
| [마이페이지](https://github.com/user-attachments/assets/9d426c51-b341-40fc-a3c7-8d0ca14bf669) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 📧 연락처 | ||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 👥 팀 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <div align="center"> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| | 역할 | 이름 | GitHub | | ||||||||||||||||||||||
| | :--------------------: | :----: | :--------------------------------------: | | ||||||||||||||||||||||
| | **Frontend Developer** | 이상현 | [@Hys-Lee](https://github.com/Hys-Lee) | | ||||||||||||||||||||||
| | **Frontend Developer** | 조형관 | [@devgony](https://github.com/devgony) | | ||||||||||||||||||||||
| | **Backend Developer** | 고범석 | [@qjatjr29](https://github.com/qjatjr29) | | ||||||||||||||||||||||
| | **Backend Developer** | 이종은 | [@jongeuni](https://github.com/jongeuni) | | ||||||||||||||||||||||
| | **Project Owner** | 신동민 | - | | ||||||||||||||||||||||
| | **Designer** | 전석희 | - | | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### FE 역할 분담 | ||||||||||||||||||||||
| #### 이상현 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - UI | ||||||||||||||||||||||
| - 페이지: 메인 페이지, 상세 페이지, 그룹 채팅방 | ||||||||||||||||||||||
| - 주요 공용 컴포넌트: 모달, 바텀시트 | ||||||||||||||||||||||
| - 기능 | ||||||||||||||||||||||
| - 모달, 바텀시트, 토스트 전역 커스텀 훅 | ||||||||||||||||||||||
| - 투두, 채팅 무한 스크롤 | ||||||||||||||||||||||
| - 개발 | ||||||||||||||||||||||
| - 스토리북 설정(plop.js) 및 공통 컴포넌트 디자인 시스템화(vercel), 패키지화. | ||||||||||||||||||||||
| - 크로마틱 CI 적용 | ||||||||||||||||||||||
| - Figma 디자인 토큰 Tailwind 토큰화 (Token Studio, Style Dictionary) | ||||||||||||||||||||||
| - 스테이징 배포 (netlify) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| #### 조형관 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - UI | ||||||||||||||||||||||
| - 페이지: 온보딩, 마이 페이지, 그룹 페이지 | ||||||||||||||||||||||
| - 주요 공용 컴포넌트: 쿠퍼티노 피커, Lottie 로딩 애니메이션 컴포넌트 | ||||||||||||||||||||||
| - 기능 | ||||||||||||||||||||||
| - OAuth 로그인 | ||||||||||||||||||||||
| - 공통 api fetcher 제작 | ||||||||||||||||||||||
| - 개발 | ||||||||||||||||||||||
| - API 생성 (swagger-typescript-api) | ||||||||||||||||||||||
| - Cursor 사용한 제작 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🚀 Motimo 디자인 시스템 둘러보기 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### **디자인 시스템 페이지** | ||||||||||||||||||||||
| <img width="1894" height="945" alt="image" src="https://github.com/user-attachments/assets/0154c0fc-1dcf-4f58-b415-591a75fd751e" /> | ||||||||||||||||||||||
| <a href="10th-motimo-storybook.vercel.app">10th-motimo-storybook.vercel.app</a> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
Comment on lines
+186
to
+188
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. External link missing protocol; make it clickable Add https:// to the Storybook link so GitHub renders it correctly. -<a href="10th-motimo-storybook.vercel.app">10th-motimo-storybook.vercel.app</a>
+<a href="https://10th-motimo-storybook.vercel.app">10th-motimo-storybook.vercel.app</a>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| > ### **Motimo 공통 컴포넌트 패키지** | ||||||||||||||||||||||
| > | ||||||||||||||||||||||
| > <img width="1476" height="937" alt="image" src="https://github.com/user-attachments/assets/ade5a4fc-e020-456a-bd8b-b3fc931cc3fe" /> | ||||||||||||||||||||||
| <a href="https://www.npmjs.com/package/motimo-shared-ui">https://www.npmjs.com/package/motimo-shared-ui</a> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🤝 기여하기 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 🐛 버그 신고 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 버그를 발견하셨나요? [이슈](https://github.com/prography/10th-Motimo-FE/issues)를 생성해주세요! | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 💡 기능 제안 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 새로운 기능을 제안하고 싶으시다면 [토론](https://github.com/prography/10th-Motimo-FE/discussions)에서 의견을 나눠주세요! | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <!-- ## 📊 통계 | ||||||||||||||||||||||
| <div align="center"> | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
|  | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| --- | ||||||||||||||||||||||
| --> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 📄 라이선스 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 이 프로젝트는 [예: MIT License]에 따라 라이선스됩니다. 자세한 내용은 `LICENSE` 파일을 참조하세요. | ||||||||||||||||||||||
| 이 프로젝트는 **MIT License** 하에 배포됩니다. 자세한 내용은 [LICENSE](LICENSE) 파일을 참조하세요. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## 🙏 감사의 말 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - [Vaul](https://github.com/emilkowalski/vaul) - 바텀 시트에 사용된 라이브러리 | ||||||||||||||||||||||
| - [Motion](https://github.com/motiondivision/motion) - 애니메이션에 사용된 라이브러리 | ||||||||||||||||||||||
| - [Contributors](https://github.com/prography/10th-Motimo-FE/contributors) - 모든 기여자분들께 감사드립니다 | ||||||||||||||||||||||
| - [Prography](https://prography.org/) - 활발한 개발 환경 지원 | ||||||||||||||||||||||
| - Motimo 팀원들과 Progarphy 10기 분들 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
Comment on lines
+232
to
+237
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. Spelling: “Progarphy” → “Prography” Minor typo fix in acknowledgements. -- Motimo 팀원들과 Progarphy 10기 분들
+- Motimo 팀원들과 Prography 10기 분들📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| <br/><br/> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <div align="center"> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| **⭐ 이 프로젝트가 도움이 되셨다면 스타를 눌러주세요! ⭐** | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Made with ❤️ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { Api, HttpClient } from "./generated/motimo/Api"; | ||
| import useAuthStore from "../stores/useAuthStore"; | ||
| import useToastStore from "@/stores/useToastStore"; | ||
|
|
||
| // HTTP 클라이언트 생성 시 인증 헤더를 자동으로 추가하는 securityWorker 설정 | ||
| const httpClient = new HttpClient({ | ||
|
|
@@ -16,10 +17,52 @@ const httpClient = new HttpClient({ | |
| }; | ||
| } | ||
|
|
||
| const isGuest = useAuthStore.getState().isGuest; | ||
| if (isGuest) { | ||
| return { format: "json" }; | ||
| } | ||
|
|
||
| return {}; | ||
| }, | ||
| }); | ||
|
|
||
| // 비동기 에러 시 toast 띄우기 | ||
| const showToast = (content: string, createdAt: Date) => { | ||
| useToastStore.getState().updateToastInfo({ content, createdAt }); | ||
| }; | ||
|
|
||
| // Debouncer 감싸도 될 것 같은데? | ||
| const debounceer = <T, E>(apiRequest: typeof httpClient.request<T, E>) => { | ||
| const timeLimit = 1000; | ||
| let timer: number; | ||
| let rejectTimer: (reason?: any) => void; | ||
| return ( | ||
| requestParams: Parameters<typeof httpClient.request<T, E>>[0], | ||
| ): ReturnType<typeof httpClient.request<T>> => { | ||
| if (timer) { | ||
| clearTimeout(timer); | ||
| rejectTimer("debouncing"); | ||
| } | ||
| const apiRes: Promise<T> = new Promise((resolve, reject) => { | ||
| rejectTimer = reject; | ||
| timer = Number( | ||
| setTimeout(async () => { | ||
| try { | ||
| const res = apiRequest(requestParams); | ||
| resolve(res); | ||
| } catch (error) { | ||
| console.error(error); | ||
| showToast(`API ERROR`, new Date()); | ||
| } | ||
| }, timeLimit), | ||
| ); | ||
| }); | ||
| return apiRes; | ||
| }; | ||
| }; | ||
|
|
||
| httpClient.request = debounceer(httpClient.request); | ||
|
|
||
|
Comment on lines
+35
to
+65
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 ❓ Verification inconclusiveDebouncer breaks typing, loses
Apply this diff to fix typing, context, and error handling: -// Debouncer 감싸도 될 것 같은데?
-const debounceer = <T, E>(apiRequest: typeof httpClient.request<T, E>) => {
- const timeLimit = 1000;
- let timer: number;
- let rejectTimer: (reason?: any) => void;
- return (
- requestParams: Parameters<typeof httpClient.request<T, E>>[0],
- ): ReturnType<typeof httpClient.request<T>> => {
- if (timer) {
- clearTimeout(timer);
- rejectTimer("debouncing");
- }
- const apiRes: Promise<T> = new Promise((resolve, reject) => {
- rejectTimer = reject;
- timer = Number(
- setTimeout(async () => {
- try {
- const res = apiRequest(requestParams);
- resolve(res);
- } catch (error) {
- console.error(error);
- showToast(`API ERROR`, new Date());
- }
- }, timeLimit),
- );
- });
- return apiRes;
- };
-};
-
-httpClient.request = debounceer(httpClient.request);
+// Global debouncer (verify this behavior is desired)
+const debounceRequests = (client: HttpClient, ms = 1000): HttpClient["request"] => {
+ let timer: ReturnType<typeof setTimeout> | undefined;
+ let rejectTimer: ((reason?: unknown) => void) | undefined;
+
+ return async function request<T, E>(
+ params: Parameters<HttpClient["request"]>[0],
+ ): ReturnType<HttpClient["request"]> {
+ if (timer) {
+ clearTimeout(timer);
+ rejectTimer?.(new Error("debounced"));
+ }
+ return await new Promise<T>((resolve, reject) => {
+ rejectTimer = reject;
+ timer = setTimeout(async () => {
+ try {
+ const res = await client.request<T, E>(params);
+ resolve(res);
+ } catch (error) {
+ console.error(error);
+ showToast("API ERROR", new Date());
+ reject(error);
+ } finally {
+ timer = undefined;
+ rejectTimer = undefined;
+ }
+ }, ms);
+ });
+ };
+};
+
+httpClient.request = debounceRequests(httpClient);If the intent is to debounce only identical or mutating requests, I can provide a keyed debouncer (method+URL+[body]) to avoid dropping unrelated calls. Do you want that? Fix Debouncer in api/service.ts: correct typing, preserve The current implementation introduces three critical issues:
Additionally, the global debounce drops every request in the window. If you only intend to debounce identical requests, consider a key-based approach (e.g., by URL+params). Apply this diff to fix all three issues: --- a/api/service.ts
+++ b/api/service.ts
@@ -35,7 +35,7 @@
-const debounceer = <T, E>(apiRequest: typeof httpClient.request<T, E>) => {
+const debounceRequests = (client: HttpClient, ms = 1000): HttpClient["request"] => {
let timer: ReturnType<typeof setTimeout> | undefined;
let rejectTimer: ((reason?: unknown) => void) | undefined;
- return (requestParams: Parameters<typeof httpClient.request<T, E>>[0]): ReturnType<typeof httpClient.request<T>> => {
+ return async function request<T, E>(
+ params: Parameters<HttpClient["request"]>[0]
+ ): ReturnType<HttpClient["request"]> {
if (timer) {
clearTimeout(timer);
rejectTimer?.(new Error("debounced"));
@@ -45,20 +45,32 @@
- const apiRes: Promise<T> = new Promise((resolve, reject) => {
- rejectTimer = reject;
- timer = Number(
- setTimeout(async () => {
- try {
- const res = apiRequest(requestParams);
- resolve(res);
- } catch (error) {
- console.error(error);
- showToast(`API ERROR`, new Date());
- }
- }, timeLimit),
- );
- });
- return apiRes;
+ return new Promise<T>((resolve, reject) => {
+ rejectTimer = reject;
+ timer = setTimeout(async () => {
+ try {
+ // Preserve context and catch async errors
+ const res = await client.request<T, E>(params);
+ resolve(res);
+ } catch (error) {
+ console.error(error);
+ showToast("API ERROR", new Date());
+ reject(error);
+ } finally {
+ timer = undefined;
+ rejectTimer = undefined;
+ }
+ }, ms);
+ });
};
};
-httpClient.request = debounceer(httpClient.request);
+// Override with the debounced version of request
+httpClient.request = debounceRequests(httpClient, 1000);Let me know if you’d like a keyed-debouncer (method+URL+body) instead of a global one.
🤖 Prompt for AI Agents |
||
| // API 클라이언트 인스턴스 생성 | ||
| export const api = new Api(httpClient); | ||
|
|
||
|
|
||
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.
💡 Verification agent
🧩 Analysis chain
Favicon path likely 404s in Storybook; point to /public instead of /app
Storybook serves static assets from staticDirs = ../public, so /app/icon.png won’t be resolvable. Use /icon.png or add the app folder to staticDirs.
managerHead: (head) => ` ${head} - <link rel="icon" type="image/png" href="/app/icon.png" /> + <link rel="icon" type="image/png" href="/icon.png" /> `,Run this to verify where icon.png lives:
Expected: public/icon.png exists; if it’s instead at app/icon.png, either move it to public or add path.resolve(__dirname, "../app") to staticDirs.
🏁 Script executed:
Length of output: 75
Fix broken Storybook favicon by updating staticDirs and link path
Icon.png lives in app/icon.png, but Storybook only serves ../public by default. You’ll need to include the app folder in staticDirs and point the link at /icon.png (or configure a custom mount if you want to preserve /app/icon.png).
• File: .storybook/main.ts
• Add your app directory to staticDirs and change the link href:
If you prefer to keep the /app prefix, you can instead use:
🤖 Prompt for AI Agents