class Mission {
constructor(args = null) {
this.args = args;
this.config = {
products: {
tv: { dn: 'Smart TV\'s', bp: 100, gpd: 10 },
ha: { dn: 'Home Appliances', bp: 150, gpd: 12 },
as: { dn: 'Audio Systems', bp: 100, gpd: 50 },
lp: { dn: 'Laptops', bp: 150, gpd: 100 },
sp: { dn: 'SmartPhones', bp: 150, gpd: 20 }
}
}
this.create();
this.spinner = ``;
self.onnetrestoreEvents = self.onnetrestoreEvents ?? [];
this.cpdet = {}
}
init(c) {
try {
this.config = { ...this.config, ...c }
} catch {
console.log('Invalid initialization object');
}
this.start();
}
sharePdct() {
Client.share({ title: mss.pdct?.pname ?? currPdct.dn, text: `@${CALC.parseMoney(currPdct.bp, true)}/-`, url: `${AC.env}${location.pathname.slice(1)}?venture=[0]` });
sessionStorage.exportImage = mss.pdct?.imgs[0] ?? '';
}
create() {
let x = `
`;
$('body').addClass('d-flex flex-column h-100').append(x);
}
#checkStockSize(dot) {
let eop = new Date(), cpd = Date.now(), tdiff;
eop.setFullYear(eop.getFullYear() + 1);
eop.setMonth(0);
eop.setDate(1);
tdiff = eop.getTime() - cpd;
let estss = Math.ceil(tdiff / (1000 * 60 * 60 * 24)) * dot;
$('#estss').text(estss);
return estss;
}
start() {
self.currPdct = this.config.products[this.config.cp];
let view = `
${currPdct.dn}
Bid price: Ksh ${currPdct.bp}
${currPdct.gpd} units available
Be the first to place your bid here
`;
$('main').html(view).find('.hedex').children()
$('header.masta').find('#ct').text(currPdct.dn);
this.checkDrawTime('#timetodraw,.timetodraw');
this.#fetchProduct();
this.#checkStockSize(currPdct.gpd);
this.syncBids();
}
#fetchProduct() {
$.ajax({
url: 'promotions/res/.incs/pdts/',
data: { fetch: this.config.cp },
dataType: 'json',
success: pdct => {
this.#parseProduct(pdct)
},
error: err => {
if (isNetError(err)) return;
showToast(err.statusText);
}
})
}
#parseProduct(pdct) {
mss.pdct = pdct;
$('#pdctName').text(pdct.pname);
$('#pdctMprice').text(pdct.price).closest('.card').on('click', function () {
mss.viewPdct(pdct);
});
$('#pdctImg')[0].src = (pdct.imgs[0]);
mss.cpdet = pdct;
}
viewPdct(pdct) {
let m = `
${pdct.pname}
Remaining: ${this.#checkStockSize(currPdct.gpd)}units
Today's offer: ${currPdct.gpd} units
`;
Action.confirm({
title: "Product Details",
html: m,
positive: "Place Bid",
negative: "Back"
}).then(res => {
if (res) return mss.bid('#bidder');
})
}
async #createAccRef(amount) {
try {
return new Promise((resolve, reject) => {
let r;
try { r = Operator.getSP().venture; } catch (e) { e }
if (Number(r) < 0) resolve(r);
$.post('promotions/.inc/api/createTxnRef', {
uid: localStorage.user,
amount: amount,
strict: false
}).then(res => resolve(res)).fail(err => reject(err.statusText))
}).catch(err => showToast(err.message ?? err))
} catch (error) {
console.log(error.message);
}
}
#createTimestamp() {
let x = new Date();
x.setMinutes(x.getMinutes() - x.getTimezoneOffset());
return x.toJSON().replace(/[^0-9]/g, '').slice(0, -3);
}
async bid(t) {
if (mss.lock) return ActionCentre('*Please confirm the previous transaction to proceed on another bid', 15000, 'Error');
let pdct = this.config.products[this.config.cp];
await this.getPhoneNumber().then(async pn => {
let Timestamp = this.#createTimestamp(), Amount = pdct.bp, AccountReference;
localStorage.setItem('user', pn);
await this.#createAccRef(pdct.bp).then(acref => {
if (!acref) return showToast('Unable to create Account Reference');
if (isNaN(acref)) return showToast('Invalid Account reference: ' + acref);
AccountReference = acref;
});
if (!AccountReference) return;
Swal.fire({
html: `
A payment request has been sent to your phone number, please complete the payment to place your bid.
`
}).then(confirmed => {
if (!confirmed) return;
const pmReq = {
AccountReference: AccountReference, Amount: Amount, TransactionDesc: pdct.dn, PhoneNumber: pn, Timestamp: Timestamp
}
Trigger.reqDeposit(pmReq).then(async res => {
if (res && res.status == 200) {
mss.lock = true;
mss.submitBid(AccountReference);
let bidData = {
ref: JSON.stringify({ FirstName: localStorage.getItem('user'), MSISDN: pn }),
etime: Timestamp,
id: AccountReference
};
mss.parseonSyncBids([bidData], true);
setTimeout(() => {
mss.lock = false;
showToast('Bid placed successfully ✅');
}, 5000);
} else {
showToast(res?.message ?? 'Payment request failed, please try again later');
}
}).catch(err => {
mss.lock = false;
if (isNetError(err)) {
showToast('Network error: Please check your internet connection');
return;
}
showToast(err.message ?? err);
});
})
})
}
checkDrawTime(plc) {
function time() {
let ctime = new Date(), ctimeOffsetBalancer = ctime.getTimezoneOffset() / 60 + 3;
ctime.setHours(ctime.getHours() + ctimeOffsetBalancer)
let dtime = new Date(ctime);
dtime.setDate(dtime.getDate() + 1);
dtime.setHours(0);
dtime.setMinutes(0);
dtime.setSeconds(0);
let dtt = dtime.getTime(), ctt = ctime.getTime(), diffTime = dtt - ctt, hoursin = Math.floor(diffTime / (1000 * 60 * 60)), minutesin = Math.floor((diffTime % (1000 * 60 * 60)) / (1000 * 60)), secsin = Math.floor((diffTime % (1000 * 60)) / 1000);
return `${hoursin}H: ${minutesin}M: ${secsin}S`;
}
if (document.querySelector(plc)) return setInterval(() => {
$(plc).html(time());
}, 1000);
return time();
}
submitBid(bid) {
try {
$.ajax({
url: 'promotions/res/.incs/stream/',
type: 'POST',
data: { bid: bid },
success: res => {
try {
if (res && !isNaN(res)) return showToast('Entered to draw successfully ✅');
throw JSON.parse(res);
} catch {
showToast(res);
}
},
error: err => {
if (isNetError(err)) return setTimeout(() => mss.submitBid(bid), 5000)
}
})
} catch (error) {
console.log(error.message ?? error)
}
}
parseonSyncBids(bids, instate = false) {
try {
if (!bids.length) return;
let bidView = ``;
if (instate)
bidView += ``;
bids.forEach(bid => {
let ref = JSON.parse(bid.ref);
if ($('#hedex').children('#' + bid.id).length)
return;
bidView += `
-
${ref.FirstName}
${ref.MSISDN}
#${bid.id}
`;
mss.pass = bid.id;
});
if (!bidView) return;
if (instate) {
bidView += `
`;
$('#hedexArea').html(bidView);
} else {
$('#hedex').append(bidView);
}
$('#khamara')[0].scrollIntoView();
} catch (error) {
console.log(error.message);
}
}
syncBids() {
try {
if (!mss.bidStream) mss.bidStream = setInterval(mss.syncBids, 10000);
if (!document.hasFocus()) return console.log('Stream paused');
if (mss.passcode && mss.passcode != 1) return;
const url = `promotions/res/.incs/stream/`;
$.ajax({
url: url,
type: 'POST',
data: { x: mss.config.cp, pass: mss.pass ?? '' },
beforeSend: e => {
mss.passcode = performance.now();
},
complete: e => {
mss.passcode = 1;
},
dataType: 'json',
success: data => {
return mss.parseonSyncBids(data, mss.pass ? false : true);
},
error: err => {
mss.passcode = 1;
if (isNetError(err))
return self.onnetrestoreEvents[0] = () => {
mss.syncBids();
}
}
});
} catch (error) {
console.log(error);
}
}
}
self.mss = new Mission();