일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 패스트캠퍼스후기
- 오공완
- 프로그래머스
- 직장인인강
- swift
- 스위프트
- Components
- stopPropagation
- ios
- 패캠인강후기
- 코딩테스트
- 패스트캠퍼스
- HTML
- 연결리스트생성
- 사이드프로젝트10개기술스택으로구현하는풀스택서버리스프로젝트withReact
- 연결리스트삭제
- 수강료0원챌린지
- 직장인자기계발
- 이벤트캡처링
- MVMM
- 실패율
- eventcapturing
- hig
- 자료구조
- 이벤트버블링
- 패캠챌린지
- 연결리스트삽입
- JavaScript
- 환급챌린지
- eventbubbling
- Today
- Total
날쌘 개발자
프로젝트 구현(12) - 정산 결과 컴포넌트 구현 본문
패스트캠퍼스 환급챌린지
드디어 마지막날이다!
비록 프로젝트는 30일만에 완성하지못했지만, 차근차근 강의를 따라가며 완성해볼 생각이다.
오늘 해볼 것은 더치페이 서비스의 주 기능이라고 할 수있는,
정산 메인페이지의 좌측 하단에 위치할 정산 결과 컴포넌트 이다
먼저, 정산결과컴포넌트를 만들어줄 SettlementSummary 파일을 만들어준다.
만든 후 ExpenseMain의 LeftPane 내부에 주석처리 해놓았던 정산결과컴포넌트 렌더링 부분을 다음과 같이 수정한다.
const LeftPane = () => (
<Container>
<StyledGapRow>
<Row>
<ServiceLogo />
</Row>
<Row>
<AddExpenseForm />
</Row>
<Row>
<SettlementSummary />
</Row>
</StyledGapRow>
</Container>
)
이제 SettlementSummary만 완성시켜주면 프론트면에서는 어느정도 완성된 모습이 보일것같았는데
언뜻 생각해보면 그냥 사람 수대로 돈을 나눠서 알려주면 되는거 아닌가? 했던거에 비해 생각보다 고려할것이 많고 복잡했다..
SettlementSummary.jsx
import { useRecoilValue } from "recoil"
import styled from "styled-components"
import { expensesState } from "../state/expenses"
import { groupMembersState } from "../state/groupMembers"
import { StyledTitle } from "./AddExpenseForm"
export const calculateMinimumTransaction = (expenses, members, amountPerPerson) => {
const minTransactions = []
if (amountPerPerson === 0) {
return minTransactions
}
// 1. 사람별로 냈어야 할 금액
const membersToPay = {}
members.forEach(member => {
membersToPay[member] = amountPerPerson
})
// 2. 사람별로 냈어야 할 금액 업데이트
expenses.forEach(({ payer, amount }) => {
membersToPay[payer] -= amount
})
// 3. amount 별로 오름차순으로 sorting된 리스트(배열)
const sortedMembersToPay = Object.keys(membersToPay)
.map(member => (
{ member: member, amount: membersToPay[member] }
))
.sort((a, b) => a.amount - b.amount)
var left = 0
var right = sortedMembersToPay.length - 1
while (left < right) {
while (left < right && sortedMembersToPay[left].amount === 0) {
left++
}
while (left < right && sortedMembersToPay[right].amount === 0) {
right--
}
const toReceive = sortedMembersToPay[left]
const toSend = sortedMembersToPay[right]
const amountToReceive = Math.abs(toReceive.amount)
const amountToSend = Math.abs(toSend.amount)
if (amountToSend > amountToReceive) {
minTransactions.push({
receiver: toReceive.member,
sender: toSend.member,
amount: amountToReceive,
})
toReceive.amount = 0
toSend.amount -= amountToReceive
left++
}
else {
minTransactions.push({
receiver: toReceive.member,
sender: toSend.member,
amount: amountToSend
})
toSend.amount = 0
toReceive.amount += amountToSend
right--
}
}
return minTransactions
}
export const SettlementSummary = () => {
const expenses = useRecoilValue(expensesState)
const members = useRecoilValue(groupMembersState)
const totalExpenseAmount = parseInt(expenses.reduce((prevAmount, curExpense) => prevAmount + parseInt(curExpense.amount), 0))
const groupMembersCount = members.length
const splitAmount = totalExpenseAmount / groupMembersCount
const minimumTransaction = calculateMinimumTransaction(expenses, members, splitAmount)
return (
<StyledWrapper>
<StyledTitle>2. 정산은 이렇게!</StyledTitle>
{totalExpenseAmount > 0 && groupMembersCount > 0 && (
<>
<StyledSummary>
<span>{groupMembersCount} 명이서 총 {totalExpenseAmount} 원 지출</span>
<br />
<span>한 사람 당 {splitAmount} 원</span>
</StyledSummary>
<StyledUl>
{minimumTransaction.map(({ sender, receiver, amount }, index) =>
<li key={`transaction-${index}`}>
<span>{sender}가 {receiver}에게 {amount} 원 보내기</span>
</li>
)}
</StyledUl>
</>
)}
</StyledWrapper>
)
}
const StyledWrapper = styled.div`
padding: 50px;
background-color: #683BA1;
color: #FFFBFB;
box-shadow: 3px 0px 4px rgba(0, 0, 0, 0.25);
border-radius: 15px;
text-align: center;
font-size: 22px;
`
const StyledUl = styled.ul`
margin-top: 31px;
font-weight: 600;
line-height: 200%;
list-style-type: disclosure-closed;
li::marker {
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0;
}
}
`
const StyledSummary = styled.div`
margin-top: 31px;
`
이렇게 프로젝트완성을 하진 못했지만 30일 환급챌린지는 나름 성실하게 마친것같다..
하면서 느낀점은, 확실히 매일매일 최소 한두시간은 투자해야하기 때문에 공부습관잡기에 아주 도움이 되었다.
매일 채워야할 분량이 존재하긴하지만, 크게 부담되지 않는 양이기에 본인 스케줄에 어느정도 맞춰서 조절할 수 있었고,
진행하는그렇게 크다고 할 수 있는 프로젝트도 아니어서 이거 하나만 붙잡고있을 필요도 없었다.
다만 아쉬웠던 점으로는.. 개강기간에 맞물리고 동시에 하고있는게 몇개 더 있는관계로 시간을 좀 더 할애하지 못했다는 점..
시간을 좀 더 투자하고 깊게 집중할 시간이 조금더 있었다면, 훨씬 더 많은 도움이 되었을것 같은데 그 점이 조금 아쉬웠다...
나중에 기회가 된다면 다른강의도 사서 시간도 충분히 투자해가며 열심히해볼 의향이 있다
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
'web > 챌린지' 카테고리의 다른 글
프로젝트 구현(11) - 정산 리스트 컴포넌트 (0) | 2023.03.20 |
---|---|
프로젝트 구현(10) - 정산 리스트 컴포넌트 : 테스트 코드 (0) | 2023.03.19 |
프로젝트 구현(9) - 비용 입력 컴포넌트 구현(2) : 구현 및 스타일링 (0) | 2023.03.18 |
프로젝트 구현(8) - 비용 입력 컴포넌트 구현(1) : 테스트 코드 (0) | 2023.03.17 |
서비스 배포(3) - 테스팅 툴 소개 (0) | 2023.03.16 |