데이터도 잘 다루고 글도 잘 쓰고 그림도 잘 그리는 개발자가 되고싶다
블로그
전체 42025. 03. 30.
0
워밍업클럽 - 풀스택 4주차 발자국
4주차는 인스타그램 클론 프로젝트와 이제까지 만들었던 프로젝트들을 배포하는 과정을 배웠다.가장 먼저 만든 페이지는 회원가입/로그인을 위한 페이지이다. Input 태그 두 개를 사용해서 이메일과 비밀번호를 입력받을 수 있게 만들었고, 로그인 화면에서도 비슷한 UI를 사용했다.otp 발급과 인증을 위한 코드는 이렇게 작성되었다. const verifyOtpMutation = useMutation({ mutationFn: async () => { const { data, error } = await supabase.auth.verifyOtp({ type: "signup", email, token: otp, }); if (data) { console.log(data); } if (error) { alert(error.message); } }, }); { if (confirmationRequired) { verifyOtpMutation.mutate(); } else { signupMutation.mutate(); } }} loading={ confirmationRequired ? verifyOtpMutation.isPending : signupMutation.isPending } disabled={ confirmationRequired ? verifyOtpMutation.isPending : signupMutation.isPending } color="light-blue" className="w-full text-md py-1" > {confirmationRequired ? "인증하기" : "가입하기"} 이메일을 입력하고 회원가입을 누르면 supabase와 연동되어 가입 확인 메일을 보낼 수 있다. 링크를 클릭하면 리다이렉트 되어 회원가입을 계속 진행하는 방법과, 이메일에 쓰여진 OTP를 입력하여 인증을 받는 두 가지 방법을 모두 배울 수 있었다. 이메일에 쓰여진 코드로 인증하면 회원가입이 완료되고 바로 메인 페이지로 이동한다. 사이드 메뉴의 가장 아래 chat 메뉴를 클릭하면 대화방이 나타난다. 유저를 선택해서 메시지를 보낼 수 있다. 개인 대화방만 구현되어 있다. 내가 보낸 메세지는 파란색으로, 상대방이 보낸 메세지는 회색으로 나타난다. 파라미터 값 하나로 구현할 수 있는 단순한 기능이라는 게 신기했다.나와 상대방이 보낸 메세지를 구분하는 코드는 이렇게 작성되었다."use client"; export default function Message({ isFromMe, message }) { return ( {message} ); } 4주차 + 최종 후기실시간 대화라는 기능이 생각한 것보다 더 간단하게 만들 수 있다는 것에 놀랐다. 프로젝트를 시작하기 전에는 복잡하고 어렵게 구현해야 할 거 같았던 기능들을 쉽게 구현할 수 있다는 것이 신기했다.이번 인프런 워밍업클럽을 통해 supabase를 처음 알게 되었다. 데이터베이스, 스토리지부터 인증 시스템까지 많은 것들이 구현되어 있어서 간단한 개인 프로젝트를 만들 때 유용하게 쓰일 거 같다.다음 주에는 supabase를 활용한 간단한 기능들을 혼자 만들면서 시스템에 익숙해지려고 한다. 이번 워밍업클럽은 next.js, typescript 같은 기술 스택과 함께 유용한 기능들을 많이 알아갈 수 있어서 좋은 시간이었다.
2025. 03. 23.
0
워밍업클럽 - 풀스택 3주차 발자국
3주차는 넷플릭스 클론 프로젝트였다.3주차에서 배운 것들은csv로 저장된 데이터를 DB에 올리는 법DB에 저장된 데이터를 가져오는 법무한 스크롤을 구현하는 방법그리드를 사용해서 요소들을 배치하는 법/[id] 폴더를 만들어 동적 페이지를 만드는 법이런 것들을 배웠다. 지금 진행 중인 팀 프로젝트에서도 동적 페이지와 그리드 배치는 적용할 수 있어 보여서 이번 주 강의도 열심히 들었다. 과제그리고 이번 주의 과제는 찜하기 기능을 만들어서 내가 찜한 영화를 메인 페이지 리스트 최상단에 뜨도록 하는 것이었다. 찜한 목록과 그렇지 않은 목록을 별도로 만들어서 구현할 수도 있었지만, 그냥 단순하게 찜한 영화를 최상위 리스트로 열거하는 방법을 적용했다. 일단 supabase로 들어가서 찜한 영화를 표시할 수 있는 새로운 컬럼을 하나 만들었다.dibs_on이라는 이름의, bool 값이 저장되는 컬럼이다. 기본값은 false로 지정했다.영화의 상세 페이지에 접속하면 '찜하기' 기능을 쓸 수 있도록 만들었다. 나의 넷플릭스 이용 패턴과 동일하게, 영화나 드라마의 상세 정보를 확인한 다음 찜할 수 있는 유저 시나리오이다.상세 페이지에 접속하면 찜하기 버튼이 나오고, 이 버튼을 누르면 클릭 이벤트가 실행되면서 DB까지 찜한 상태를 동기화한다.찜하기 버튼은 영화 이름 옆에 나오도록 배치했다.찜하기를 누르면 실행되는 함수이다. 찜하기 버튼을 누르면 true와 false의 값이 바뀌고, 바뀐 값을 setDibsOn 함수로 전달한다.movieActions.ts에 setDibsOn 함수를 구현했다. DB까지 상태값의 변화를 전달해준다.이제 웹으로 돌아와서 적당히 아래쪽에 있는 영화의 상세페이지로 들어간다. 찜하기 버튼을 누르고 메인 페이지로 돌아오면 아까 찜했던 영화가 제일 첫 리스트로 나타난다.찜하기 전은 하얀 하트, 찜한 후는 빨간색 하트로 표시된다. 메인 페이지로 돌아오면 아까 찜한 영화가 제일 첫 리스트로 나타난다! 과제 끝! 3주차 후기평일에는 부트캠프 팀 프로젝트를 하고 있어서 매주 금, 토, 일 강의를 듣고 일요일에 과제를 한다. 시간 텀이 길어서인지 cmd에서 supabase로 로그인을 하고 db 데이터를 가져오는 과정이 매주 헷갈린다. 프로젝트를 생성하는 초기 설정에서도 매주 비슷한 지점에서 버벅거리는 것 같다. 다음 4주차에는 시간을 좀 더 내서 이제까지의 설정 과정들을 한 번 더 정리하고, 평일에도 조금씩 강의를 듣고 실습해야겠다는 다짐을 했다.
2025. 03. 15.
0
워밍업클럽 - 풀스택 2주차 발자국
이번 주에는 드랍박스를 클론코딩하는 프로젝트를 진행했다.이번 프로젝트에서 새로 배운 것들을 정리해보자면, useDropzone: 파일을 드래그 앤 드롭으로 업로드할 수 있는 섹션을 만든다. const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, multiple: true, });이 부분에서 getRootProps, getInputProps는 ()를 붙여서 사용해야 하는데 그걸 또 빼먹어서 오류가 났다. 콜백으로 사용하는 함수와의 차이를 확실히 공부할 필요가 있어 보인다... 스토리지에 데이터를 업로드하고 정보를 가져오기- upload, search, delete const results = await Promise.all( files.map((file) => { supabase.storage .from(process.env.NEXT_PUBLIC_STORAGE_BUCKET) .upload(file.name, file, { upsert: true }); }) );스토리지에 파일을 등록하고 삭제하거나 조회할 수 있는 기능을 구현했다. 혼자서 구현할 때는 꽤 복잡하게 했던 거 같은데 엄청 편리하게 구현한 것 같다.따로 진행 중인 팀 프로젝트에서 데이터 업로드에 고생을 하고 있는데, 잘 배워놓으면 더 편하게 업로드를 구현할 수 있을 거 같다. supabase를 제대로 배워봐야겠다는 생각이 든다. 과제: 최종 수정 시간 표시하기 image에 포함된 updated_at 속성을 파일 제목 아래에 작은 글씨로 표시되게 만들었다.먼저 개발자 도구와 console.log(image)로 image 객체에 포함된 정보들을 확인해주고,수정된 날짜를 나타내는 updated_at을 찾아 파일명 아래에 포함시켰다. {/* updated_at */} 수정된 시간: {formattedDate}날짜를 좀 더 보기 쉽게 나타내기 위해서 포맷도 지정해 줬다. const formattedDate = new Date(image.updated_at).toLocaleString("ko-KR", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hour12: true, }); 후기 기본적인 CRUD 기능이기 때문에 어디에서나 쓰인다는 걸 팀 프로젝트를 진행하면서 느끼고 있다. 꼭 필요한 기능이니 워밍업 클럽 완주 이후에도 다시 공부해야겠다.클론 코딩을 하면서도 놓치는 부분이 많다는 걸 또다시 느끼고 있다. 노션과 깃허브 코드를 다시 살펴보면서 제대로 정리해 볼 생각이다.
2025. 03. 09.
0
워밍업클럽 - 풀스택 1주차 발자국
풀스택 개발자가 되어 보겠다고 리액트, 자바스크립트, 자바, 스프링부트 이런 것들을 공부하긴 했지만 머릿속으로는 잘 정리가 되지 않았다.실제로 구동하는 웹 사이트를 만들어보며 배우는 게 가장 빠를 것이라 생각하고 워밍업클럽에 참여하게 되었다. 1주차는 supabase를 써서 간단한 투두 리스트를 만드는 것이었다.useState같은 것들은 리액트를 공부하며 미리 봐 두어서 조금은 익숙했다. 과제로는 리스트의 제목 옆에 생성 시간과 완료 시간을 띄워야 했는데, 뭔가 좀 애매하게 돌아갔다.미션으로 생성 시간을 띄우는 건 무난하게 했는데,완료 시간은 새로고침할 때마다 사라지는 걸 보니 데이터베이스에 업데이트는 안 되는 것 같다. 일단 가장 먼저 완료 시간을 기록할 컬럼을 supabase 테이블에 추가했다.그 다음으로는 코드를 봤다.생성 시간과 완료 시간을 띄우는 부분은 todo.tsx에다가 만들었고,저 두 시간은 상태로 관리해야 할 거 같아서 useState도 추가했다.console.log로 변수 이름을 확인하고 checked를 누르면 완료 시간이 찍히도록 해 봤는데여기서 뭔가 많이 놓친 거 같다. 나중에 수정하려고 따로 표시해뒀다.이렇게까지 해서 checked가 변화하면 완료 시간이 뜨는 이상한 기능이 만들어졌다. 보완해야 하는데... 일단 강의를 한 번 더 들어야 할 것 같다... 다른 강의를 들으면서 '버전에 따라 호환이 안 되는 기능도 많으니 버전을 확실히 확인해라'는 말을 여러 번 들었는데, 이번 강의에서 그걸 뼈저리게 느꼈다.어제오늘 합쳐서 7시간동안 왜 에러가 나는지 코드를 찾고 고치고 찾고 고치고, node를 다시 설치해보고 별 걸 다 했던 것 같다밀린 강의를 어제 오늘 몰아들으면서 버전 충돌 때문에 하루 종일 방법을 찾았더니 머리가 아파서 여기까지만 해 보기로 했다 1주차 후기는... 엄청 어려웠다.따라 만들고 기능을 어떻게 돌아가게는 하는 건 어렵지 않은데 처음 배울 때 그 익숙하지 않는다는 점이 어려웠다.그래도 2주차부터는 완전히 새로운 문법보다는 기능 구현이 위주라 다행인 것 같다! 다음 주부터는 강의 안 미루고 열심히 들어야겠다.