add more tests for payment history page, responsive mobile view
This commit is contained in:
parent
c2ffbff216
commit
81c1c17a2f
|
|
@ -8,39 +8,82 @@ describe('Payments Page', () => {
|
|||
cy.intercept('GET', /\S+\/invoice_history\?limit=10&cursor=0/, { fixture: 'payments_page1' }).as('getPayments1');
|
||||
cy.intercept('GET', /\S+\/invoice_history\?limit=10&cursor=10/, { fixture: 'payments_page2' }).as('getPayments2');
|
||||
cy.intercept('GET', /\S+\/invoice_history\?limit=10&cursor=20/, { fixture: 'payments_page3' }).as('getPayments3');
|
||||
})
|
||||
|
||||
it('should list user\'s payments', () => {
|
||||
// Call the external API that fetches the payment records
|
||||
cy.visit('/account/payments')
|
||||
cy.wait('@getPayments1')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr').first().within(() => {
|
||||
cy.contains('05/01/2022')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it.only('paginate through the payments', () => {
|
||||
// Call the external API that fetches the payment records
|
||||
cy.visit('/account/payments')
|
||||
cy.wait('@getPayments1')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr').first().within(() => {
|
||||
cy.contains('12/01/2022')
|
||||
})
|
||||
|
||||
// Click the next page button
|
||||
cy.get('[data-testid="nextPageButton"]').click()
|
||||
cy.wait('@getPayments2')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr').first().within(() => {
|
||||
cy.contains('02/01/2022')
|
||||
})
|
||||
|
||||
// Click the next page button
|
||||
cy.get('[data-testid="nextPageButton"]').click()
|
||||
cy.wait('@getPayments3')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr').first().within(() => {
|
||||
cy.contains('03/01/2021')
|
||||
})
|
||||
});
|
||||
|
||||
describe('in desktop', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport('macbook-13');
|
||||
});
|
||||
|
||||
it('should list user\'s payments', () => {
|
||||
// Call the external API that fetches the payment records
|
||||
cy.visit('/account/payments')
|
||||
cy.wait('@getPayments1')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr td').first().within(() => {
|
||||
cy.contains('12/01/2022')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
it('paginate through the payments', () => {
|
||||
// Call the external API that fetches the payment records
|
||||
cy.visit('/account/payments')
|
||||
cy.wait('@getPayments1')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr').first().within(() => {
|
||||
cy.contains('12/01/2022')
|
||||
})
|
||||
|
||||
// Click the next page button
|
||||
cy.get('[data-testid="nextPageButton"]').click()
|
||||
cy.wait('@getPayments2')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr:nth-child(11)').first().within(() => {
|
||||
cy.contains('02/01/2022')
|
||||
})
|
||||
|
||||
// Click the next page button
|
||||
cy.get('[data-testid="nextPageButton"]').click()
|
||||
cy.wait('@getPayments3')
|
||||
cy.get('[data-testid="paymentsListTable"]').should('be.visible').find('tbody tr:nth-child(22)').first().within(() => {
|
||||
cy.contains('03/01/2021')
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('in mobile', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport('iphone-6');
|
||||
});
|
||||
|
||||
it('should list user\'s payments', () => {
|
||||
// Call the external API that fetches the payment records
|
||||
cy.visit('/account/payments')
|
||||
cy.wait('@getPayments1')
|
||||
cy.get('[data-testid=paymentSwiper]').should('be.visible')
|
||||
|
||||
for (let i = 0; i < 9; i++) {
|
||||
cy.get('.swiper-button-next').click();
|
||||
cy.wait(500);
|
||||
}
|
||||
cy.wait('@getPayments2')
|
||||
for (let i = 0; i < 10; i++) {
|
||||
cy.get('.swiper-button-next').click();
|
||||
cy.wait(500);
|
||||
}
|
||||
cy.get('.swiper-button-next').click();
|
||||
cy.wait('@getPayments3')
|
||||
for (let i = 0; i < 2; i++) {
|
||||
cy.get('.swiper-button-next').click();
|
||||
cy.wait(500);
|
||||
}
|
||||
cy.get('.swiper-button-next').should('have.class', 'swiper-button-disabled');
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -9,4 +9,9 @@
|
|||
|
||||
.borderless td, .borderless th {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.swiper-card {
|
||||
box-shadow: none !important;
|
||||
border: solid 1px #eee;
|
||||
}
|
||||
|
|
@ -104,10 +104,10 @@
|
|||
object-fit: cover;
|
||||
}
|
||||
|
||||
.swiper-person-card{
|
||||
box-shadow: none !important;
|
||||
border: solid 1px #eee;
|
||||
}
|
||||
// .swiper-person-card{
|
||||
// box-shadow: none !important;
|
||||
// border: solid 1px #eee;
|
||||
// }
|
||||
|
||||
.latency-badge{
|
||||
min-width: 0%;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Card, CardBody, Row, Col, Table, Alert, Button } from 'reactstrap';
|
||||
import { Card, CardBody, Row, Col, Alert } from 'reactstrap';
|
||||
import FalconCardHeader from '../common/FalconCardHeader';
|
||||
import { getInvoiceHistory } from '../../helpers/rest';
|
||||
import { isIterableArray } from '../../helpers/utils';
|
||||
import { useResponsive } from '@farfetch/react-context-responsive';
|
||||
import PaymentHistoryList from '../payments/JKPaymentHistoryList';
|
||||
import PaymentHistorySwiper from '../payments/JKPaymentHistorySwiper';
|
||||
|
||||
const JKPaymentHistory = () => {
|
||||
const { t } = useTranslation('account');
|
||||
|
|
@ -11,6 +14,7 @@ const JKPaymentHistory = () => {
|
|||
const LIMIT = 10;
|
||||
const [offset, setOffset] = useState(0);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { greaterThan } = useResponsive();
|
||||
|
||||
const fetchPayments = async () => {
|
||||
const options = { limit: LIMIT, cursor: offset };
|
||||
|
|
@ -18,11 +22,11 @@ const JKPaymentHistory = () => {
|
|||
setLoading(true);
|
||||
const response = await getInvoiceHistory(options);
|
||||
const data = await response.json();
|
||||
setPayments(data.entries);
|
||||
setPayments(prev => [...prev, ...data.entries]);
|
||||
setOffset(prev => prev + LIMIT);
|
||||
}catch(error) {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}finally {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
|
@ -30,13 +34,13 @@ const JKPaymentHistory = () => {
|
|||
useEffect(async () => {
|
||||
// fetch payments
|
||||
const options = { cursor: offset, limit: LIMIT };
|
||||
await fetchPayments(options);
|
||||
await fetchPayments(options);
|
||||
}, []);
|
||||
|
||||
const goToNextPage = async () => {
|
||||
const options = { cursor: offset, limit: LIMIT };
|
||||
await fetchPayments(options);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
|
|
@ -46,36 +50,11 @@ const JKPaymentHistory = () => {
|
|||
<Col className="mb-2 col-md-9 col-lg-8 m-auto">
|
||||
{isIterableArray(payments) && payments.length ? (
|
||||
<>
|
||||
<Table striped bordered className="fs--1" data-testid="paymentsListTable">
|
||||
<thead className="bg-200 text-900">
|
||||
<tr>
|
||||
<th scope="col">{t('payments.payment_attributes.date')}</th>
|
||||
<th scope="col" style={{ minWidth: 250 }}>
|
||||
{t('payments.payment_attributes.description')}
|
||||
</th>
|
||||
<th scope="col">{t('payments.payment_attributes.status')}</th>
|
||||
<th scope="col">{t('payments.payment_attributes.amount')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="list">
|
||||
{payments.map(payment => (
|
||||
<tr key={payment.id}>
|
||||
<td>{new Date(payment.created_at).toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit"}
|
||||
)}
|
||||
</td>
|
||||
<td>{payment.description}</td>
|
||||
<td>{payment.status}</td>
|
||||
<td>{`$${(payment.total_in_cents / 100).toFixed(2)}`}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
<Button onClick={goToNextPage} data-testid="nextPageButton" disabled={loading}>
|
||||
{loading ? <span>{t('payments.loading')}</span> : <span>{t('payments.load_more')}</span> }
|
||||
</Button>
|
||||
{greaterThan.sm ? (
|
||||
<PaymentHistoryList payments={payments} goToNextPage={goToNextPage} loading={loading} />
|
||||
) : (
|
||||
<PaymentHistorySwiper payments={payments} goToNextPage={goToNextPage} />
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Alert color="info" className="mb-0">
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const JKPeopleSwiper = ({ people, goNextPage }) => {
|
|||
>
|
||||
{people.map((person, index) => (
|
||||
<SwiperSlide key={`people-swiper-item-${person.id}`}>
|
||||
<Card className="swiper-person-card">
|
||||
<Card className="swiper-card">
|
||||
<CardHeader className="bg-200">
|
||||
<div className="avatar avatar-xl d-inline-block me-2 mr-2">
|
||||
<JKProfileAvatar url={person.photo_url} size="xl"/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
import React from 'react';
|
||||
import { useResponsive } from '@farfetch/react-context-responsive';
|
||||
import { Row, Col } from 'reactstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const JKPayment = ({ payment }) => {
|
||||
const { greaterThan } = useResponsive();
|
||||
const { t } = useTranslation('account');
|
||||
return (
|
||||
<>
|
||||
{greaterThan.sm ? (
|
||||
<tr key={payment.id}>
|
||||
<td>
|
||||
{new Date(payment.created_at).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
})}
|
||||
</td>
|
||||
<td>{payment.description}</td>
|
||||
<td className='text-capitalize'>{payment.status}</td>
|
||||
<td>{`$${(payment.total_in_cents / 100).toFixed(2)}`}</td>
|
||||
</tr>
|
||||
) : (
|
||||
<>
|
||||
<small>
|
||||
<Row>
|
||||
<Col xs={4} className="mb-2 text-right">
|
||||
{t('payments.payment_attributes.date')}:
|
||||
</Col>
|
||||
<Col xs={8} className="mb-2 pl-2">
|
||||
{new Date(payment.created_at).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit'
|
||||
})}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={4} className="mb-2 text-right">
|
||||
{t('payments.payment_attributes.description')}:
|
||||
</Col>
|
||||
<Col xs={8} className="mb-2 pl-2">
|
||||
{payment.description}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={4} className="mb-2 text-right">{t('payments.payment_attributes.status')}:</Col>
|
||||
<Col xs={6} className="mb-2 pl-2 text-capitalize">
|
||||
{payment.status}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={4} className="mb-2 text-right">{t('payments.payment_attributes.amount')}:</Col>
|
||||
<Col xs={8} className="mb-2 pl-2">
|
||||
{`$${(payment.total_in_cents / 100).toFixed(2)}`}
|
||||
</Col>
|
||||
</Row>
|
||||
</small>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default JKPayment;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import React from 'react'
|
||||
import { Table, Button } from 'reactstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import JKPayment from './JKPayment';
|
||||
|
||||
const JKPaymentHistoryList = ({payments, goToNextPage, loading}) => {
|
||||
const { t } = useTranslation('account');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table striped bordered className="fs--1" data-testid="paymentsListTable">
|
||||
<thead className="bg-200 text-900">
|
||||
<tr>
|
||||
<th scope="col">{t('payments.payment_attributes.date')}</th>
|
||||
<th scope="col" style={{ minWidth: 250 }}>
|
||||
{t('payments.payment_attributes.description')}
|
||||
</th>
|
||||
<th scope="col">{t('payments.payment_attributes.status')}</th>
|
||||
<th scope="col">{t('payments.payment_attributes.amount')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="list">
|
||||
{payments.map(payment => (
|
||||
<JKPayment payment={payment} />
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
<Button onClick={goToNextPage} data-testid="nextPageButton" disabled={loading}>
|
||||
{loading ? <span>{t('payments.loading')}</span> : <span>{t('payments.load_more')}</span> }
|
||||
</Button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default JKPaymentHistoryList
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
// import Swiper core and required modules
|
||||
import SwiperCore, { Navigation, Pagination, Scrollbar, A11y } from 'swiper';
|
||||
|
||||
// Import Swiper React components
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
|
||||
// Import Swiper styles
|
||||
import 'swiper/swiper.scss';
|
||||
import 'swiper/components/navigation/navigation.scss';
|
||||
import 'swiper/components/pagination/pagination.scss';
|
||||
import 'swiper/components/scrollbar/scrollbar.scss';
|
||||
|
||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||
|
||||
import JKPayment from './JKPayment';
|
||||
|
||||
SwiperCore.use([Navigation, Pagination, Scrollbar, A11y]);
|
||||
|
||||
const JKPaymentHistorySwiper = ({ payments, goToNextPage }) => {
|
||||
const { t } = useTranslation('account');
|
||||
return (
|
||||
<>
|
||||
<Swiper
|
||||
spaceBetween={0}
|
||||
slidesPerView={1}
|
||||
onSlideChange={(e) => console.log('slide change', e)}
|
||||
onSlideNextTransitionEnd={swiper => {
|
||||
if(swiper.isEnd){
|
||||
goToNextPage()
|
||||
}
|
||||
}}
|
||||
pagination={{
|
||||
clickable: true,
|
||||
type: 'custom'
|
||||
}}
|
||||
navigation={{
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev'
|
||||
}}
|
||||
data-testid="paymentSwiper"
|
||||
>
|
||||
{payments.map((payment, index) => (
|
||||
<SwiperSlide key={`people-swiper-item-${payment.id}`}>
|
||||
<Card className="swiper-card">
|
||||
<CardHeader className="bg-200 text-center">
|
||||
<h5 className="d-inline-block align-top mt-1">{t('payments.payment')}</h5>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<JKPayment payment={payment} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
<div className="py-4 px-6 bg-white border-top w-100 fixed-bottom">
|
||||
<div className="swiper-pagination" />
|
||||
<div className="swiper-button-prev" />
|
||||
<div className="swiper-button-next" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
JKPaymentHistorySwiper.propTypes = {
|
||||
payments: PropTypes.arrayOf(PropTypes.instanceOf(Object)),
|
||||
goToNextPage: PropTypes.func
|
||||
};
|
||||
|
||||
export default JKPaymentHistorySwiper;
|
||||
|
|
@ -44,7 +44,7 @@ const JKFriendsSwiper = ({ friends, goNextPage }) => {
|
|||
>
|
||||
{friends.map((friend, index) => (
|
||||
<SwiperSlide key={`friends-swiper-item-${friend.id}`}>
|
||||
<Card className="swiper-person-card">
|
||||
<Card className="swiper-card">
|
||||
<CardHeader className="bg-200">
|
||||
<div className="avatar avatar-xl d-inline-block me-2 mr-2">
|
||||
<JKProfileAvatar url={friend.photo_url} size="xl"/>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const JKLobbyUserSwiper = ({ onlineMusicians, setSelectedUsers, loadingStatus })
|
|||
>
|
||||
{onlineMusicians.map((musician, index) => (
|
||||
<SwiperSlide key={`session-lobby-swiper-item-${musician.id}`}>
|
||||
<Card className="swiper-person-card">
|
||||
<Card className="swiper-card">
|
||||
<CardHeader className="bg-200">
|
||||
<div className="avatar avatar-xl d-inline-block me-2 mr-2">
|
||||
<JKProfileAvatar url={musician.photo_url} size="xl" />
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ const JKSessionSwiper = ({ sessions }) => {
|
|||
>
|
||||
{sessions.map((session, index) => (
|
||||
<SwiperSlide key={`sessions-swiper-item-${session.id}`}>
|
||||
<Card className="swiper-person-card">
|
||||
<Card className="swiper-card">
|
||||
<CardHeader className="text-center bg-200">
|
||||
<h4 className="d-inline-block align-center mt-1">Session</h4>
|
||||
</CardHeader>
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
},
|
||||
"payments": {
|
||||
"page_title": "Payment History",
|
||||
"payment": "Payment",
|
||||
"payment_attributes": {
|
||||
"date": "Date",
|
||||
"description": "Description",
|
||||
|
|
|
|||
Loading…
Reference in New Issue