프로젝트/Next+TypeScript 20

[Coworkers] 클립보드 복사 (Trouble Shooting)

오늘 작업에는 클립보드를 이용하는 부분이 있습니다❗ 멤버 초대 모달의 '링크 복사하기' 버튼을 클릭하면 URL을 클립보드에 복사하고, 유저 정보 모달의 '이메일 복사하기' 버튼을 클릭하면 유저의 이메일을 복사해요✨ 클립보드를 어떻게 구현해야 할까요..🤔라이브러리를 찾아보기 전에 저의 해답지인 MDN을 찾아볼게요! Clipboard API의 writeText() 메서드를 사용하면 특정 text를 클립보드에 저장하고 Promise를 반환한다고 하네요😀Clipboard API - writeText 사용법async function writeClipboardText(text) { try { await navigator.clipboard.writeText(text); } catch (error) { ..

[맛길] API Routes를 이용한 API 구축

지난번에 Youtube Data API를 사용해 열심히 JSON 데이터를 만들었습니다.처음 사용해 보는 API다 보니 공식문서를 여러 번 읽는 것도 힘들었지만, 이제 빛을 볼 시간입니다🙌🙌🙌 프로젝트에 JSON 데이터를 추가하고 사용해볼게요. 맛길 프로젝트의 기획 포스팅을 보지 않으셨다면, 왜 프로젝트에 JSON 데이터를 일일이 추가하는지 의문이 드실 수 있겠네요😅😅  이번 프로젝트는 CRUD나 로그인 기능을 제외했기 때문에 firebase나 supabase  같은 실시간 DB 서버를 사용하는 것은 조금 과한 것 같아요. 그래서 저는 Next.js에서 지원하는 API Routes를 사용해 볼 겁니다. API Routes는 Next.js에서 Serverless API Endpoint를 만들 수 있..

[Coworkers] 팀 생성 페이지 작업 (feat. 빌드 타임 에러 수정)

이미지 업로드 작업에서 너무 많은 시간을 써버렸네요..😅이미지 업로드 문제를 해결하기 위해 React Hook Form을 정독했으니 팀 생성은 이제 아무것도 아닙니다❗❗ 우선 팀 생성 API를 먼저 작업해 볼게요.팀 생성 APIimport axios from '@/app/lib/instance';export interface PostGroupData { profile?: string; // 프로필 이미지는 선택 사항 name: string;}const postGroup = async (data: PostGroupData) => { const res = await axios.post('groups', data, { headers: { Authorization: `Bearer ${pro..

[Coworkers] 팀 생성 페이지 작업 (API 연동)

공통 컴포넌트 작업을 마무리하고, 오늘부터는 페이지 작업 시작입니다.팀 생성 페이지를 먼저 작업해 보겠습니다❗ 작업 목표 작업에 앞서 피그마 디자인을 먼저 확인해 볼게요👀 팀 이름 Input이 팀원분이 공통으로 작업해 주신 Input 컴포넌트와 유사하게 생겼으니 공통 Input을 사용하면 되겠네요👍 공통 Input 코드더보기 import { MouseEvent, ReactNode, useState } from 'react';import { useFormContext, RegisterOptions } from 'react-hook-form';import IconVisibility from '@/app/components/icons/IconVisibility';import IconInVisibility ..

[Coworkers] Trouble Shooting - 코드 리뷰

Trouble Shooting🚨 상황팀원의 PR(pull request)에서 발견된 버그와 개선 사항 및 수정 방법에 대해 리뷰를 작성했습니다.반응형 화면과 이벤트 관련 테스트도 진행하면서 코멘트를 열심히 남겼는데요..😊 리뷰에 대한 피드백 반영이나 확인 없이 PR이 머지되었습니다...😥 🤔 무엇이 문제였을까요?문제 상황이 왜 발생했는지 고민해봤을 때 아래 3가지 정도가 있는 것 같습니다.  1️⃣ 리뷰 프로세스의 불명확함2️⃣ 의사소통 부족3️⃣ 팀의 리뷰 문화 미정립 다른 리뷰 코멘트는 확인하시고 응답하신 것을 보면 2️⃣번은 아닌 것 같습니다😥 📖 배운 점1️⃣ 의사소통과 피드백 방법의 개선 필요성다시 확인해보니 제가 남긴 리뷰가 모호하거나 딱딱한 어조로 작성되어 요청보다는 단순한 의견으..

[Coworkers] 공통 컴포넌트 Modal

고급 프로젝트 Coworkers의 시작❗ 저는 Modal 공통 컴포넌트를 맡게 되었습니다. 작업을 시작하기 전에 지난 프로젝트에서 팀원분께서 만들어주신 Modal 컴포넌트를 사용할 때 좋았던 점들과 불편했던 점들을 생각해 봤어요🤔좋은 점Modal의 Container만 만들어두고 Content는 children으로 받아 사용할 수 있어 편했음Modal의 dim 영역을 클릭했을 때 닫히는 기능이 있어 편했음불편한 점Modal 컴포넌트를 사용하는 페이지에서 모달의 open 관련 State를 선언하고 관리해야 해서 불편했음DOM 계층의 Depth가 깊어지면 z-index 관련해서 신경쓸 부분이 많아 불편했음Modal의 dim과 컨텐츠가 각각 Dim, Modal 컴포넌트로 분리되어 있어 불편했음위 내용을 고려하..

[맛길] 데이터 채우기 - Youtube Data API

기획 단계에서 Serverless Function을 이용해 유튜브 영상과 상세 내용을 관리하기로 했습니다❗ 흠.. 영상 정보를 어떻게 저장할까요🤔직접 JSON 파일에 작성하기에는 양이 너무 많아 비효율적일 것 같습니다. 저는 구글링을 통해 크롤링과  Youtube Data API를 알게 되었습니다.크롤링이 더 간단한 것 같지만, 프론트엔드 개발자라면 API를 사용하는 게 당연하겠죠👍 사실 크롤링이 유튜브 정책 위반이라는 내용도 있고, 크롤링 관련 재판 사례들이 있는 것 같아서 선택한 것도 없진 않습니다...😅  Youtube Data API 탐색기를 통해서 query에 "먹을텐데"를 검색하니 아래와 같은 결과가 나왔네요. 재생목록의 영상을 가져오려면 아래  2단계를 거쳐야해요.1️⃣ 재생목록 API..

[맛길] 프로젝트 주제 및 기술 스택 선정

🌈 사이드 프로젝트 시작 계기팀 프로젝트를 진행하면서 소통과 협업의 기술을 배울 수 있어 프론트앤드 개발자로서 한 걸음 더 가까워진 것 같아요.그런데 프로젝트 후반으로 갈 수록 저를 포함한 팀원들의 체력과 의욕이 떨어져 기능을 하나씩 빼게 되었습니다. 추가 기능을 구현하고 싶은 제 입장에서는 프로젝트에 대해 만족을 못하고 있는 느낌이 들었어요😂 제가 원하는대로 만들 수 있는 사이드 프로젝트를 한 번 해보면 팀원과의 협업의 소중함도 느끼고 문제 상황도 혼자 해결해 보면서 성장할 것 같아요. 그래서 개인 사이드 프로젝트를 시작하기로 결심했습니다❗❗🤔 사이드 프로젝트 주제 선정막상 프로젝트를 시작하려고 하니 주제 선정부터 쉽지 않았어요..😂일상생활을 하면서 많은 사람들이 느꼈던 불편 또는 이런 것이 있..

[Taskify] Trouble Shooting - 동적 페이지 라우팅

🚫 문제 상황 : 동적 라우팅 ([id].tsx) 페이지에서 새로고침 하면 404 page로 이동한다.문제 원인을 찾지 못해서 vercel 배포 환경 설정이 잘 못 되었는지 확인하기 위해 로컬에서도 빌드를 진행했습니다.빌드 후 next/static 폴더의 리소스를 비교했지만 로컬과 vercel 모두 [id]로 동적 파일을 생성했습니다.어디서부터 잘못된 걸까요...💡 해결 방법팀 회의와 검색을 통해 문제 원인과 해결 방법 여러개 찾아보았는데, 프로젝트에 바로 적용하기에는 어려운 부분들도 있어서 멘토님께 해당 이슈를 공유했습니다. 멘토님의 조언을 통해 해결 방법을 간추려 봤습니다.getServerSideProps 선언해 SSR(Server Side Rendering)로 동작하도록 수정실제로 SSR로 수정..

[Taskify] 1차 배포 테스트(2) - 사용자 편의성 개선

오늘은 저번 이슈 해결에 이어서 사용자 편의성 개선 작업을 해보려고 합니다.🌈 개선 사항 : select 메뉴 버튼이나 옵션 바깥 부분을 클릭했을 때 select 메뉴가 닫히면 좋을 것 같다.멘토님께 피드백을 받고 구글, 네이버 같은 사이트들을 확인해 봤는데 모두 select 메뉴 바깥 부분을 클릭하면 닫히도록 동작하네요👀💡 수정 코드 및 결과/* import, type 등 생략... */function Dropdown({ children, menus, onMenuClick,}: PropsWithChildren) { const { isOpen, toggleDropdown, closeDropdown } = useDropdown(); const ref = useRef(); const hand..