From 270e9440314aaf85370c32cd0e3b5c0ecc7735e3 Mon Sep 17 00:00:00 2001 From: Skile Date: Thu, 20 Jun 2019 01:33:32 +0900 Subject: [PATCH 1/5] Payment Viewer Frontend page --- frontend/src/components/App.js | 3 ++- frontend/src/components/atoms/Button/index.js | 6 +++++ frontend/src/components/atoms/Graph/index.js | 1 - .../components/organisms/PaymentForm/index.js | 5 ++-- .../components/organisms/PaymentList/index.js | 8 +++++-- frontend/src/containers/PaymentForm.js | 23 +++++++++++++------ frontend/src/containers/PaymentPage.js | 8 ++++--- frontend/src/store/sagas.js | 2 +- 8 files changed, 39 insertions(+), 17 deletions(-) diff --git a/frontend/src/components/App.js b/frontend/src/components/App.js index 918d3da..c2491de 100644 --- a/frontend/src/components/App.js +++ b/frontend/src/components/App.js @@ -29,7 +29,8 @@ const App = () => { - + + diff --git a/frontend/src/components/atoms/Button/index.js b/frontend/src/components/atoms/Button/index.js index 456933c..2b52c9f 100644 --- a/frontend/src/components/atoms/Button/index.js +++ b/frontend/src/components/atoms/Button/index.js @@ -16,6 +16,12 @@ const Button = styled.button` width: 100%; max-width: 224px; z-index: 1; + + :disabled { + background-color: lightgrey; + color: grey; + cursor: none; + } ` const LightButton = styled(Button)` diff --git a/frontend/src/components/atoms/Graph/index.js b/frontend/src/components/atoms/Graph/index.js index 8171624..8295dfb 100644 --- a/frontend/src/components/atoms/Graph/index.js +++ b/frontend/src/components/atoms/Graph/index.js @@ -11,7 +11,6 @@ const Wrapper = styled.div` padding-top: 100%; width: 100%; position: relative; - z-index: -1; ` const Content = styled.div` diff --git a/frontend/src/components/organisms/PaymentForm/index.js b/frontend/src/components/organisms/PaymentForm/index.js index 8d43ce8..3947532 100644 --- a/frontend/src/components/organisms/PaymentForm/index.js +++ b/frontend/src/components/organisms/PaymentForm/index.js @@ -32,7 +32,8 @@ const Credit = ({ member: {membername}, index, ...props }) => ( /> ) -const PaymentForm = ({ handleSubmit, room, members, payment, amountLeft, total, nBbang, ...props }) => { +const PaymentForm = ({ handleSubmit, room, members, payment, amountLeft, total, nBbang, ...rest }) => { + const { disabled } = rest return (
@@ -78,7 +79,7 @@ const PaymentForm = ({ handleSubmit, room, members, payment, amountLeft, total, > 취소 - +
) diff --git a/frontend/src/components/organisms/PaymentList/index.js b/frontend/src/components/organisms/PaymentList/index.js index 27f2b92..050ec68 100644 --- a/frontend/src/components/organisms/PaymentList/index.js +++ b/frontend/src/components/organisms/PaymentList/index.js @@ -14,8 +14,12 @@ const PaymentList = ({ paymentlist, roomurl }) => ( { paymentlist && paymentlist.map( - ({ forWhat, fromWho, total }, idx) => ( - + ({ id, forWhat, fromWho, total }, idx) => ( + ) ) } diff --git a/frontend/src/containers/PaymentForm.js b/frontend/src/containers/PaymentForm.js index 9c7dde4..265e698 100644 --- a/frontend/src/containers/PaymentForm.js +++ b/frontend/src/containers/PaymentForm.js @@ -54,16 +54,25 @@ const mapDispatchToProps = dispatch => ({ } }) -const PaymentFormContainer = ({...props}) => { - const initialValues = { - credits: props.members.map( - ({ membername }) => ({ toWho: membername, amount: 0.0 }) - ), - room: props.room, - } +const PaymentFormContainer = ({payment, ...props}) => { + const initialValues = (payment ? + { // if payment exists + ...payment, + room: props.room, + } : + { // if payment doesn't exist + credits: props.members.map( + ({ membername }) => ({ toWho: membername, amount: 0.0 }) + ), + room: props.room, + } + ) + + console.log(initialValues) return ( diff --git a/frontend/src/containers/PaymentPage.js b/frontend/src/containers/PaymentPage.js index 383dcb7..944ccb3 100644 --- a/frontend/src/containers/PaymentPage.js +++ b/frontend/src/containers/PaymentPage.js @@ -3,14 +3,16 @@ import { connect } from 'react-redux' import { PaymentPage } from 'components' -const PaymentPageContainer = props => { - return +const PaymentPageContainer = ({ match, payments, ...props }) => { + const paymentId = parseInt(match.params.payment_id) + const payment = payments.find(p => p.id === paymentId) + return } const mapStateToProps = state => ({ room: state.room.room, members: state.member.members, - payment: state.payment.payment, + payments: state.payment.payments, }) export default connect(mapStateToProps)(PaymentPageContainer) diff --git a/frontend/src/store/sagas.js b/frontend/src/store/sagas.js index 4018bd9..42928d8 100644 --- a/frontend/src/store/sagas.js +++ b/frontend/src/store/sagas.js @@ -11,7 +11,7 @@ const req = require.context('.', true, /\.\/.+\/sagas\.js$/) const sagas = req.keys().map(key => req(key).default) sagas.push(function* () { - yield takeEvery(a => a.error, function* ({ type, error }) { + yield takeEvery(a => a.error && a.type[0] !== '@', function* ({ type, error }) { toastError(type, JSON.stringify(error)) }) }) From b565d051c683ce3422b8cfd8fb4d0528b2ab9528 Mon Sep 17 00:00:00 2001 From: Skile Date: Thu, 20 Jun 2019 02:07:48 +0900 Subject: [PATCH 2/5] Add normalization on PaymentForm --- frontend/src/components/atoms/Button/index.js | 12 ++++++++-- .../components/organisms/PaymentForm/index.js | 23 ++++++++++++------- .../src/components/pages/UserPage/index.js | 8 +++---- frontend/src/containers/PaymentForm.js | 17 ++++++++++---- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/atoms/Button/index.js b/frontend/src/components/atoms/Button/index.js index 2b52c9f..e49129e 100644 --- a/frontend/src/components/atoms/Button/index.js +++ b/frontend/src/components/atoms/Button/index.js @@ -13,17 +13,25 @@ const Button = styled.button` font-size: 1em; margin: ${({ horizontal }) => horizontal ? "0 0.5em" : "0.5em auto 0"}; padding: 4px 15px; - width: 100%; + width: ${({ width }) => width}; max-width: 224px; z-index: 1; :disabled { background-color: lightgrey; color: grey; - cursor: none; + cursor: default; } ` +Button.defaultProps = { + width: '100%', +} + +Button.propTypes = { + width: PropTypes.string.isRequired, +} + const LightButton = styled(Button)` background: white; color: black; diff --git a/frontend/src/components/organisms/PaymentForm/index.js b/frontend/src/components/organisms/PaymentForm/index.js index 3947532..a720ea5 100644 --- a/frontend/src/components/organisms/PaymentForm/index.js +++ b/frontend/src/components/organisms/PaymentForm/index.js @@ -18,7 +18,10 @@ const TinyInput = styled(SimpleInput)` margin: 0; ` -const Credit = ({ member: {membername}, index, ...props }) => ( +const natural = value => value && Math.max(Math.round(value), 0) +const lessThan = x => (value => value && Math.min(natural(value), x)) + +const Credit = ({ total, member: {membername}, index, ...props }) => ( {membername}} lower={ @@ -26,20 +29,24 @@ const Credit = ({ member: {membername}, index, ...props }) => ( name={`credits[${index}].amount`} type="number" parse={value => value && Number(value)} + normalize={lessThan(total)} component={TinyInput} /> } /> ) -const PaymentForm = ({ handleSubmit, room, members, payment, amountLeft, total, nBbang, ...rest }) => { - const { disabled } = rest +const PaymentForm = ({ handleSubmit, room, members, payment, amountLeft, total, ...rest }) => { + const { + disabled, + set1OverN, setRandom, // setter callback + } = rest return (
- + {members.map( ({ membername }) => ( - - + + @@ -67,7 +74,7 @@ const PaymentForm = ({ handleSubmit, room, members, payment, amountLeft, total,
{members.map( (member, index) => ( - + ) )}
diff --git a/frontend/src/components/pages/UserPage/index.js b/frontend/src/components/pages/UserPage/index.js index 53cc95b..ec48d00 100644 --- a/frontend/src/components/pages/UserPage/index.js +++ b/frontend/src/components/pages/UserPage/index.js @@ -2,7 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import { Link } from 'react-router-dom' -import { Block, Button, Header, List, ListItem } from 'components' +import { Block, Button, Header, List, LinkButton, ListItem } from 'components' /** * Presentational Components의 경우 redux 로직을 배제한다 (cf. pages/MainPage/index.js) @@ -13,9 +13,9 @@ const UserPage = ({username, roomList, onClickUserInfo, onClickSignOut}) => (

{username}

- - - + + 유저 정보 +
새로운 방을 원한다면? diff --git a/frontend/src/containers/PaymentForm.js b/frontend/src/containers/PaymentForm.js index 265e698..e7b0e6d 100644 --- a/frontend/src/containers/PaymentForm.js +++ b/frontend/src/containers/PaymentForm.js @@ -45,13 +45,22 @@ const mapStateToProps = state => ({ }) const mapDispatchToProps = dispatch => ({ - nBbang(total, members) { - const amount = total / members.length + set1OverN(total, members) { + const amount = Math.floor(total / members.length) members.forEach( (m, index) => dispatch(change(FORM_NAME, `credits[${index}].amount`, amount)) ) - } + }, + setRandom(total, members) { + const rand = members.map(() => Math.random()) + const sum = rand.reduce((a, b) => (a + b), 0) + + rand.map(x => Math.floor(total * x / sum)).forEach( + (r, index) => + dispatch(change(FORM_NAME, `credits[${index}].amount`, r)) + ) + }, }) const PaymentFormContainer = ({payment, ...props}) => { @@ -68,8 +77,6 @@ const PaymentFormContainer = ({payment, ...props}) => { } ) - console.log(initialValues) - return ( Date: Thu, 20 Jun 2019 02:32:15 +0900 Subject: [PATCH 3/5] Room filtered by owner --- .travis.yml | 2 ++ backend/src/dutch_broomstick/views.py | 4 +++- frontend/src/store/room/reducer.js | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a6e640c..d38b8aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,5 +12,7 @@ matrix: - pipenv run python src/manage.py test - language: node_js node_js: 8 + install: + - yarn install before_install: - cd frontend diff --git a/backend/src/dutch_broomstick/views.py b/backend/src/dutch_broomstick/views.py index 6fab410..1b231b6 100644 --- a/backend/src/dutch_broomstick/views.py +++ b/backend/src/dutch_broomstick/views.py @@ -25,9 +25,11 @@ class UserDetailView(generics.RetrieveUpdateAPIView): class RoomListCreateView(generics.ListCreateAPIView): permission_classes = (CheckUsername,) - queryset = Room.objects.all() serializer_class = RoomSerializer + def get_queryset(self): + return Room.objects.filter(owner=self.request.user) + def perform_create(self, serializer): serializer.save(owner=self.request.user) diff --git a/frontend/src/store/room/reducer.js b/frontend/src/store/room/reducer.js index cd6f6fa..ffa099b 100644 --- a/frontend/src/store/room/reducer.js +++ b/frontend/src/store/room/reducer.js @@ -1,3 +1,4 @@ +import { USER_SIGNOUT } from 'store/actions' import * as actions from './actions'; const initialState = { @@ -42,6 +43,10 @@ const initialState = { const roomReducer = (state = initialState, action) => { switch(action.type) { + case USER_SIGNOUT: + return { + ...initialState, + } case actions.ROOM_CREATE_REQUEST: return { ...state, From 83d174afdf40b3aa5debd22c434adb3aae76eca7 Mon Sep 17 00:00:00 2001 From: Skile Date: Thu, 20 Jun 2019 02:50:16 +0900 Subject: [PATCH 4/5] Fix minor bugs --- .travis.yml | 4 +++- frontend/src/components/pages/IndividualPage/index.js | 4 ++-- frontend/src/containers/RoomCreateForm.js | 11 ++++++++++- frontend/src/containers/RoomPage.js | 10 +++------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index d38b8aa..027e5cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,8 @@ matrix: - language: node_js node_js: 8 install: - - yarn install + - npm install before_install: - cd frontend + script: + - npm test diff --git a/frontend/src/components/pages/IndividualPage/index.js b/frontend/src/components/pages/IndividualPage/index.js index 0b48c67..1f968b4 100644 --- a/frontend/src/components/pages/IndividualPage/index.js +++ b/frontend/src/components/pages/IndividualPage/index.js @@ -33,8 +33,8 @@ const IndividualPage = ({ sendlist, getlist, roomurl, nickname }) => ( { getlist && getlist.map( - ({ to, label }, idx) => ( - + ({ from, label }, idx) => ( + ) ) } diff --git a/frontend/src/containers/RoomCreateForm.js b/frontend/src/containers/RoomCreateForm.js index 08961a8..f9d2306 100644 --- a/frontend/src/containers/RoomCreateForm.js +++ b/frontend/src/containers/RoomCreateForm.js @@ -1,6 +1,7 @@ import React from 'react' import { connect } from 'react-redux' -import { reduxForm, formValueSelector, arrayPush, change } from 'redux-form' +import { toastr } from 'react-redux-toastr' +import { reduxForm, formValueSelector, arrayPush, change, SubmissionError } from 'redux-form' import { RoomCreateForm } from 'components' import { roomCreateRequest } from 'store/actions' @@ -33,6 +34,14 @@ export default connect(mapStateToProps, mapDispatchToProps)( onSubmit(values, dispatch, props) { const { roomname, members } = values const { username, token } = props // username means ownername + + if (!(members && members.length)) { + toastr.light( + "방 생성 오류", "화면 하단에서 다른 멤버를 최소 1명 추가해주세요.", + { icon: 'error', status: 'error' } + ) + return + } dispatch(roomCreateRequest(roomname, members, username, token)) } })(RoomCreateFormContainer) diff --git a/frontend/src/containers/RoomPage.js b/frontend/src/containers/RoomPage.js index 6551d5f..feba373 100644 --- a/frontend/src/containers/RoomPage.js +++ b/frontend/src/containers/RoomPage.js @@ -1,5 +1,5 @@ import React from 'react' -import { Redirect } from 'react-router-dom' +import { push } from 'connected-react-router' import { connect } from 'react-redux' import { RoomPage } from 'components' @@ -14,11 +14,7 @@ class RoomPageContainer extends React.Component { } render() { - const { room, member } = this.props - - if (member) { - return - } + const { room, } = this.props if (room) { document.title = `${this.props.room.roomname} - Dutch Broomstick` @@ -31,7 +27,6 @@ class RoomPageContainer extends React.Component { const mapStateToProps = state => ({ room: state.room.room, - member: state.room.member, members: state.member.members, payments: state.payment.payments, showPayment: state.room.showPayment, @@ -42,6 +37,7 @@ const mapDispatchToProps = dispatch => ({ onLeave: () => dispatch(roomLeave()), onClickMember: (member, sendlist, getlist) => { dispatch(roomSetMember(member, sendlist, getlist)) + dispatch(push(`member/${member.id}/`)) }, onToggle: () => dispatch(roomToggleContents()), }) From 9ff683a6560cb212b1f626c5d57c065fac0b99c3 Mon Sep 17 00:00:00 2001 From: Skile Date: Thu, 20 Jun 2019 03:24:00 +0900 Subject: [PATCH 5/5] Design RoomPage: add Roomname --- frontend/src/components/atoms/Block/index.js | 15 +++++++++-- .../src/components/pages/RoomPage/index.js | 27 ++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/atoms/Block/index.js b/frontend/src/components/atoms/Block/index.js index 7fa68c4..17ab22a 100644 --- a/frontend/src/components/atoms/Block/index.js +++ b/frontend/src/components/atoms/Block/index.js @@ -1,11 +1,18 @@ import styled from 'styled-components' +import PropTypes from 'prop-types' + +const alignItems = ({direction}) => ( + direction === 'column' ? + 'center' : 'baseline' +) const Block = styled.div` background-color: ${props => props.transparent ? "transparent" : "white"}; border: ${props => props.transparent ? "none" : "thin solid #bfbfbf"}; display: flex; - flex-direction: ${props => props.direction || "column"}; - align-items: center; + flex-direction: ${({direction}) => direction}; + justify-content: space-between; + align-items: ${alignItems}; margin: 0.5em auto 0; padding: 1em 20px; max-width: 310px; @@ -17,4 +24,8 @@ const Block = styled.div` } ` +Block.defaultProps = { + direction: 'column', +} + export default Block diff --git a/frontend/src/components/pages/RoomPage/index.js b/frontend/src/components/pages/RoomPage/index.js index ffd7a02..2ddf47c 100644 --- a/frontend/src/components/pages/RoomPage/index.js +++ b/frontend/src/components/pages/RoomPage/index.js @@ -51,14 +51,33 @@ const RoomPage = props => {
{}}> - + - + + +

+ {room.roomname} +

+
{showPayment ? () : (members && )