You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
3.4 KiB
JavaScript
113 lines
3.4 KiB
JavaScript
4 years ago
|
import {DateTime} from 'luxon'
|
||
|
import Router from 'next/router'
|
||
|
|
||
|
import Table from '~/components/table'
|
||
|
import useUser from '~/hooks/useUser'
|
||
|
|
||
|
AccountPage.getInitialProps = async function({ctx: {axios}}) {
|
||
|
const {data} = await axios.get(`/api/orders`)
|
||
|
return {orders: data.sort(sortOrders)}
|
||
|
}
|
||
|
|
||
|
export default function AccountPage({orders}) {
|
||
|
const user = useUser()
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<h2>Account</h2>
|
||
|
|
||
|
{/* TODO: Red is kind of intimidating. Should we change this to a yellow or blue info style? */}
|
||
|
{!user.email_confirmed && (
|
||
|
<p className="warning">
|
||
|
<strong style={{display:'inline-block', marginBottom: 8}}>Confirm your email address</strong>
|
||
|
<br/>Confirming your email address allows it to be used for password recovery. <button className="buttonLink">Confirm email address</button>
|
||
|
</p>
|
||
|
)}
|
||
|
|
||
|
<h3>Email and Password</h3>
|
||
|
<div style={{maxWidth: 700, margin: '0 auto'}}>
|
||
|
<p><strong>Email:</strong> {user.email} <button className="buttonLink">Change</button></p>
|
||
|
|
||
|
{/* TODO: Store date password was set so we can show "Set on [date]"? */}
|
||
|
<p><strong>Password:</strong> {!user.password_hash ? 'Unset' : <>Set. <button className="buttonLink">Change</button></>}</p>
|
||
|
</div>
|
||
|
|
||
|
<h3>Your Orders</h3>
|
||
|
<Table
|
||
|
columns={[
|
||
|
{name: 'Purchased', extractor: getPurchaseTime},
|
||
|
{name: 'Items', extractor: getNumberItems},
|
||
|
{name: 'Item Price', extractor: getItemPrice},
|
||
|
{name: 'Shipping', extractor: getShippingEstimate},
|
||
|
{name: 'Total', extractor: getAmountPaid},
|
||
|
{name: '', extractor: order =>
|
||
|
<button className="buttonLink" onClick={() => Router.push(`/account/orders/${order.uuid}`)}>Details</button>
|
||
|
}
|
||
|
]}
|
||
|
rows={orders}
|
||
|
/>
|
||
|
<p/>
|
||
|
</>
|
||
|
)
|
||
|
}
|
||
|
|
||
|
function getPurchaseTime(order){
|
||
|
const mostRecentTransaction = order.transactions.sort(sortTransactions)[0]
|
||
|
const time = parsePaymentTime(mostRecentTransaction)
|
||
|
|
||
|
return time.setZone('local').toFormat('LLLL dd, h:mm a')
|
||
|
}
|
||
|
|
||
|
function getNumberItems(order){
|
||
|
return order.transactions.map(transaction =>
|
||
|
transaction.cart.items.map(item => item.count)
|
||
|
).reduce((a,b)=>(a+b))
|
||
|
}
|
||
|
|
||
|
function getItemPrice(order){
|
||
|
return formatMoney(order.transactions.map(transaction => transaction.item_total_price)
|
||
|
.reduce((a,b)=>(a+b)))
|
||
|
}
|
||
|
|
||
|
function getShippingEstimate(order){
|
||
|
return formatMoney(order.transactions.map(transaction => transaction.shipping_price)
|
||
|
.reduce((a,b)=>(a+b)))
|
||
|
}
|
||
|
|
||
|
function getAmountPaid(order){
|
||
|
return formatMoney(order.transactions.map(({payments}) => payments.map(payment => payment.value_cents))
|
||
|
.flat()
|
||
|
.reduce((a,b)=>(a+b)))
|
||
|
}
|
||
|
|
||
|
function parsePaymentTime({payments}){
|
||
|
for(const payment of payments) {
|
||
|
if(typeof payment.time === 'string')
|
||
|
payment.time = DateTime.fromISO(payment.time)
|
||
|
}
|
||
|
|
||
|
payments.sort((a,b) => b.time.diff(a.time))
|
||
|
return payments[0].time
|
||
|
}
|
||
|
|
||
|
function sortTransactions(a,b){
|
||
|
const timeA = parsePaymentTime(a)
|
||
|
const timeB = parsePaymentTime(b)
|
||
|
|
||
|
return timeB.diff(timeA).as('seconds')
|
||
|
}
|
||
|
|
||
|
function sortOrders(a,b){
|
||
|
const timePaidA = parsePaymentTime(a.transactions.sort(sortTransactions)[0])
|
||
|
const timePaidB = parsePaymentTime(b.transactions.sort(sortTransactions)[0])
|
||
|
|
||
|
return timePaidB.diff(timePaidA).as('seconds')
|
||
|
}
|
||
|
|
||
|
const formatMoney = money => {
|
||
|
if (money === undefined || money === null) return null;
|
||
|
|
||
|
return '$' + (money / 100).toFixed(2)
|
||
|
}
|
||
|
|