Skip to content
/ Dpay Public

개인프로젝트 - 모임 비용 정산을 간단하게 할 수 있는 웹 애플리케이션

Notifications You must be signed in to change notification settings

dmswnlee/Dpay

Repository files navigation

디페이(Dpay)

친구, 지인들과의 모임이나 여행 시 결제한 비용들을 입력하여 간편하게 정산할 수 있도록 돕는 더치페이 서비스입니다.
모임을 생성하여 멤버, 날짜, 사용한 비용을 입력하면 그 내용을 한눈에 확인할 수 있습니다.
입력된 데이터를 바탕으로 정산 결과를 바로 확인할 수 있어 복잡한 정산 과정을 간소화하고 편리하게 비용 관리를 할 수 있는 웹 애플리케이션입니다.


➗ 배포한 사이트
https://dpay-two.vercel.app/


➗ 프로젝트 기간
2024.10.19 ~ 2024.11.23


➗ 개발 스택

  • 빌드 : React.js
  • 언어 : TypeScript
  • 호스팅 : Vercel
  • 데이터 & Autentication : supabase
  • 패키지매니저 : npm
  • 라이브러리
    • 상태관리 : zustand
    • CSS 스타일링 : Styled-component
    • UI 컴포넌트 : Chakra UI
    • 테스트 : RTL + Jest

➗ 디렉토리 구조

src
|-- assets
|-- components
|   |-- shared
|-- hooks
|-- pages
|   |-- CreateGroup.tsx
|   |-- ExpenseMain.tsx
|   |-- Home.tsx
|   |-- Login.tsx
|   |-- MyPage.tsx
|   |-- Signup.tsx
|-- store
|-- types   
|   |-- expense.ts
|   |-- formData.ts
|   |-- group.ts
|-- UI


기능구현

회원가입

signup

  • 그룹 생성 기능을 사용하기 위해서는 회원가입 필요
  • supabase 인증 기능을 활용한 회원가입 진행
  • 폼 유효성 검증을 통해 조건을 충족한 뒤 가입하기 버튼 클릭 시 가입완료

로그인

login


그룹 생성

create

  • 모임 이름, 멤버, 날짜 입력 후 생성하기 버튼 클릭 시 그룹 생성

비용 입력

expense

  • 비용 입력 폼의 유효성 검증 조건에 맞게 입력
  • 날짜, 비용 내용, 메모, 비용, 결제한 멤버 입력 후 추가하기 클릭 시 비용 리스트에 추가
  • 비용 추가 할 때마다 정산 결과에 실시간 반영

비용 삭제 및 내보내기

export

  • 삭제 버튼 클릭 시 해당 비용 삭제
  • 정산결과에 있는 내보내기 버튼 클릭 시 png 파일로 저장

공유하기

share

  • 페이지 하단에 있는 공유 버튼 클릭 시 해당 그룹 url 클립보드에 저장
  • url을 통해 해당 모임 멤버에게 모임 공유 가능

마이페이지

mypage

  • 마이페이지에서 회원 정보 확인 가능
  • 마이페이지에 있는 모임 내역에서만 모임들 삭제 가능


💡 supabase를 통해 회원가입, 로그인, 데이터 저장 기능 구현

import { createClient } from "@supabase/supabase-js";

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseKey = import.meta.env.VITE_SUPABASE_KEY;

export const supabase = createClient(supabaseUrl, supabaseKey);

💡 프로젝트에서 입력되는 상태들은 zustand를 사용해 관리

import { create } from "zustand";

interface GroupState {
	groupName: string;
	tags: string[];
	startDate: string;
	endDate: string;
	setGroupName: (name: string) => void;
	addTag: (tag: string) => void;
	removeTag: (tag: string) => void;
	setTags: (tags: string[]) => void;
	setStartDate: (date: string) => void;
	setEndDate: (date: string) => void;
}

export const useGroupStore = create<GroupState>(set => ({
	groupName: "",
	tags: [],
	startDate: "",
	endDate: "",
	setGroupName: name => set({ groupName: name }),
	addTag: tag => set(state => ({ tags: [...state.tags, tag] })),
	removeTag: tagToRemove => set(state => ({ tags: state.tags.filter(tag => tag !== tagToRemove) })),
	setTags: (tags) => set({ tags }),
	setStartDate: date => set({ startDate: date }),
	setEndDate: date => set({ endDate: date }),
}));

💡 html-to-image 라이브러리를 사용해 이미지 내보내기 구현

const exportToImage = () => {
		if (wrapperElement.current === null) {
			return;
		}

		toPng(wrapperElement.current, {
			filter: node => node.tagName !== "BUTTON",
		})
			.then(dataURL => {
				const link = document.createElement("a");
				link.href = dataURL;
				link.download = "settlement-summary.png";
				link.click();
			})
			.catch(err => {
				console.error("이미지를 다운로드하는 중 오류가 발생했습니다:", err);
			});
	};

💡 웹에서 제공하는 Web Share API를 활용한 공유 기능 구현

	const handleSharing = () => {
		if (navigator.userAgent.match(/iphone|android/i) && navigator.share) {
			navigator.share({
				url: window.location.href,
			});
		} else {
			navigator.clipboard.writeText(window.location.href).then(() => {
				alert("공유 링크가 클립 보드에 복사 되었습니다.");
			});
		}
	};


About

개인프로젝트 - 모임 비용 정산을 간단하게 할 수 있는 웹 애플리케이션

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published