add svg icons. running into scroll issue. will upgrade packages.

This commit is contained in:
Jordan
2024-08-15 14:07:19 -07:00
parent a463189052
commit dc7f4b25a9
38 changed files with 3272 additions and 2097 deletions

View File

@ -1,22 +1,47 @@
import { Product } from "../product";
import { Id, Product, productPriceFor } from "../product";
import uuid from "react-native-uuid"
describe("Product tests", () => {
it(`Length product gives correct price for a shorter length`, () => {
const standard = new Product(20, { l: 4, u: "feet" });
const comparison = standard.priceFor({ l: 2, u: "feet" });
expect(comparison).toEqual(10);
const standard : Product = {
id: uuid.v4().valueOf() as Id,
dimensions: {
l: 5,
u: "ft",
},
type: "lumber",
pricePerUnit: 10,
};
const comparison = productPriceFor(standard, { l: 2, u: "feet" });
expect(comparison).toEqual(4);
});
it(`Length product gives correct price for a longer length`, () => {
const standard = new Product(20, {l: 4, u : "feet"});
const comparison = standard.priceFor({l : 8, u : "feet"});
expect(comparison).toEqual(40);
const standard : Product = {
id: uuid.v4().valueOf() as Id,
dimensions: {
l: 5,
u: "ft",
},
type: "lumber",
pricePerUnit: 10,
};
const comparison = productPriceFor(standard, { l: 10, u: "feet" });
expect(comparison).toEqual(20);
});
it(`Length product gives correct price if different units`, () => {
const standard = new Product(10, {l: 1, u : "feet"});
const comparison = standard.priceFor({l : 24, u: "inch"});
expect(comparison).toBeCloseTo(20, 4);
const standard : Product = {
id: uuid.v4().valueOf() as Id,
dimensions: {
l: 12,
u: "in",
},
type: "lumber",
pricePerUnit: 1,
};
const comparison = productPriceFor(standard, { l: 2, u: "feet" });
expect(comparison).toBeCloseTo(2, 1);
});
});

View File

@ -33,6 +33,8 @@ export const dimensionType = (d: dimensions_t) => isArea(d) ? "area" : "length";
};
}
const FACTOR = 0.1309;
/**
* Gets the total length of a carpet roll based on a diameter
* @param outerDiameter Outer diameter of the carpet roll
@ -43,9 +45,15 @@ export function diameterToLength(outerDiameter: length_t, innerDiameter: length_
if (outerDiameter.u !== innerDiameter.u) {
throw new Error("diameter units must match!")
}
const thickness = (((outerDiameter.l - innerDiameter.l) / 2) / numRings);
const l = FACTOR * numRings * (innerDiameter.l + outerDiameter.l);
return {
l: Math.PI * (Math.pow(outerDiameter.l, 2) / 4) - (Math.pow(innerDiameter.l, 2) / 4) / thickness,
u: innerDiameter.u,
};
l,
u: outerDiameter.u
}
}
export function dimensionsDisplay(d : dimensions_t) {
if ("w" in d) {
return `${d.w} x ${d.l} ${d.u}`
}
}

View File

@ -1,5 +1,5 @@
import uuid from "react-native-uuid";
import { dimensions_t, area_t } from "./dimensions";
import { dimensions_t, area_t, dimensionsDisplay } from "./dimensions";
import { matchDimensions } from "./dimensions";
import { Area, Length, Unit } from "convert";
@ -8,79 +8,96 @@ export type Id = string;
export type Currency = "USD";
export type ProductAttributes = {
id?: string,
name?: string,
image?: string,
description?: string,
depth?: string,
currency?: Currency,
[index:string]: any,
}
id?: string;
name?: string;
image?: string;
description?: string;
depth?: string;
currency?: Currency;
[index: string]: any;
};
export function dimensionArea(d: dimensions_t) {
return "w" in d ? d.w * d.l : 0;
return "w" in d ? d.w * d.l : 0;
}
export const PRODUCT_TYPES = [
"lumber",
"area_rug",
] as const;
export type product_type_t = typeof PRODUCT_TYPES[number];
export const PRODUCT_TYPES = ["lumber", "area_rug"] as const;
export type product_type_t = (typeof PRODUCT_TYPES)[number];
export type Product = {
id?: Id;
pricePerUnit: number;
dimensions: dimensions_t;
type: product_type_t;
attributes?: ProductAttributes;
id?: Id;
pricePerUnit: number;
dimensions: dimensions_t;
type: product_type_t;
attributes?: ProductAttributes;
};
export type LumberProduct = Product & {
type: "lumber"
}
type: "lumber";
};
export type AreaRugProduct = Product & {
type: "lumber"
type: "lumber";
};
export function productPriceFor(
product: Product,
dimensions: dimensions_t,
damage: number = 0
): number {
if (Number.isNaN(damage)) damage = 0;
const dim = matchDimensions(dimensions, product.dimensions);
return (
(dim.w
? (dimensionArea(dim) / dimensionArea(product.dimensions)) *
product.pricePerUnit
: (dim.l / product.dimensions.l) * product.pricePerUnit) *
(1.0 - damage)
);
}
export function productPriceFor(product : Product, dimensions: dimensions_t, damage: number = 0): number {
if (Number.isNaN(damage)) damage = 0;
const dim = matchDimensions(dimensions, product.dimensions);
return (
dim.w ? dimensionArea(dim) / dimensionArea(product.dimensions) * product.pricePerUnit
: (dim.l / product.dimensions.l) * product.pricePerUnit
) * (1.0 - damage);
export function priceDisplay(price: number) {
return price.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
}
export function priceDisplay(price : number) {
return price.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
export function pricePerUnitDisplay(product: Product) {
const p = priceDisplay(product.pricePerUnit);
const { l, u } = product.dimensions;
const w = (product.dimensions as area_t).w || null;
const d = w ? `${l}${u} x ${w}${u}` : `${l}${u}`;
return `$${p} per ${d}`;
}
export function attributesAsList(attributes: ProductAttributes) {
return Object.entries(attributes).map(([key, value]) => {
return { key, value };
});
}
export function productLabel(
product: Product,
{ pricing }: { pricing: boolean } = { pricing: false }
) {
const n = product.attributes?.name || `Product ${product.id}`;
const p = priceDisplay(product.pricePerUnit);
const d = dimensionsDisplay(product.dimensions);
if (!pricing) {
return n;
}
return `${n} ($${p} per ${d})`;
}
export function removeAttribute(
attributes: { [key: string]: any },
key: string
) {
return Object.fromEntries(
Object.entries(attributes).filter(([k, v]) => {
k == key;
})
);
}
export function pricePerUnitDisplay(product : Product) {
const p = priceDisplay(product.pricePerUnit);
const { l, u } = product.dimensions;
const w = (product.dimensions as area_t).w || null;
const d = w ? `${l}${u} x ${w}${u}` : `${l}${u}`;
return `$${p} per ${d}`
}
export function attributesAsList(attributes : {[key:string]: any}) {
return Object.entries(attributes).map(([key, value]) => {
return { key, value }
})
}
export function removeAttribute(attributes: {[key: string]: any}, key: string) {
return Object.fromEntries(
Object.entries(attributes).filter(
([k, v]) => {
k == key;
}
)
);
}

View File

@ -0,0 +1,15 @@
function waitForWindow(): Promise<Window> {
return new Promise((resolve) => {
if (typeof window !== 'undefined') {
resolve(window);
} else {
const intervalId = setInterval(() => {
if (typeof window !== 'undefined') {
clearInterval(intervalId);
resolve(window);
}
}, 100);
}
});
}