- Cash Floats: ledger card (opening balance, top-ups, slips), manual entries, slip photos - Office access level; clock app Slips tab (photograph a slip, popup for supplier/cost code/comments/amount); only Office sees it; per-role route table in lib/clock-access - Job cards: Machine Service PDF (with Oil block), JC numbers, manual Close job, Delete - Hide Expenses > Vehicle Costs and Finance (Bastion) from the menu Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
12 lines
768 B
TypeScript
12 lines
768 B
TypeScript
/** Phone photos are 4–8 MB; shrink to ~1600px JPEG so a yard with poor signal can still upload. Browser only. */
|
||
export async function shrinkImage(file: File, name = 'photo.jpg', maxSide = 1600): Promise<File> {
|
||
try {
|
||
const bmp = await createImageBitmap(file);
|
||
const scale = Math.min(1, maxSide / Math.max(bmp.width, bmp.height));
|
||
const canvas = document.createElement('canvas');
|
||
canvas.width = Math.round(bmp.width * scale); canvas.height = Math.round(bmp.height * scale);
|
||
canvas.getContext('2d')!.drawImage(bmp, 0, 0, canvas.width, canvas.height);
|
||
const blob = await new Promise<Blob | null>(r => canvas.toBlob(r, 'image/jpeg', 0.8));
|
||
return blob ? new File([blob], name, { type: 'image/jpeg' }) : file;
|
||
} catch { return file; }
|
||
}
|