{"id":22985056,"url":"https://github.com/hhejo/moonee","last_synced_at":"2025-10-15T02:22:09.950Z","repository":{"id":258894942,"uuid":"874497773","full_name":"hhejo/moonee","owner":"hhejo","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-24T08:46:27.000Z","size":86,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-24T09:23:25.367Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hhejo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-18T00:02:21.000Z","updated_at":"2024-10-24T08:44:04.000Z","dependencies_parsed_at":"2024-10-27T07:01:51.115Z","dependency_job_id":null,"html_url":"https://github.com/hhejo/moonee","commit_stats":null,"previous_names":["hhejo/moonee"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhejo%2Fmoonee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhejo%2Fmoonee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhejo%2Fmoonee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hhejo%2Fmoonee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hhejo","download_url":"https://codeload.github.com/hhejo/moonee/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246802610,"owners_count":20836369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-15T03:19:53.274Z","updated_at":"2025-10-15T02:22:09.839Z","avatar_url":"https://github.com/hhejo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 무니 (MooNee)\n\n## 요약\n\n\u003e indexedDB를 이용한 오프라인 가계부 웹 앱\n\n![무니 (MooNee)](./assets/000-moonee-main.png)\n\n## 상세\n\n5번째 PJT\n\n### 0. 목차\n\n1. 소개\n2. 기술 스택\n3. 느낀 점\n4. 기능 (페이지 구성)\n5. 아쉬웠던 부분\n6. 앞으로 학습할 것들, 나아갈 방향\n7. 어려웠던 부분, 해결한 과정\n\n### 1. 소개\n\n**[무니 (MooNee)](https://hhejo.github.io/moonee/)**\n\n- indexedDB를 이용한 오프라인 가계부 웹 앱\n- 간단하게 가계부를 작성하고 관리\n- 지출, 수입 항목을 작성하고 조회\n- 전체, 날짜별, 지출별, 수입별로 항목 조회\n- 총 지출, 수입, 합계 조회\n- 모든 내역을 CSV 파일로 내보내기\n\n작업 기간\n\n- 2024/10, 1주\n\n인력 구성\n\n- 1인\n\n### 2. 기술 스택\n\n\u003cimg src=\"https://img.shields.io/badge/JavaScript-F7DF1E?style=for-the-badge\u0026logo=JavaScript\u0026logoColor=black\"\u003e \u003cimg src=\"https://img.shields.io/badge/Vite-646CFF?style=for-the-badge\u0026logo=Vite\u0026logoColor=white\"\u003e \u003cimg src=\"https://img.shields.io/badge/Tailwindcss-06B6D4?style=for-the-badge\u0026logo=Tailwindcss\u0026logoColor=white\"\u003e\n\n### 3. 느낀 점\n\n- indexedDB를 이용해 오프라인 웹 애플리케이션 제작\n- localStore를 이용하는 것도 괜찮지만, 좀 더 관리되는 DB라서 기능이 누적될수록 좋을 것 같았음\n- JavaScript만으로는 늘어나는 코드를 관리하기가 아주 힘들었음\n- 커스텀 이벤트를 처음 사용해보니 그렇게 어렵지 않고 유용해서 나중에도 활용하고 싶다는 생각이 들었음\n\n### 4. 기능 (페이지 구성)\n\n1. 메인 페이지\n   - 이번 달 총 수입, 지출의 합계 출력\n   - 이번 달 총 수입, 총 지출 출력\n   - 새로운 거래내역을 추가하는 버튼\n   - 해당 버튼 클릭 시 사라지면서 거래내역 폼 보이기\n2. 거래내역 추가 양식\n   - 수입, 지출 중 하나 선택해서 클릭\n   - 날짜 입력\n   - 금액 입력 (3자리마다 쉼표 처리)\n   - 내용 입력\n   - 취소하기 버튼을 누르면 폼 사라지고 거래내역 추가 버튼 다시 드러남\n   - 저장하기 버튼을 누르면 폼 사라지고 거래내역 추가 버튼 다시 드러나며 거래내역이 생성됨\n3. 거래내역 목록\n   - 날짜마다 거래내역을 모아 출력\n   - 전체, 수입, 지출 버튼을 눌러 해당 항목만 출력\n4. CSV 파일 내보내기\n   - 해당 버튼을 눌러 전체 거래내역을 CSV 파일로 저장\n\n|                                              |                                                 |                                           |\n| :------------------------------------------: | :---------------------------------------------: | :---------------------------------------: |\n|      ![메인 화면](./assets/01-main.PNG)      |    ![거래내역 추가 폼](./assets/02-form.PNG)    |   ![거래내역 입력](./assets/03-add.PNG)   |\n|    ![거래내역 목록](./assets/04-list.PNG)    |     ![수입 필터링](./assets/05-income.PNG)      |  ![지출 필터링](./assets/06-expense.PNG)  |\n| ![거래내역 내보내기](./assets/07-export.PNG) | ![거래내역 내보내기 2](./assets/08-export2.PNG) | ![거래내역 CSV 파일](./assets/09-csv.PNG) |\n\n시연 영상\n\n- `assets` 폴더에 위치\n\n### 5. 아쉬웠던 부분\n\n- 거래내역 수정 기능을 추가하고 싶었지만 하지 못해 아쉬움\n- 로그인, 거래내역 동기화 기능을 추가하고 싶었음\n- 모바일 웹 앱으로 구현했는데, 크롬과 모바일 사파리에서 다르게 보이는 것을 생각하지 못하고 구현해서 아쉬움\n- 더 많은 필터 기능\n- 검색 기능\n- 태그, 메모 기능\n\n### 6. 앞으로 학습할 것들, 나아갈 방향\n\n- `React`를 사용해서 현재 프로젝트를 더 확장하고 싶고, 다른 사람이 사용하게 하면 좋겠음\n\n### 7. 어려웠던 부분, 해결한 과정\n\nindexedDB\n\n- 처음 사용해보는 웹 스토리지 기능이어서 검색, 문서 읽기를 통해 구현\n- 다른 DB와 기능은 비슷했지만, 좀 다른 점이 있었고(버전 등) 명칭이 달라 약간 낯설었음\n\nCSS, TailwindCSS\n\n- Flex 자식 요소들이 너비를 갖지 않아 헤매다가, 부모 요소, 자식 요소에 `w-full` 클래스를 주어 해결\n- 거래내역 생성 폼에서 수입·지출 버튼을 라디오 버튼으로 만드는 중에 라디오 버튼을 꾸미기 힘들어 시간이 걸렸지만, `\u003clabel\u003e` 태그 안에 `\u003cinput type=\"radio /\u003e`와 `\u003cdiv\u003e` 태그를 넣어 해결. `\u003cinput /\u003e` 태그를 숨기는 트릭과 `peer`에 대해 알게 되었음\n\nJavaScript\n\n- `Intl` API를 통해 손쉽게 금액의 세자리수마다 쉼표를 찍어줄 수 있었음. 폼에 입력할 때도 쉼표를 붙여줌\n- 파일 분할이 되지 않아 늘어나는 코드를 관리하기 힘들었음. 결국 `Vite`를 사용해 프로젝트 관리\n- 파일을 분할해서 UI 관련 기능, indexedDB 접근 관련 기능, 기타 로직을 나누고 싶었음\n  - UI 관련 함수에서 또 다른 함수를 호출하는데 그 함수는 indexedDB 관련 함수를 호출하는 등 코드 흐름이 복잡해져서 관리가 힘들어 고민\n  - 각자 할 일만 하고, 커스텀 이벤트를 통해 해당 이벤트 핸들러에서 로직 관리\n  - `document`의 이벤트 핸들러는 모두 `index.js`에서 관리. 보기 편하고 관리하기 좋아짐\n  - 작업 흐름이 보여 관리하기 쉬워져 만족\n- `document.addEventListener`에 등록하는 콜백을 `async` 함수로 해도 될지 찾아봤는데 문제 없을 것 같아 적용\n- 분리한 파일들의 이름을 어떻게 지을지 고민이 됐음\n  - 해당 파일에서 UI 등록하는 부분, 다른 로직을 담당하는 부분을 더 나눌까 고민했지만 코드 양이 그렇게 많지 않아 나누지 않음\n- `Vite` 번들러를 이용해 모듈로 나눈 경우(`type: \"module\"`이 된 경우), `index.html`에서 이벤트 핸들러 인식이 되지 않아 `window` 객체에 전역으로 등록해서 해결\n\n날짜 헤딩 넣기\n\n배포 (GitHub Pages)\n\n- `GitHub Pages`에 배포가 잘 되지 않는 문제\n  - 배포된 사이트에 들어가보니, `html` 파일만 있고 `js` 파일을 불러오지 못한 것 같아 네트워크 탭으로 확인해보니, `style.css` 파일과 `js` 파일 일부분을 불러오는 데에 실패\n  - 해당 `js` 파일은 다른 파일에서 불러올 때 파일 이름에 `.js`를 명시해주지 않아 불러오는 데에 실패함\n  - `\u003clink /\u003e` 태그에서 `href=\"src/style.css\"`라고 썼어야 하는데, `/src` 라고 작성해서 실패. 작성을 잘 하자\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhejo%2Fmoonee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhhejo%2Fmoonee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhhejo%2Fmoonee/lists"}