Allow users to re-use previously entered addresses

main
Ashelyn Dawn 4 years ago
parent 00143e477f
commit 1711cd194b

@ -5,6 +5,7 @@ const stripe = require('stripe')(process.env.STRIPE_PRIVATE_KEY);
const easypost = new (require('@easypost/api'))(process.env.EASYPOST_API_KEY); const easypost = new (require('@easypost/api'))(process.env.EASYPOST_API_KEY);
const ensureAdmin = require('./middleware/ensureAdmin') const ensureAdmin = require('./middleware/ensureAdmin')
const ensureCart = require('./middleware/ensureCart') const ensureCart = require('./middleware/ensureCart')
const ensureUser = require('./middleware/ensureUser')
const validate = require('./middleware/validators') const validate = require('./middleware/validators')
@ -15,6 +16,11 @@ router.get('/', async (req, res) => {
return res.json(await db.order.findAllForSession(req.session.uuid)) return res.json(await db.order.findAllForSession(req.session.uuid))
}) })
router.get('/addresses', async (req, res) => {
if(!req.user) return res.json(null)
return res.json(await db.address.findAllForUser(req.user.uuid))
})
router.get('/all', ensureAdmin, async (req, res) => { router.get('/all', ensureAdmin, async (req, res) => {
const orders = await db.order.findAllComplete() const orders = await db.order.findAllComplete()
res.json(orders) res.json(orders)
@ -39,6 +45,22 @@ router.get('/:uuid', ensureAdmin, async (req, res) => {
res.json(order) res.json(order)
}) })
router.post('/current/address/:uuid', ensureUser, ensureCart, async (req, res) => {
const origOrder = await db.order.findForCart(req.cart.uuid);
if(!origOrder) throw new Error("Unable to find current order");
const currentTransaction = origOrder
.transactions.find(transaction => (
transaction.payment_state === 'started'
))
const address = await db.address.findByUUID(req.params.uuid, req.user.uuid)
if(!address) throw new Error("Unable to find address");
const order = await db.order.addAddress(currentTransaction, address)
res.json(order)
})
router.post('/current/address', ensureCart, parseJSON, validate.address, validate.handleApiError, async (req, res) => { router.post('/current/address', ensureCart, parseJSON, validate.address, validate.handleApiError, async (req, res) => {
const origOrder = await db.order.findForCart(req.cart.uuid); const origOrder = await db.order.findForCart(req.cart.uuid);
if(!origOrder) throw new Error("Unable to find current order"); if(!origOrder) throw new Error("Unable to find current order");

@ -2,6 +2,7 @@ const pg = require('../pg')
const joinjs = require('join-js').default; const joinjs = require('join-js').default;
const debug = require('debug')('sos:db:address') const debug = require('debug')('sos:db:address')
const mappings = require('../mappings') const mappings = require('../mappings')
const dbUtil = require('../util')
const easypost = new (require('@easypost/api'))(process.env.EASYPOST_API_KEY); const easypost = new (require('@easypost/api'))(process.env.EASYPOST_API_KEY);
@ -41,3 +42,31 @@ address.create = async (name, street1, street2, city, state, zip, country) => {
const {rows} = await pg.query(query) const {rows} = await pg.query(query)
return joinjs.map(rows, mappings, 'addressMap', 'address_')[0] return joinjs.map(rows, mappings, 'addressMap', 'address_')[0]
} }
address.findByUUID = async (address_uuid, user_uuid) => dbUtil.executeQuery({
query: {
text: `
select * from sos.v_order
where address_uuid = $1
and order_user_uuid = $2;`,
values: [
address_uuid,
user_uuid
]
},
returnType: 'address',
single: true
})
address.findAllForUser = async (user_uuid) => dbUtil.executeQuery({
query: {
text: `
select * from sos.v_order
where order_user_uuid = $1
and transaction_payment_state = 'completed';`,
values: [
user_uuid
]
},
returnType: 'address'
})

@ -12,13 +12,13 @@ const { publicRuntimeConfig: {STRIPE_PUBLIC_KEY} } = getConfig()
const stripePromise = loadStripe(STRIPE_PUBLIC_KEY); const stripePromise = loadStripe(STRIPE_PUBLIC_KEY);
import PaypalIcon from '../../../images/icons/paypal.svg' import PaypalIcon from '../../../images/icons/paypal.svg'
// TODO: Load previous addresses
CheckoutSummary.getInitialProps = async function({ctx: {axios}}){ CheckoutSummary.getInitialProps = async function({ctx: {axios}}){
const {data: addresses} = await axios.get(`/api/orders/addresses`)
const {data: order} = await axios.get(`/api/orders/current`) const {data: order} = await axios.get(`/api/orders/current`)
return {order} return {order, addresses}
} }
export default function CheckoutSummary({order: _order}){ export default function CheckoutSummary({order: _order, addresses}){
const user = useUser(); const user = useUser();
const [order, updateOrder] = useState(_order) const [order, updateOrder] = useState(_order)
const [couponError, setCouponError] = useState(null) const [couponError, setCouponError] = useState(null)
@ -52,7 +52,6 @@ export default function CheckoutSummary({order: _order}){
try { try {
const {data: updatedOrder} = await axios.post(`/api/orders/current/coupon`, {code}) const {data: updatedOrder} = await axios.post(`/api/orders/current/coupon`, {code})
console.log(order, updatedOrder)
updateOrder(updatedOrder) updateOrder(updatedOrder)
} catch (err) { } catch (err) {
console.log(err.response.data.errors) console.log(err.response.data.errors)
@ -64,6 +63,14 @@ export default function CheckoutSummary({order: _order}){
} }
} }
// For address selection
const onAddressSelect = uuid => async ev => {
if(ev) ev.preventDefault()
const {data: updatedOrder} = await axios.post(`/api/orders/current/address/${uuid}`)
updateOrder(updatedOrder)
}
// For Stripe checkout // For Stripe checkout
const handleStripeButton = async ev => { const handleStripeButton = async ev => {
if(ev) ev.preventDefault() if(ev) ev.preventDefault()
@ -90,6 +97,7 @@ export default function CheckoutSummary({order: _order}){
order.address order.address
? ( ? (
<div> <div>
<p style={{marginTop: 0, fontWeight: 'bold'}}>Shipping To:</p>
<p style={{margin: 0}}>{order.address.name}</p> <p style={{margin: 0}}>{order.address.name}</p>
<p style={{margin: 0}}>{order.address.street1}</p> <p style={{margin: 0}}>{order.address.street1}</p>
<p style={{margin: 0}}>{order.address.street2}</p> <p style={{margin: 0}}>{order.address.street2}</p>
@ -99,22 +107,42 @@ export default function CheckoutSummary({order: _order}){
) )
: ( : (
<> <>
{user ? ( {!user && (
<div style={{textAlign: 'center'}}> <>
<p>
TODO: Load previous addresses
</p>
</div>
):(
<div style={{textAlign: 'center'}}> <div style={{textAlign: 'center'}}>
<p> <p>
<Link href="/login"><a>Log in</a></Link> to use your<br/>saved addresses <Link href="/login"><a>Log in</a></Link> to use your<br/>saved addresses
</p> </p>
</div> </div>
<span className={styles.horizDivider}>
OR
</span>
</>
)} )}
{user && addresses && addresses.length && (
<>
<div style={{textAlign: 'center'}}>
<span>Select a previous address:</span>
{addresses.map(address => (
<div className={styles.addressCard}>
<span>
{address.name || address.company} / {address.street1}<br/>
{address.street2 && <> {address.street2} <br/> </>}
{address.city} / {address.state} / {address.zip}
</span>
<button style={{textAlign: 'center'}} className="buttonLink" onClick={onAddressSelect(address.uuid)}>
Use this address
</button>
</div>
))}
</div>
<span className={styles.horizDivider}> <span className={styles.horizDivider}>
OR OR
</span> </span>
</>
)}
<div> <div>
<Button style={{width: '100px'}} onClick={()=>Router.push('/store/checkout/address')}>Input Address</Button> <Button style={{width: '100px'}} onClick={()=>Router.push('/store/checkout/address')}>Input Address</Button>
</div> </div>

@ -55,3 +55,28 @@
.paymentButtons button { .paymentButtons button {
margin: 4px; margin: 4px;
} }
.addressCard {
font-size: 12px;
margin: 0 12px;
padding: 12px;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
white-space: normal;
margin-bottom: 4px;
display: flex;
flex-direction: row;
align-items: center;
}
.addressCard:last-child {
margin-bottom: 0;
}
.addressCard > span {
flex: 1;
}
.addressCard > button {
width: 80px;
}

Loading…
Cancel
Save