PWA 추가 유저들 대부분 모바일 환경에서 사용하고있어, PWA(Progressive Web App)를 추가했다. 보통 CRA로 리액트 환경을 만들때 PWA를 사용하지만, 나는 CRA도 사용하지 않았고 이미 개발도 어느정도 완료가 된 상태여서 PWA를 추가하는 방식으로 찾아봤다. PWA란? 웹 앱을 웹 브라우저 API와 결합하여 크로스플랫폼 동작하는 앱으로 만들 수 있다. PWA는 한 번 릴리즈 하고 나서 앱을 다시 배포 할 필요 없이 지속적으로 수정할 수 있다. 모든 코드가 서버에서 호스팅되고 APK나 IPA의 일부가 아니기 때문에 어떤 변경이든 실시간으로 적용할 수 있는 것이다. 네트워크 연결에 의존하는 앱은, 네트워크 연결이 없을 때 아무것도 할 수 없게 된다. PWA는 네트워크에 문제가 있어도 유..
유저명/타이틀 변경, 계정 삭제 기능 추가 수정 버튼 클릭 시 flag State 변경으로 수정모드로 변경한다. const onEditHandler = useCallback(() => { setIsEditing((prev) => !prev); }, []); {isEditing ? ( ) : ( {userName} {userTitle} )} {isEditing ? ( 저장 ) : ( 수정 )} 포스트 변경과 동일한 구조로 유저명과 유저타이틀도 변경된 내용을 POST로 서버로 보낸다. const onEditUserSubmit = useCallback( (e) => { e.preventDefault(); const regexp = /^[가-힣.,?;^_!%\s]+$/g; if (editName) { if (e..
유저 아바타 AWS S3에 저장 서버 하드에 저장하면 서버 재배포 시 새로 생긴 경로는 모조리 삭제되서 초기화된다.. 이 문제를 마주하고 처음에는 서버를 재배포 할 때마다 서버에 있는 새로 생긴 폴더를 다 다운받으면 되지 않을까? 하는 생각을 했다. 크롬 확장도구인 Resources Saver를 사용하면 해당 페이지의 개발자 도구-Resources 탭에서 볼 수 있는 모든 파일을 다운해준다. 하지만 이 방법은 서버를 배포하기 전에 항상 내가 수동으로 작업해야하고, 한 번이라도 잊어버리면 모든 유저 이미지를 날릴 수 있는 위험이 있었다. AWS S3를 사용하기로 마음을 먹는데.. 프론트엔드를 시작해서 서버구축도 해보고 NoSQL도 생성해보고 많은 성장을 하고 있지만 AWS라는 단어는 조금 무서웠다. 하지만..
유저 아바타 변경 기능 multer를 사용해보자 이미지 업로드 버튼 클릭 시 파일을 첨부할 수 있도록 input태그를 사용했다. 이미지 업로드 onUploadHandler 함수 실행 시 유저가 input창에서 선택했던 파일을 FormData를 사용해 avatar라는 키의 값으로 넣어준다. 그리고 post통신으로 서버에 데이터를 보낸다. body에는 formData가 들어간다. const onUploadHandler = useCallback( (e) => { e.preventDefault(); const formData = new FormData(); formData.append('avatar', e.target.files[0]); fetch(`${process.env.API_SERVER}/api/user..
프로젝트명 변경 왜? 이제와서? 기존의 Life Is a Sentence, 즉 LIS 는 독특하고 기억에 남기 때문에 좋은 옵션이지만, 웹이 무엇을 하는지 처음에는 사용자에게 명확하지 않을 수 있다고 생각했다. 제작 하면서도 더 좋은 제목을 생각했고 SentenceU는 문장 공유 서비스에 대한 명확한 목적을 보여줄 것 같았다. 그래서 최종적으로 SENTENCE U 센텐스유로 결정했다. 무료 라이선스 폰트로 일단 간단하게 로고도 만들었다. 나는 프론트엔드 개발자가 될꺼다. 디자이너가 아닌. 서버 배포 처음부터 서버는 클라우드타입을 통해 배포를 하려했다. 모두의 플랫폼팀, 클라우드타입 클라우드타입은 클라우드 기반 애플리케이션을 빠르게 개발하고 배포할 수 있는 클라우드 애플리케이션 플랫폼입니다. cloudty..
포스트 리스트 날짜별로 구분 최신글 처럼 날짜별로 보이면 좋을 것 같은 리스트는 섹션별로 나눠서 보여주는 것이 좋을 것 같았다. dayjs를 사용해서 postList라는 매개변수를 받아 그 글의 createdAt을 최신순으로 MM월 DD일 ddd요일 형태로 새로운 배열에 추가한다. import dayjs from 'dayjs'; import 'dayjs/locale/ko'; dayjs.locale('ko'); export const makeSection = (postList) => { const sections = {}; postList.forEach((post) => { const monthDate = dayjs(post.createdAt).format('MM월 DD일 ddd요일'); if (Array..
DIARY, REQUEST페이지 제외 하고 모든 UI 작성 완료 홈페이지와 개인 프로필 페이지의 UI는 완성했다. 다이어리 페이지에는 캘린더와 유저 본인만 볼수있는 다이어리 리스트를 추가할 것이고, 요청페이지에는 관리자에게 보낼수있는 요청사항을 담은 Form을 추가할 것이다. 유저의 ID, 이름, 이미지, 접속상태 가져오는 useQuery 통합 기존에 서버에서 res.data를 가지고와 useQuery의 data에 할당해 객체의 값을 가져오려고 시도했었는데 계속 객체의 키에 접근이 불가능했다. 그래서 서버에서 받을때 특정 키 값만 리턴받아 전부 따로 함수로 내보냈다. import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; ..
글 CRUD 기능 완성 (수정/삭제) 일단 수정/삭제 기능을 추가하기 위해서 post카드를 클릭했을 때 수정버튼과 삭제버튼이 나오도록 구현했다. post카드를 눌렀을때 높이를 조절하는 것은 ref와 css를 사용해서 적용했다. 처음에는 state를 사용해서 emotion props로 보냈는데, state가 바뀔때마다 post카드가 리렌더링 되는 바람에 useRef를 사용했다. postContainer 자체에 ref를 적용하고 그 안에있는 PostWrap에 onClick이벤트를 줬다. PostWrap이 클릭되면 Container에 클래스'open'을 추가/삭제하는 기능이다. 이 때 like버튼을 클릭할 경우에는 열리지 않도록 클릭한 것이 svg나 path인 경우에는 동작하지 않도록 했다. 추가로 유저가 수..
메인페이지 UI완성 layout은 아래와 같이 나눴다. 상단에는 NavBar와 네이버 명언에서 크롤링해온 데이터가나오는 롤링배너를 위치시켰다. 메뉴의 구성은 아래와 같이 나눴다. Write : 글쓰기 Collection : 좋아요 누른 글만 모아보는 페이지 Diary : 한줄일기를 작성할 수 있는 페이지 Request : 요청사항을 적는 페이지 홈의 왼쪽 구간에는 사이트에 대한 설명과 인기글 3개를 보여준다. GIF이미지는 여러 이야기들이 한공간에 모이는 느낌이 드는 이미지로 선정했다. 가운데 구간은 최신글 리스트를 보여준다. react-scrollbar를 사용하여 스크롤이 가능하도록 구현했다. 마지막으로 오른쪽 구간은 접속중인 유저목록과 글쓰기 플로팅 버튼을 보여준다. 온라인 유저가 리스트 처음으로 오..
NavBar UI 스타일 적용 NavBar의 프로필 부분을 모달창의 컴포넌트는 만들어놨지만 작동을 안해서 수정할 경 스타일을 적용했다. 약간 어두운 흰색을 배경으로 채도가 조금 빠진 검정색을 이용했다. 유저프로필쪽에 호버를 하면 메뉴가 내려오도록 꾸몄다. 로그인 하지 않은 상태의 기본 모습 로그인 한 상태의 기본 모습 로그인 한 상태에서 호버하면 나타나는 메뉴 로그아웃 한 상태에서 호버하면 나타나는 메뉴 메인페이지 명언 칸 명언데이터 크롤링 기존에 빈 칸이였던 자리에 여러 유명인사들의 명언들을 보여주도록 크롤링 하는법을 찾아봤다. 많은 난항이 있었다... 일단 get메소드로 html파일을 가져오고 cheerio라이브러리를 사용해 html파일에서 원하는 클래스 혹은 태그에서 데이터를 가져왔다. await ..