UNPKG

pesaqr

Version:

QR Code Banner to scan and pay M-PESA for any Till/Paybill Number via the M-PESA app

189 lines (182 loc) 6.22 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LitElement, html, css } from "lit"; import { customElement, property } from "lit/decorators.js"; import qrcode from "qrcode-generator"; const TRANSACTION_TYPE = { TILL_NUMBER: "till", PAYBILL: "paybill", SEND_MONEY: "phone", }; let PesaQR = class PesaQR extends LitElement { constructor() { super(); this.type = "till"; this.tillNumber = ""; this.paybillNumber = ""; this.accountNumber = ""; this.phoneNumber = ""; this.amount = ""; this.width = null; this.theme = "light"; this.loading = false; this.error = null; this.type = "till"; this.tillNumber = ""; this.paybillNumber = ""; this.accountNumber = ""; this.phoneNumber = ""; this.amount = ""; this.width = null; } render() { return html ` <div class="pesaqr"> <div class="qr-header">SCAN WITH M-PESA</div> <div id="qrcode"></div> </div> `; } updated(changedProperties) { if (changedProperties.has("type") || changedProperties.has("tillNumber") || changedProperties.has("paybillNumber") || changedProperties.has("accountNumber") || changedProperties.has("phoneNumber") || changedProperties.has("amount")) { this.generateQRCode(); } if (changedProperties.has("width")) { if (this.width) { this.style.setProperty("--qr-width", `${this.width}px`); } } } generateQRCode() { let qrData = ""; switch (this.type) { case TRANSACTION_TYPE.TILL_NUMBER: if (this.tillNumber) { qrData = `BG|${this.tillNumber}|${this.amount}`; } break; case TRANSACTION_TYPE.PAYBILL: if (this.paybillNumber && this.accountNumber) { qrData = `PB|${this.paybillNumber}|${this.amount}|${this.accountNumber}`; } break; case TRANSACTION_TYPE.SEND_MONEY: if (this.phoneNumber) { qrData = `SM|${this.phoneNumber}|${this.amount}`; } break; default: console.error("Invalid transaction type"); return; } if (qrData) { const qr = qrcode(0, "L"); qr.addData(qrData); qr.make(); const qrCodeContainer = this.shadowRoot?.getElementById("qrcode"); if (qrCodeContainer) { qrCodeContainer.innerHTML = qr.createImgTag(20); } } } }; PesaQR.styles = css ` :host { display: block; font-family: Arial, sans-serif; --qr-size: calc(var(--qr-width, 600px) * 0.35); --header-padding: calc(var(--qr-size) * 0.025); --border-radius: calc(var(--qr-size) * 0.05); --font-size: calc(var(--qr-size) * 0.05); /* Theme Variables */ --qr-primary-color: var(--pesaqr-primary-color, #16a34a); --qr-background: var(--pesaqr-background, white); --qr-text-color: var(--pesaqr-text-color, white); --qr-border-color: var(--pesaqr-border-color, #16a34a); } /* Dark theme */ :host([theme="dark"]) { --qr-primary-color: var(--pesaqr-primary-color, #22c55e); --qr-background: var(--pesaqr-background, #1f2937); --qr-text-color: var(--pesaqr-text-color, #f3f4f6); --qr-border-color: var(--pesaqr-border-color, #22c55e); } .pesaqr { position: relative; border: calc(var(--qr-size) * 0.02) solid var(--qr-border-color); border-radius: var(--border-radius); overflow: visible; width: fit-content; background: var(--qr-background); margin-top: calc(var(--header-padding) * 2); } .qr-header { position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%); background: var(--qr-primary-color); color: var(--qr-text-color); padding: var(--header-padding) calc(var(--header-padding) * 2); text-align: center; user-select: none; font-weight: bold; border-radius: calc(var(--border-radius) * 0.35); font-size: var(--font-size); white-space: nowrap; border: calc(var(--qr-size) * 0.02) solid var(--qr-border-color); } #qrcode { display: flex; justify-content: center; align-items: center; } #qrcode img { width: var(--qr-size) !important; height: var(--qr-size) !important; border-radius: calc(var(--border-radius) * 0.75); } `; __decorate([ property({ type: String }) ], PesaQR.prototype, "type", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "tillNumber", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "paybillNumber", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "accountNumber", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "phoneNumber", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "amount", void 0); __decorate([ property({ type: Number }) ], PesaQR.prototype, "width", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "theme", void 0); __decorate([ property({ type: Boolean }) ], PesaQR.prototype, "loading", void 0); __decorate([ property({ type: String }) ], PesaQR.prototype, "error", void 0); PesaQR = __decorate([ customElement("pesa-qr") ], PesaQR); export { PesaQR };