Skip to content

Commit

Permalink
Update price checker with shipping cost
Browse files Browse the repository at this point in the history
and fix highlighted box colour
  • Loading branch information
keybraker committed Nov 2, 2024
1 parent 178889b commit ddf6871
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 28 deletions.
5 changes: 3 additions & 2 deletions src/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ text-black {
}

.lowest-price-store-highlight {
border: 2px solid var(--color-text-success-0) !important;
box-shadow: 1px 1px 0 var(--color-text-success-0) !important;
border: 2px solid var(--color-text-link-marketplace-visited) !important;
box-shadow: 1px 1px 0 var(--color-text-link-marketplace-visited) !important;
box-shadow: 0px 8px 12px rgba(0, 0, 0, 0.1) !important;
}

.info-label-positive {
Expand Down
77 changes: 55 additions & 22 deletions src/decorators/PriceCheckerIndicator.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { Language } from "../enums/Language";
import { buyThroughSkroutzShippingCostRetriever } from "../retrievers/buyThroughSkroutzShippingCostRetriever";
import { buyThroughSkroutzRetriever } from "../retrievers/buyThroughSkroutzRetriever";
import { marketDataReceiver } from "../retrievers/marketDataRetriever";
import { LowestPriceData, marketDataReceiver } from "../retrievers/marketDataRetriever";
import { State } from "../types/State";

interface LowestPriceData {
formatted: string;
unformatted: number;
shopId: number;
}


function roundToZero(value: number, precision = 1e-10) {
return Math.abs(value) < precision ? 0 : value;
Expand Down Expand Up @@ -48,21 +44,27 @@ export class PriceCheckerIndicator {

private createPriceIndicationElement(): HTMLDivElement {
const priceIndication = document.createElement("div");
const colFlex = document.createElement("div");
const rowFlex = document.createElement("div");
const colFlex1 = document.createElement("div");
const colFlex2 = document.createElement("div");
const rowFlex1 = document.createElement("div");
const rowFlex2 = document.createElement("div");
const rowFlex3 = document.createElement("div");
const otherLowestPrice = document.createElement("div");

const shippingCost = this.btsShippingCost ?? 0;
let isLowestPrice = false;
if (!!this.btsPrice && !!this.lowestPriceData) {
isLowestPrice = this.btsPrice + shippingCost <= this.lowestPriceData.unformatted;
isLowestPrice = this.btsPrice + shippingCost <= this.lowestPriceData.lowestTotalPrice;
}

const checkerStyle = isLowestPrice ? "info-label-positive" : "info-label-negative";

priceIndication.classList.add("display-padding", "inline-flex-row", "price-checker-outline", checkerStyle);
colFlex.classList.add("inline-flex-col");
rowFlex.classList.add("inline-flex-row");
colFlex1.classList.add("inline-flex-col");
colFlex2.classList.add("inline-flex-col");
rowFlex1.classList.add("inline-flex-row");
rowFlex2.classList.add("inline-flex-row");
rowFlex3.classList.add("inline-flex-row");
otherLowestPrice.classList.add("price");

const priceComma = document.createElement("span");
Expand All @@ -71,8 +73,8 @@ export class PriceCheckerIndicator {
const loyaltyPoints = document.createElement("span");
const shippingInfo = document.createElement("span");

const lowestPrice = this.lowestPriceData ? this.lowestPriceData.unformatted : undefined;
const [integerPart, decimalPart] = (lowestPrice?.toFixed(2) ?? "?").split(".");
const lowestPrice = this.lowestPriceData ? this.lowestPriceData.lowestTotalPrice : undefined;
const [integerPart, decimalPart] = (this.lowestPriceData?.lowestProductPrice?.toFixed(2) ?? "?").split(".");

priceComma.textContent = ",";
priceDecimal.textContent = decimalPart;
Expand All @@ -90,46 +92,77 @@ export class PriceCheckerIndicator {
const priceDifference = document.createElement("span");
const priceDifferenceExplanation = document.createElement("span");

const shippingCostSpan = document.createElement("span");
const shippingCostExplanationSpan = document.createElement("span");

const diff = roundToZero((lowestPrice ?? 0) - (this.btsPrice ?? 0) - shippingCost);

const isLowestPriceFreeShipping = this.lowestPriceData?.lowestShippingCost === 0;
console.log("this.lowestPriceData?.lowestShippingCost :>> ", this.lowestPriceData?.lowestShippingCost);
console.log("isLowestPriceFreeShipping :>> ", isLowestPriceFreeShipping);
if (diff > 0) {
priceDifference.textContent = ` ${diff} / ${diff.toFixed(2)}€`;
if (isLowestPriceFreeShipping) {
shippingCostSpan.textContent = this.state.language === Language.ENGLISH ? "Free shipping" : "Δωρεάν μεταφορικά";
} else {
shippingCostSpan.textContent = ` + ${this.lowestPriceData?.lowestShippingCost}€`;
shippingCostExplanationSpan.textContent = this.state.language === Language.ENGLISH
? " shipping cost"
: " μεταφορικά";
}

priceDifference.textContent = ` ${diff.toFixed(2)}€`;
priceDifferenceExplanation.textContent = this.state.language === Language.ENGLISH
? " more expensive"
: " ακριβότερο";
} else if (diff < 0) {
if (isLowestPriceFreeShipping) {
shippingCostSpan.textContent = this.state.language === Language.ENGLISH ? "Free shipping" : "Δωρεάν μεταφορικά";
} else {
shippingCostSpan.textContent = ` + ${this.lowestPriceData?.lowestShippingCost}€`;
shippingCostExplanationSpan.textContent = this.state.language === Language.ENGLISH
? " shipping cost"
: " μεταφορικά";
}

priceDifference.textContent = ` ${diff.toFixed(2)}€`;
priceDifferenceExplanation.textContent = this.state.language === Language.ENGLISH
? " cheaper"
: " φτηνότερο";
}

rowFlex.appendChild(otherLowestPrice);
rowFlex.appendChild(priceDifference);
rowFlex.appendChild(priceDifferenceExplanation);
rowFlex2.appendChild(shippingCostSpan);
rowFlex2.appendChild(shippingCostExplanationSpan);

rowFlex3.appendChild(priceDifference);
rowFlex3.appendChild(priceDifferenceExplanation);

colFlex.appendChild(rowFlex);
colFlex2.appendChild(rowFlex2);
colFlex2.appendChild(rowFlex3);

rowFlex1.appendChild(otherLowestPrice);
rowFlex1.appendChild(colFlex2);

colFlex1.appendChild(rowFlex1);

const information = document.createElement("div");
information.textContent = this.state.language === Language.ENGLISH
? "is the lowest price with shipping apart from \"Buy through Skroutz\""
: "είναι η χαμηλότερη τιμή με μεταφορικά εκτός \"Αγορά μέσω Skroutz\"";
information.classList.add("align-center", "font-bold");

colFlex.appendChild(information);
colFlex1.appendChild(information);

const goToStoreButton = this.goToStoreButtonCreator(isLowestPrice);
colFlex.appendChild(goToStoreButton);
colFlex1.appendChild(goToStoreButton);

priceIndication.title = this.state.language === Language.ENGLISH
? `(note that "Buy through Skroutz" is ${this.btsPrice}€ + ${shippingCost}€ shipping)`
: `(σημειώστε ότι "Αγορά μέσω Skroutz" είναι ${this.btsPrice}€ + ${shippingCost}€ μεταφορικά)`;
priceIndication.appendChild(colFlex);
priceIndication.appendChild(colFlex1);

return priceIndication;
}


private goToStoreButtonCreator(isLowestPrice: boolean): HTMLButtonElement {
const goToStoreButton = document.createElement("button");
const buttonStyle = isLowestPrice ? "go-to-shop-button-positive" : "go-to-shop-button-negative";
Expand Down
21 changes: 17 additions & 4 deletions src/retrievers/marketDataRetriever.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
export type LowestPriceData = {
lowestProductPrice: number;
lowestShippingCost: number;
lowestTotalPrice: number;
shopId: number;
}

function getSKU(): string | null {
const metaTag = document.querySelector("meta[itemprop=\"sku\"]") as HTMLMetaElement | null;
return metaTag ? metaTag.content : null;
}

export async function marketDataReceiver() {
export async function marketDataReceiver(): Promise<LowestPriceData | undefined> {
try {
const productCode = getSKU();
if (!productCode) {
Expand Down Expand Up @@ -32,14 +39,19 @@ export async function marketDataReceiver() {
final_price_formatted?: string,
price: number,
}[];
const currency = responseJSON.price_min.trim().slice(-1);
// const currency = responseJSON.price_min.trim().slice(-1);
let shopId = 0;
let lowestPrice = Number.MAX_VALUE;
let lowestProductPrice = Number.MAX_VALUE;
let lowestShippingCost = Number.MAX_VALUE;

Object.values(productCards).forEach(card => {
const totalCost = card.raw_price + card.shipping_cost;
if (totalCost < lowestPrice) {
lowestPrice = totalCost;
lowestProductPrice = card.raw_price;
lowestShippingCost = card.shipping_cost;

shopId = card.shop_id;
}
});
Expand All @@ -49,8 +61,9 @@ export async function marketDataReceiver() {
}

return {
formatted: `${lowestPrice} ${currency}`,
unformatted: lowestPrice,
lowestProductPrice,
lowestShippingCost,
lowestTotalPrice: lowestPrice,
shopId,
};
} catch (error) {
Expand Down

0 comments on commit ddf6871

Please sign in to comment.