|
|
|
import React, {useState, useRef, useEffect} from 'react'
|
|
|
|
import {DateTime} from 'luxon'
|
|
|
|
import {Button} from '~/components/form'
|
|
|
|
import {Button as RMWCButton} from '@rmwc/button'
|
|
|
|
import Link from 'next/link'
|
|
|
|
import ActionBar from '~/components/admin/actionBar'
|
|
|
|
|
|
|
|
import styles from '~/styles/shippingLabel.module.css'
|
|
|
|
|
|
|
|
import useLocalStorage from '~/hooks/useLocalStorage'
|
|
|
|
|
|
|
|
OrderLabel.getInitialProps = async ({ctx: {axios, query: {id}}}) => {
|
|
|
|
const {data: order} = await axios.get(`/api/orders/${id}`)
|
|
|
|
return {order}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function OrderLabel({order}){
|
|
|
|
const [printCache, setPrintCache] = useLocalStorage('admin:orderlabelview', {})
|
|
|
|
const [imgLoaded, setImgLoaded] = useState(false)
|
|
|
|
const imgRef = useRef()
|
|
|
|
|
|
|
|
const currentRotation = parseInt(printCache[order.uuid]?.rotation || '0deg', 10)
|
|
|
|
|
|
|
|
// On first load, if we haven't already decided rotation for this image,
|
|
|
|
// determine based on aspect ratio
|
|
|
|
useEffect(() => {
|
|
|
|
if(printCache[order.uuid] || !imgRef.current || !imgLoaded)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const {current: img} = imgRef
|
|
|
|
|
|
|
|
if(img.naturalWidth > img.naturalHeight)
|
|
|
|
setRotation(90)
|
|
|
|
|
|
|
|
}, [printCache, imgLoaded, imgRef.current])
|
|
|
|
|
|
|
|
function setRotation(deg) {
|
|
|
|
setPrintCache(printCache => {
|
|
|
|
return clearCache({
|
|
|
|
...printCache,
|
|
|
|
[order.uuid]: {
|
|
|
|
uuid: order.uuid,
|
|
|
|
rotation: deg + 'deg',
|
|
|
|
timestamp: DateTime.local().toISO()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function rotateRight() {
|
|
|
|
setRotation((currentRotation + 90) % 360)
|
|
|
|
}
|
|
|
|
|
|
|
|
function rotateLeft() {
|
|
|
|
setRotation((currentRotation - 90) % 360)
|
|
|
|
}
|
|
|
|
|
|
|
|
function print() {
|
|
|
|
printLabel(imgRef.current, currentRotation)
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<ActionBar title="Print Shipping Label"/>
|
|
|
|
<Link href={`/admin/orders/${order.uuid}`}><a><RMWCButton icon="arrow_left">Back to order</RMWCButton></a></Link>
|
|
|
|
|
|
|
|
<div className={styles.controls}>
|
|
|
|
<Button outline icon="rotate_left" onClick={rotateLeft}/>
|
|
|
|
<Button outline icon="print" onClick={print}/>
|
|
|
|
<Button outline icon="rotate_right" onClick={rotateRight}/>
|
|
|
|
</div>
|
|
|
|
<div className={styles.container}>
|
|
|
|
<img ref={imgRef} onLoad={() => setImgLoaded(true)} style={{transform: `rotate(${currentRotation}deg)`}} src={order.delivery.easypost.postage_label.label_url}/>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear out older cache entries . . . return cleared cache
|
|
|
|
function clearCache(cache) {
|
|
|
|
// Get all cache values
|
|
|
|
return Object.values(cache)
|
|
|
|
// Filter out anything older than a week
|
|
|
|
.filter(({timestamp}) => Math.abs(DateTime.fromISO(timestamp).diffNow().as('days')) < 7)
|
|
|
|
// Convert back to keyed object
|
|
|
|
.reduce((acc, obj) => ({...acc, [obj.uuid]: obj}), {})
|
|
|
|
}
|
|
|
|
|
|
|
|
function printLabel(image, rotationDegrees) {
|
|
|
|
const {naturalWidth: width, naturalHeight: height} = image
|
|
|
|
const shorterSize = width > height ? 'height' : 'width'
|
|
|
|
const longerSize = width > height ? 'width' : 'height'
|
|
|
|
|
|
|
|
const {origin, translate} = (() => {
|
|
|
|
switch(rotationDegrees) {
|
|
|
|
case 90:
|
|
|
|
case -270:
|
|
|
|
return {origin: 'left top', translate: '0%, -100%'}
|
|
|
|
|
|
|
|
case 180:
|
|
|
|
case -180:
|
|
|
|
return {origin: 'center center', translate: '0%, 0%'}
|
|
|
|
|
|
|
|
case 270:
|
|
|
|
case -90:
|
|
|
|
return {origin: 'left top', translate:'-100%, 0%'}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return {origin: 'left top', translate: '0%, 0%'}
|
|
|
|
}
|
|
|
|
})()
|
|
|
|
|
|
|
|
|
|
|
|
const popup = window.open("", "Print label", "toolbar=off,width=800,height=600")
|
|
|
|
popup.document.write(`<img src="${image.getAttribute('src')}"/>`)
|
|
|
|
popup.document.write(`
|
|
|
|
<style>
|
|
|
|
html, body { width: 100%; margin: 0; padding: 0;}
|
|
|
|
|
|
|
|
img {
|
|
|
|
${shorterSize}: 4in;
|
|
|
|
${longerSize}: auto;
|
|
|
|
transform-origin: ${origin};
|
|
|
|
transform: rotate(${rotationDegrees}deg) translate(${translate});
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
`)
|
|
|
|
popup.document.close()
|
|
|
|
popup.focus()
|
|
|
|
popup.print()
|
|
|
|
popup.close()
|
|
|
|
}
|